/telegram-pycon-pl-2022

End-to-end Telegram bot development and deployment

Primary LanguagePythonThe UnlicenseUnlicense

End-to-end Telegram bot development and deployment

Download Telegram Desktop

Navigate to https://desktop.telegram.org/ to download Telegram Desktop.

BotFather

Create a new bot with BotFather

Search for @BotFather Telegram bot and click START button: botfather_newbot_0001.png

Send /newbot command: botfather_newbot_0002.png

Send bot name (e.g., PyConPLBot): botfather_newbot_0003.png

Send bot username (e.g., PyConPLBot). It must end with bot: botfather_newbot_0004.png

Copy and save the token (e.g., 5741693832:AAFyfYpqWRHaGVhTt9CO4edV7bTlNR7bvaA): botfather_newbot_0005.png

Turn on inline mode

Navigate to @BotFather Telegram bot and send /mybots command: botfather_edit_bot_0001.png

Choose a bot from the list (e.g., @PyConPLBot): botfather_edit_bot_0002.png

Click Bot Settings button: botfather_edit_bot_0003.png

Click Inline Mode button: botfather_edit_bot_0004.png

Click Turn on button: botfather_edit_bot_0005.png

Add inline placeholder

Click Edit inline placeholder button: botfather_edit_bot_0006.png

Send placeholder (e.g., buy and sell prices of foreign currencies): botfather_edit_bot_0007.png

Success! Inline setting updated: botfather_edit_bot_0008.png

Host Telegram bot locally

Hello world bot with pyTelegramBotAPI

Lets start with Hello, World! bot written with pyTelegramBotAPI.

$ git clone https://github.com/korniichuk/telegram-pycon-pl-2022.git
$ cd telegram-pycon-pl-2022

Install requirements:

$ pip install -r requirements.txt

Create .env file with token:

$ touch .env

Copy and past token to .env file:

$ echo TOKEN=<TOKEN> > .env

Example:

$ echo TOKEN=5741693832:AAFyfYpqWRHaGVhTt9CO4edV7bTlNR7bvaA > .env

Start Hello, World! bot:

$ python3 bot1.py

Navigate to your Telegram bot (e.g., @PyConPLBot) and click START button:

hello_world_bot.png

You can achieve the same result with /start command.

Synchronous NBP bot with pyTelegramBotAPI

$ python3 bot2.py

Navigate to your Telegram bot (e.g., @PyConPLBot) and send /start command.

Test table A, table B, and table C buttons:

table_c_command.png

Send /a, /b, and /c commands:

c_command.png

Create a new Telegram group (e.g., PyCon PL group). Add your Telegram bot (e.g., @PyConPLBot) to the group. Add your friend(s) (optional).

Test /start@<you_bot_username> (e.g., /start@pyconplbot) command:

telegram_group.png

Communication with Telegram bots is not always easy. You had to send them messages in separate chats or add them to your groups.

With the inline mode, bots become omnipresent and can be used as a tool in any of your chats, groups or channels – it doesn't matter, whether the bot is a member or not.

Open chat with your friend(s) or create a new Telegram group, and type the username of your bot (e.g., @pyconplbot). You can see inline placeholder now (e.g., buy and sell prices of foreign currencies):

inline_placeholder.png

Type space and rate command (e.g., @pyconplbot rate):

inline_mode.png

Select USD: inline_mode_usd.png

See result: inline_mode_usd_result.png

Asynchronous NBP bot with pyTelegramBotAPI

$ python3 bot3.py

Asynchronous NBP bot with python-telegram-bot

$ python3 bot4.py

Asynchronous NBP bot with aiogram

$ python3 bot5.py

Note: Parse mode Markdown is legacy since Telegram Bot API 4.5, retained for backward compatibility. Source: https://core.telegram.org/bots/api#formatting-options

Deploy on AWS with SAM

Install SAM

$ wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip
$ unzip aws-sam-cli-linux-x86_64.zip -d sam-installation
$ sudo ./sam-installation/install

$ sam --version

Source: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html

Token

Insert your token to lambda_function.py file. For example, from:

TOKEN = "<TOKEN>" # token from @BotFather for your Telegram bot

to:

TOKEN = "5741693832:AAFyfYpqWRHaGVhTt9CO4edV7bTlNR7bvaA"

SAM build

$ cd ..
$ cd aws-serverless-application-model

$ sam build

SAM deploy

$ sam deploy --guided

Enter Stack Name (e.g., telegram). Enter AWS Region (e.g., eu-west-1).

Confirm changes before deploy [y/N]

Enter Y.

Allow SAM CLI IAM role creation [Y/n]:

Enter Y.

Disable rollback [y/N]:

Enter N.

MyLambdaFunction Function Url may not have authorization defined, Is this okay? [y/N]:

Enter Y.

Save arguments to configuration file [Y/n]: 

Enter Y.

Enter SAM configuration file name (e.g., samconfig.toml).

Enter SAM configuration environment (e.g., default).

Copy and save the Lambda URL Value from terminal (e.g., https://avi4v7gy25zo4lizhqqzh3dtom0zufol.lambda-url.eu-west-1.on.aws/).

Setting Telegram bot WebHook

All you have to do is to call the setWebhook method in the Bot API via the following url:

https://api.telegram.org/bot{TOKEN}/setWebhook?url={URL}/

Where:

  • TOKEN -- token you got from BotFather when you created your bot,
  • URL -- Lambda URL for the MyLambdaFunction (must be HTTPS).

Exmaple:

https://api.telegram.org/bot5741693832:AAFyfYpqWRHaGVhTt9CO4edV7bTlNR7bvaA/setWebhook?url=https://avi4v7gy25zo4lizhqqzh3dtom0zufol.lambda-url.eu-west-1.on.aws/

{"ok":true,"result":true,"description":"Webhook was set"}

Source: https://xabaras.medium.com/setting-your-telegram-bot-webhook-the-easy-way-c7577b2d6f72

Delete Telegram bot WebHook

To delete Telegram bot WebHook:

https://api.telegram.org/bot{TOKEN}/setWebhook?url=

Example:

https://api.telegram.org/bot5741693832:AAFyfYpqWRHaGVhTt9CO4edV7bTlNR7bvaA/setWebhook?url=

{"ok":true,"result":true,"description":"Webhook was deleted"}

SAM delete

To delete the sample application that you created, use the AWS CLI:

$ sam delete

Deploy on AWS with Elastic Beanstalk

The following example is written on pyTelegramBotAPI. See aiogram example: https://stackoverflow.com/a/64911415

AWS CLI

Install AWS CLI:

$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install

$ aws --version

Source: https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html#getting-started-install-instructions

EB CLI

Install EB CLI:

$ pip install awsebcli

$ eb --version

Source: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3-install-advanced.html

EB init

Navigate to aws-elastic-beanstalk folder and initialize the directory with the EB CLI:

$ cd aws-elastic-beanstalk

$ eb init

Select a default region (e.g., eu-west-1). Enter a new application name for your Elastic Beanstalk application (e.g., telegram).

It appears you are using Python. Is this correct?
(Y/n):

Enter Y.

Select a platform branch (e.g., Python 3.8 running on 64bit Amazon Linux 2). Details: https://docs.aws.amazon.com/elasticbeanstalk/latest/platforms/platforms-supported.html#platforms-supported.python

Do you want to set up SSH for your instances?
(Y/n):

Enter Y.

EB create

Create a new Elastic Beanstalk environment:

$ eb create

Enter environment name (e.g., telegram-dev). Enter DNS CNAME prefix (e.g., telegram-dev). Select a load balancer type (e.g., application).

Would you like to enable Spot Fleet requests for this environment? (y/N):

Enter N.

EB setenv

To set Telegram token as an environment variable in the EB CLI, run the following command:

$ eb setenv TOKEN=<TOKEN>

Example:

$ eb setenv TOKEN=5741693832:AAFyfYpqWRHaGVhTt9CO4edV7bTlNR7bvaA

Source: https://aws.amazon.com/premiumsupport/knowledge-center/elastic-beanstalk-pass-variables/

EB deploy

To deploy new source code to the environment:

$ eb deploy

EB open

Open the EB application URL in a browser:

$ eb open

If you can see exclamation mark, Telegram bot deployed successfully:

eb_open.png

Domain name

This part is out of workshop scope! We need to purchase and configure a custom domain name (e.g., telegrambot.click for 3 USD) for our Elastic Beanstalk environment.

SSL certificate

This part is out of workshop scope! We need use HTTPS to allow secure connection.

To set up SSL we need to obtain SSL certificate:

  1. Navigate to AWS Certificate Manager (ACM).
  2. Click Request certificate link or Request button. Select Request a public certificate. Click Next.
  3. Add two domain names: one for website (e.g., korniichuk.click) and one wildcard domain (e.g., *.korniichuk.click). It will cover all subdomains including www or any other.
  4. Select DNS validation and click Request button.

Because we delegated domain management to AWS, we need to validate ownership by expanding any domain and clicking Create records in Route 53.

SSL certificate will be issued after a while (it can take up to 48 hours - usually within 30 minutes after nameservers delegation is completed).

Source: https://dev.to/bnn1/deploying-dockerized-nextjs-app-to-aws-eb-part-3-setting-custom-domain-45bm

Add listener

This part is out of workshop scope!

  1. Open the Elastic Beanstalk console, and in the Regions list, select your AWS Region (e.g., eu-west-1).
  2. In the navigation pane, choose Environments, and then choose the name of your environment from the list (e.g., telegram-dev).
  3. In the navigation pane, choose Configuration.
  4. In the Load balancer configuration category, choose Edit. Note: If the Load balancer configuration category doesn't have an Edit button, your environment doesn't have a load balancer.
  5. On the Modify Application Load Balancer page, choose Add listener.
  6. For Port, type the incoming traffic 443 port.
  7. For Protocol, choose HTTPS.
  8. For SSL certificate, choose your certificate. Choose Add. Scroll down and click Apply

Important: Adding listener this way (via Elastic Beanstalk) will fix security group automatically. For adding listener via EC2 you need to fix security group manually.

Source: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https-elb.html

Add DNS record

This part is out of workshop scope!

dns_record.png

EB terminate

To delete bot from AWS cloud, terminate the environment:

$ eb terminate

Extra sources

  1. Long polling vs Webhooks
  2. Sample Python Telegram bot AWS serverless
  3. Error code: 429. Description: Too Many Requests