diff --git a/Pipfile b/Pipfile index 032f728..c712d1e 100644 --- a/Pipfile +++ b/Pipfile @@ -18,6 +18,7 @@ selenium = "*" opensky-api = {editable = true, git = "https://github.com/openskynetwork/opensky-api.git", subdirectory = "python"} webdriver-manager = "*" shapely = "*" +python-telegram-bot = "*" [requires] python_version = "3.9" diff --git a/README.md b/README.md index 36c5b09..25722a7 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,38 @@ docker-compose up -d After running this command, due to the `-d` flag the container will be running in the background. To see the logs of the docker container use `docker logs CONTAINER` (add `-f` to continue streaming the containers output) +### Telegram message feature - march/2022 + +Data obtained can be sent through Telegram to a chat (contact), channel or groups. + +Creating a Telegram Bot + - Start a conversation with [BotFather](https://t.me/BotFather); + - Send it to the BotFather: /newbot + - Choose a name for your bot; + - Choose a username for your bot; + - Done! You'll get a token to access the HTTP API. + +Getting channel or chat (contact) ID + - Start a conversation with [JsonDumpBot](https://t.me/JsonDumpBot); + - It will reply with a json with information from the message; + - Go to the channel or chat you want the id and forward a message from there to JsonDumpBot; + - Find the id in the reply. It'll look something like this: + ``` + {... +"forward_from_chat": { + "id": xxxxxxxxx, + ...} +``` + - Don't forget to add the bot as admin in channel so messages can be sent. + +Getting a group ID + - Open [Telegram web](https://web.telegram.org); + - Go to group and check the url on address bar of browser; + - That's the group ID (-xxxxxxxxx), it'll look something like this: + ``` + https://web.telegram.org/z/#-xxxxxxxxx + ``` + ### TODO - General Cleanup diff --git a/References.md b/References.md index fc7ef2c..041484f 100644 --- a/References.md +++ b/References.md @@ -66,3 +66,7 @@ ### OurAirports / airports.csv / regions.csv - + +### Telegram Bot + +- \ No newline at end of file diff --git a/configs/plane1.ini b/configs/plane1.ini index 9e77914..0ffe1be 100644 --- a/configs/plane1.ini +++ b/configs/plane1.ini @@ -39,4 +39,10 @@ URL = webhookurl #Role to tag optional, the role ID ROLE_ID = Title = -USERNAME = plane-notify \ No newline at end of file +USERNAME = plane-notify + +[TELEGRAM] +ENABLE = FALSE +TITLE = Title Of Telegram message +ROOM_ID = -100xxxxxxxxxx +BOT_TOKEN = xxxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ No newline at end of file diff --git a/defTelegram.py b/defTelegram.py new file mode 100644 index 0000000..d56378c --- /dev/null +++ b/defTelegram.py @@ -0,0 +1,38 @@ +def sendTeleg(photo, message, config): + import telegram + sent = False + retry_c = 0 + while sent == False: + try: + bot = telegram.Bot(token=config.get('TELEGRAM', 'BOT_TOKEN'), request=telegram.utils.request.Request(connect_timeout=20, read_timeout=20)) + sent = bot.send_photo(chat_id=config.get('TELEGRAM', 'ROOM_ID'), photo=photo, caption=message, parse_mode=telegram.ParseMode.MARKDOWN, timeout=20) + except Exception as err: + print('err.args:') + print(err.args) + print(f"Unexpected {err=}, {type(err)=}") + print("\nString err:\n"+str(err)) + if retry_c > 4: + print('Telegram attempts exceeded. Message not sent.') + break + elif str(err) == 'Unauthorized': + print('Invalid Telegram bot token, message not sent.') + break + elif str(err) == 'Timed out': + retry_c += 1 + print('Telegram timeout count: '+str(retry_c)) + pass + elif str(err) == 'Chat not found': + print('Invalid Telegram Chat ID, message not sent.') + break + elif str(err)[:35] == '[Errno 2] No such file or directory': + print('Telegram module couldn\'t find an image to send.') + break + elif str(err) == 'Media_caption_too_long': + print('Telegram image caption lenght exceeds 1024 characters. Message not send.') + break + else: + print('[X] Unknown Telegram error. Message not sent.') + break + else: + print("Telegram message successfully sent.") + return sent \ No newline at end of file diff --git a/planeClass.py b/planeClass.py index 83bb786..0dd495a 100644 --- a/planeClass.py +++ b/planeClass.py @@ -69,7 +69,7 @@ class Plane: self.reg = get_aircraft_reg_by_icao(self.icao) self.type = get_type_code_by_icao(self.icao) self.last_pos_datetime = datetime.fromtimestamp(ac_dict.time_position) - except ValueError as e: + except Exception as e: print("Got data but some data is invalid!") print(e) self.printheader("foot") @@ -407,6 +407,11 @@ class Plane: append_airport(self.map_file_name, nearest_airport_dict) else: raise ValueError("Map option not set correctly in this planes conf") + #Telegram + if self.config.getboolean('TELEGRAM', 'ENABLE'): + from defTelegram import sendTeleg + photo = open(self.map_file_name, "rb") + sendTeleg(photo, message, self.config) #Discord if self.config.getboolean('DISCORD', 'ENABLE'): dis_message = f"{self.dis_title} {message}".strip() @@ -436,6 +441,11 @@ class Plane: route_to = self.route_info() if route_to != None: print(route_to) + #Telegram + if self.config.getboolean('TELEGRAM', 'ENABLE'): + message = f"{self.dis_title} {route_to}".strip() + photo = open(self.map_file_name, "rb") + sendTeleg(photo, message, self.config) #Discord if self.config.getboolean('DISCORD', 'ENABLE'): dis_message = f"{self.dis_title} {route_to}".strip() @@ -563,6 +573,10 @@ class Plane: else: message = f"Circling {round(nearest_airport_dict['distance_mi'], 2)}mi {cardinal} of {nearest_airport_dict['icao']}, {nearest_airport_dict['name']} at {self.alt_ft}ft" print(message) + #Telegram + if self.config.getboolean('TELEGRAM', 'ENABLE'): + photo = open(self.map_file_name, "rb") + sendTeleg(photo, message, self.config) if self.config.getboolean('DISCORD', 'ENABLE'): role_id = self.config.get('DISCORD', 'ROLE_ID') if self.config.has_option('DISCORD', 'ROLE_ID') else None sendDis(message, self.config, self.map_file_name, role_id)