From d640a21a5d8821f7d980bfc39384e79e84cde1a2 Mon Sep 17 00:00:00 2001 From: Davte Date: Mon, 15 Jul 2019 17:07:57 +0200 Subject: [PATCH] Webhook guide --- README.md | 34 ++++++++++ davtelepot/__init__.py | 2 +- examples/webhook_powered_bot.py | 106 ++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 examples/webhook_powered_bot.py diff --git a/README.md b/README.md index 4f0b6ef..045cca4 100644 --- a/README.md +++ b/README.md @@ -43,3 +43,37 @@ exit_state = Bot.run() sys.exit(exit_state) ``` Check out `help(Bot)` for detailed information. + +## Webhook additional information +To run a bot in webhook modality, you have to provide a `hostname` and `certificate` at bot instantiation and a `local_host` and `port` when calling `Bot.run` method. +* Telegram will send POST requests at `https://{hostname}/webhook/{tokens}/` using `certificate` for encryption +* `aiohttp.web.Application` server will listen `http://{local_host}:{port}` for updates + +It is therefore required a reverse proxy passing incoming requests to local_host. + +**Example of nginx reverse proxy serving this purpose** +```nginx +server { + listen 8553 ssl; + listen [::]:8553 ssl; + + server_name example.com www.example.com; + + location /telegram/ { + proxy_pass http://127.0.0.5:8552/; + } + + ssl_certificate /path/to/fullchain.pem; + ssl_certificate_key /path/to/privkey.pem; +} + +``` + +**Example of python configuration file in this situation** +```python +# File config.py, gitignored and imported in main script +hostname = "https://www.example.com:8553/telegram" +certificate = "/path/to/fullchain.pem" +local_host = "127.0.0.5" +port = 8552 +``` diff --git a/davtelepot/__init__.py b/davtelepot/__init__.py index 8669be3..4778882 100644 --- a/davtelepot/__init__.py +++ b/davtelepot/__init__.py @@ -7,7 +7,7 @@ __author__ = "Davide Testa" __email__ = "davide@davte.it" __credits__ = ["Marco Origlia", "Nick Lee @Nickoala"] __license__ = "GNU General Public License v3.0" -__version__ = "2.0.4" +__version__ = "2.0.5" __maintainer__ = "Davide Testa" __contact__ = "t.me/davte" diff --git a/examples/webhook_powered_bot.py b/examples/webhook_powered_bot.py new file mode 100644 index 0000000..1faf865 --- /dev/null +++ b/examples/webhook_powered_bot.py @@ -0,0 +1,106 @@ +"""Example showing how to use webhooks with davtelepot.""" + +# Standard library modules +import logging +import os +import sys + +# Third party modules +try: + from davtelepot.bot import Bot +except ImportError: + logging.error( + "Please install davtelepot library.\n" + "The use if a python virtual environment is advised.\n\n" + "```bash\n" + "pip -m venv env\n" + "env/bin/pip install davtelepot\n" + "env/bin/python davtelepot/examples/a_simple_bot.py" + "```" + ) + sys.exit(1) + +# Project modules +from a_simple_bot import initialize_bot + +# Get path of current script +path = os.path.dirname(__file__) + + +def _main(): + # Import or prompt user for bot token + try: + from secrets import webhook_bot_token + except ImportError: + webhook_bot_token = input("Enter bot token:\t\t") + with open( + f'{path}/secrets.py', + 'a' # Append to file, create if it does not exist + ) as secrets_file: + secrets_file.write(f'webhook_bot_token = "{webhook_bot_token}"\n') + try: + from secrets import hostname + except ImportError: + hostname = input("Enter host name:\t\t") + with open( + f'{path}/secrets.py', + 'a' # Append to file, create if it does not exist + ) as secrets_file: + secrets_file.write(f'hostname = "{hostname}"\n') + try: + from secrets import certificate + except ImportError: + certificate = input("Enter ssl certificate:\t\t") + with open( + f'{path}/secrets.py', + 'a' # Append to file, create if it does not exist + ) as secrets_file: + secrets_file.write(f'certificate = "{certificate}"\n') + try: + from secrets import local_host + except ImportError: + local_host = input("Enter local host:\t\t") + with open( + f'{path}/secrets.py', + 'a' # Append to file, create if it does not exist + ) as secrets_file: + secrets_file.write(f'local_host = "{local_host}"\n') + try: + from secrets import port + except ImportError: + port = input("Enter local port:\t\t") + with open( + f'{path}/secrets.py', + 'a' # Append to file, create if it does not exist + ) as secrets_file: + secrets_file.write(f'port = "{port}"\n') + + # Set logging preferences + log_formatter = logging.Formatter( + "%(asctime)s [%(module)-15s %(levelname)-8s] %(message)s", + style='%' + ) + root_logger = logging.getLogger() + root_logger.setLevel(logging.DEBUG) + consoleHandler = logging.StreamHandler() + consoleHandler.setFormatter(log_formatter) + consoleHandler.setLevel(logging.DEBUG) + root_logger.addHandler(consoleHandler) + + # Instantiate, initialize and make `webhook_bot` run. + webhook_bot = Bot( + token=webhook_bot_token, + database_url=f"{path}/webhook_bot.db", + hostname=hostname, + certificate=certificate + ) + initialize_bot(webhook_bot) + logging.info("Send a KeyboardInterrupt (ctrl+C) to stop bots.") + Bot.run( + local_host=local_host, + port=port + ) + + +if __name__ == '__main__': + _main()