diff --git a/.gitignore b/.gitignore index 09700873..a40abb8a 100755 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,6 @@ telethon/errors/rpcerrorlist.py # User session *.session usermedia/ -api/settings # Quick tests should live in this file example.py diff --git a/api/settings_example b/api/settings_example deleted file mode 100644 index 32ce02ea..00000000 --- a/api/settings_example +++ /dev/null @@ -1,4 +0,0 @@ -api_id=12345 -api_hash=0123456789abcdef0123456789abcdef -user_phone=+34600000000 -session_name=anonymous diff --git a/telethon_examples/README.txt b/telethon_examples/README.txt new file mode 100644 index 00000000..73af9702 --- /dev/null +++ b/telethon_examples/README.txt @@ -0,0 +1,15 @@ +You should be able to run these files with python3 filename.py after +installing Telethon (`pip3 install .` on the root of the project if you +haven't installed it yet and you downloaded the repository). + +Most of these examples assume you have the following variables defined +in your environment: + + TG_API_ID, this is the api ID of your Telegram application. + TG_API_HASH, similarly, this is the api hash. + TG_TOKEN, for bot examples, this should be the bot token. + TG_SESSION, this is the session file name to be (re)used. + +See https://superuser.com/q/284342 to learn how to define them. +It's more convenient to define them, but if you forget to do so, +the scripts will ask you to enter the variables when ran. diff --git a/telethon_examples/assistant.py b/telethon_examples/assistant.py index 1a252298..38ed0e82 100644 --- a/telethon_examples/assistant.py +++ b/telethon_examples/assistant.py @@ -11,13 +11,24 @@ from telethon import TelegramClient, events, custom logging.basicConfig(level=logging.WARNING) logging.getLogger('asyncio').setLevel(logging.ERROR) -for x in 'TG_API_ID TG_API_HASH TG_TOKEN'.split(): - if x not in os.environ: - print(f'{x} not in environmental variables', file=sys.stderr) - quit() -NAME = os.environ['TG_TOKEN'].split(':')[0] -bot = TelegramClient(NAME, os.environ['TG_API_ID'], os.environ['TG_API_HASH']) +def get_env(name, message, cast=str): + if name in os.environ: + return os.environ[name] + while True: + value = input(message) + try: + return cast(value) + except ValueError as e: + print(e, file=sys.stderr) + time.sleep(1) + + +API_ID = get_env('TG_API_ID', 'Enter your API ID: ', int) +API_HASH = get_env('TG_API_HASH', 'Enter your API hash: ') +TOKEN = get_env('TG_TOKEN', 'Enter the bot token: ') +NAME = TOKEN.split(':')[0] +bot = TelegramClient(NAME, API_ID, API_HASH) # ============================== Constants ============================== @@ -336,5 +347,5 @@ def attr_fullname(cls, n): # ============================== Helpers ============================== -bot.start(bot_token=os.environ['TG_TOKEN']) +bot.start(bot_token=TOKEN) bot.run_until_disconnected() diff --git a/telethon_examples/gui.py b/telethon_examples/gui.py index 5ea30fdd..949d1eb9 100644 --- a/telethon_examples/gui.py +++ b/telethon_examples/gui.py @@ -5,6 +5,7 @@ import inspect import os import re import sys +import time import tkinter import tkinter.constants import tkinter.scrolledtext @@ -19,16 +20,23 @@ REPLY = re.compile(r'\.r\s*(\d+)\s*(.+)', re.IGNORECASE) DELETE = re.compile(r'\.d\s*(\d+)', re.IGNORECASE) EDIT = re.compile(r'\.s(.+?[^\\])/(.*)', re.IGNORECASE) + +def get_env(name, message, cast=str): + if name in os.environ: + return os.environ[name] + while True: + value = input(message) + try: + return cast(value) + except ValueError as e: + print(e, file=sys.stderr) + time.sleep(1) + + # Session name, API ID and hash to use; loaded from environmental variables SESSION = os.environ.get('TG_SESSION', 'gui') - -API_ID = os.environ.get('TG_API_ID') -if not API_ID: - API_ID = input('Enter API ID (or add TG_API_ID to env vars): ') - -API_HASH = os.environ.get('TG_API_HASH') -if not API_HASH: - API_HASH = input('Enter API hash (or add TG_API_HASH to env vars): ') +API_ID = get_env('TG_API_ID', 'Enter your API ID: ', int) +API_HASH = get_env('TG_API_HASH', 'Enter your API hash: ') def sanitize_str(string): diff --git a/telethon_examples/interactive_telegram_client.py b/telethon_examples/interactive_telegram_client.py index 382ca0cd..ecf9570b 100644 --- a/telethon_examples/interactive_telegram_client.py +++ b/telethon_examples/interactive_telegram_client.py @@ -1,14 +1,13 @@ +import asyncio import os import sys -import asyncio +import time from getpass import getpass -from telethon.utils import get_display_name - from telethon import TelegramClient, events -from telethon.network import ConnectionTcpAbridged from telethon.errors import SessionPasswordNeededError - +from telethon.network import ConnectionTcpAbridged +from telethon.utils import get_display_name # Create a global variable to hold the loop we will be using loop = asyncio.get_event_loop() @@ -54,6 +53,19 @@ async def async_input(prompt): return (await loop.run_in_executor(None, sys.stdin.readline)).rstrip() +def get_env(name, message, cast=str): + """Helper to get environment variables interactively""" + if name in os.environ: + return os.environ[name] + while True: + value = input(message) + try: + return cast(value) + except ValueError as e: + print(e, file=sys.stderr) + time.sleep(1) + + class InteractiveTelegramClient(TelegramClient): """Full featured Telegram client, meant to be used on an interactive session to see what Telethon is capable off - @@ -63,12 +75,11 @@ class InteractiveTelegramClient(TelegramClient): talking to people, downloading media, and receiving updates. """ - def __init__(self, session_user_id, user_phone, api_id, api_hash, + def __init__(self, session_user_id, api_id, api_hash, proxy=None): """ Initializes the InteractiveTelegramClient. :param session_user_id: Name of the *.session file. - :param user_phone: The phone of the user that will login. :param api_id: Telegram's api_id acquired through my.telegram.org. :param api_hash: Telegram's api_hash. :param proxy: Optional proxy tuple/dictionary. @@ -114,6 +125,7 @@ class InteractiveTelegramClient(TelegramClient): # the *.session file so you don't need to enter the code every time. if not loop.run_until_complete(self.is_user_authorized()): print('First run. Sending code request...') + user_phone = input('Enter your phone: ') loop.run_until_complete(self.sign_in(user_phone)) self_user = None @@ -380,3 +392,11 @@ class InteractiveTelegramClient(TelegramClient): sprint('<< {} sent "{}"'.format( get_display_name(chat), event.text )) + + +if __name__ == '__main__': + SESSION = os.environ.get('TG_SESSION', 'interactive') + API_ID = get_env('TG_API_ID', 'Enter your API ID: ', int) + API_HASH = get_env('TG_API_HASH', 'Enter your API hash: ') + client = InteractiveTelegramClient(SESSION, API_ID, API_HASH) + loop.run_until_complete(client.run()) diff --git a/telethon_examples/print_updates.py b/telethon_examples/print_updates.py index d1e70ceb..a93992ca 100755 --- a/telethon_examples/print_updates.py +++ b/telethon_examples/print_updates.py @@ -1,18 +1,28 @@ #!/usr/bin/env python3 # A simple script to print all updates received -# -# NOTE: To run this script you MUST have 'TG_API_ID' and 'TG_API_HASH' in -# your environment variables. This is a good way to use these private -# values. See https://superuser.com/q/284342. -from os import environ +import os +import sys +import time from telethon import TelegramClient +def get_env(name, message, cast=str): + if name in os.environ: + return os.environ[name] + while True: + value = input(message) + try: + return cast(value) + except ValueError as e: + print(e, file=sys.stderr) + time.sleep(1) + + client = TelegramClient( - environ.get('TG_SESSION', 'session'), - environ['TG_API_ID'], - environ['TG_API_HASH'], + os.environ.get('TG_SESSION', 'printer'), + get_env('TG_API_ID', 'Enter your API ID: ', int), + get_env('TG_API_HASH', 'Enter your API hash: '), proxy=None ) diff --git a/telethon_examples/replier.py b/telethon_examples/replier.py index 0ba2a214..3f109abd 100755 --- a/telethon_examples/replier.py +++ b/telethon_examples/replier.py @@ -2,17 +2,15 @@ """ A example script to automatically send messages based on certain triggers. -NOTE: To run this script you MUST have 'TG_API_ID' and 'TG_API_HASH' in - your environment variables. This is a good way to use these private - values. See https://superuser.com/q/284342. - This script assumes that you have certain files on the working directory, such as "xfiles.m4a" or "anytime.png" for some of the automated replies. """ +import os import re +import sys +import time from collections import defaultdict from datetime import datetime, timedelta -from os import environ from telethon import TelegramClient, events @@ -30,10 +28,22 @@ REACTS = {'emacs': 'Needs more vim', recent_reacts = defaultdict(list) -# TG_API_ID and TG_API_HASH *must* exist or this won't run! -session_name = environ.get('TG_SESSION', 'session') +def get_env(name, message, cast=str): + if name in os.environ: + return os.environ[name] + while True: + value = input(message) + try: + return cast(value) + except ValueError as e: + print(e, file=sys.stderr) + time.sleep(1) + + client = TelegramClient( - session_name, int(environ['TG_API_ID']), environ['TG_API_HASH'], + os.environ.get('TG_SESSION', 'replier'), + get_env('TG_API_ID', 'Enter your API ID: ', int), + get_env('TG_API_HASH', 'Enter your API hash: '), proxy=None ) diff --git a/try_telethon.py b/try_telethon.py deleted file mode 100755 index e0bf2c8a..00000000 --- a/try_telethon.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python3 -import asyncio -import traceback - -from telethon_examples.interactive_telegram_client \ - import InteractiveTelegramClient - - -def load_settings(path='api/settings'): - """Loads the user settings located under `api/`""" - result = {} - with open(path, 'r', encoding='utf-8') as file: - for line in file: - value_pair = line.split('=') - left = value_pair[0].strip() - right = value_pair[1].strip() - if right.isnumeric(): - result[left] = int(right) - else: - result[left] = right - - return result - - -if __name__ == '__main__': - # Load the settings and initialize the client - settings = load_settings() - kwargs = {} - if settings.get('socks_proxy'): - import socks # $ pip install pysocks - host, port = settings['socks_proxy'].split(':') - kwargs = dict(proxy=(socks.SOCKS5, host, int(port))) - - client = InteractiveTelegramClient( - session_user_id=str(settings.get('session_name', 'anonymous')), - user_phone=str(settings['user_phone']), - api_id=settings['api_id'], - api_hash=str(settings['api_hash']), - **kwargs) - - print('Initialization done!') - loop = asyncio.get_event_loop() - - try: - loop.run_until_complete(client.run()) - - except Exception as e: - print('Unexpected error ({}): {} at\n{}'.format( - type(e), e, traceback.format_exc())) - - finally: - loop.run_until_complete(client.disconnect()) - print('Thanks for trying the interactive example! Exiting...')