Creating a Telegram Bot with Python-Flask (MacOS)

Jonathan Tan
5 min readSep 17, 2023

--

In this tutorial, I will be showing you how to get your Telegram Bot started locally on MacOS. I believe the steps can be replicated on Windows or Linux as well. In another article, I will be showing you how to deploy the python-flask server.

Telegram BotFather and Python-Flask

Step 1: Setting up your python-flask server

For quick set-up you may fork my python-flask server repository. Simply follow the steps in the readme.

Python-Flask Server Repository: https://github.com/jonathantan12/python-flask-server-template

Alternatively, you may refer to this, https://flask.palletsprojects.com/en/2.3.x/quickstart/.

Step 2: Create a Telegram Bot

With a telegram application downloaded, search for BotFather.

Click “Start”. Which will start the prompt with the BotFather using /start.

Select /newbot.

Give a name to your telegram Bot with the username ending with bot. For example, TetrisBot or tetris_bot.

Once done, take note of your API key which you will use in your development of your telegram bot later on.

Step 3: Set up ngrok — For port tunneling.

ngrok is a cross-platform application that enables developers to expose a local development server to the Internet with minimal effort. The software makes your locally-hosted web server appear to be hosted on a subdomain of ngrok.com, meaning that no public IP or domain name on the local machine is needed. (https://www.pubnub.com/guides/what-is-ngrok/)

To set up ngrok, you may review this detailed guide on ngrok on how to get started. https://ngrok.com/docs/getting-started/

For macOS, use HomeBrew:

brew install ngrok/ngrok/ngrok

For Windows, use Chocolatey:

choco install ngrok

To test that ngrok is up and running:

    $ ngrok -h

NAME:
ngrok - tunnel local ports to public URLs and inspect traffic

USAGE:
ngrok [command] [flags]

DESCRIPTION:
ngrok exposes local networked services behinds NATs and firewalls to the
public internet over a secure tunnel. Share local websites, build/test
webhook consumers and self-host personal services.
Detailed help for each command is available with 'ngrok help <command>'.
Open http://localhost:4040 for ngrok's web interface to inspect traffic.

Author:
ngrok - <support@ngrok.com>

TERMS OF SERVICE: https://ngrok.com/tos

EXAMPLES:
ngrok http 80 # secure public URL for port 80 web server
ngrok http --domain baz.ngrok.dev 8080 # port 8080 available at baz.ngrok.dev
ngrok http foo.dev:80 # tunnel to host:port instead of localhost
ngrok http https://localhost # expose a local https server
ngrok tcp 22 # tunnel arbitrary TCP traffic to port 22
ngrok tls --domain=foo.com 443 # TLS traffic for foo.com to port 443
ngrok start foo bar baz # start tunnels from the configuration file

COMMANDS:
api use ngrok agent as an api client
completion generates shell completion code for bash or zsh
config update or migrate ngrok's configuration file
credits prints author and licensing information
diagnose diagnose connection issues
help Help about any command
http start an HTTP tunnel
service run and control an ngrok service on a target operating system
start start tunnels by name from the configuration file
tcp start a TCP tunnel
tls start a TLS tunnel
tunnel start a tunnel for use with a tunnel-group backend
update update ngrok to the latest version
version print the version string

OPTIONS:
--config strings path to config files; they are merged if multiple
-h, --help help for ngrok
-v, --version version for ngrok

Start ngrok:

ngrok http 5000

You should see something similar to the screenshot below.

Step 4: Set up Webhook between your telegram-bot and python-flask server.

Run this line in your browser. The URL is the one that is forwarding the request from the internet to your localhost. In this case, the link ending with the .ngrok-free.app

https://api.telegram.org/bot<Your Bot Token>/setWebhook?url=<URL that you got from Ngrok>

After running, your browser will return you:

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

Next, we will want to test if your bot is connected. Return to code editor and insert this POST route. If you have forked my repository, you can insert this into dashboard.py

@app.route('/', methods=['POST'])
def post():
if request.method == 'POST':
# Access POST data from the request
msg = request.get_json()

print(msg)

return Response('ok', status=200)

Now if you start your bot again by entering /start into your bot, you will see this result in your terminal.

With the response (message), we can see that we are able to gather the information of the user and command.

Now to enable your bot to receive and reply to your chat, you can replace the POST route with this code:

@app.route('/', methods=['POST'])
def post_example():
if request.method == 'POST':
# Access POST data from the request
msg = request.get_json()
print("Message: ",msg)

# Trying to parse message
try:
print("There is a text")
chat_id = msg['message']['chat']['id']
text = msg['message']['text'] # This gets the text from the msg

if text == "are you alive?":

url = f'https://api.telegram.org/bot{bot_token}/sendMessage' # Calling the telegram API to reply the message

payload = {
'chat_id': chat_id,
'text': "yes, I am alive"
}

r = requests.post(url, json=payload)

if r.status_code == 200:
return Response('ok', status=200)
else:
return Response('Failed to send message to Telegram', status=500)
except:
print("No text found")

return Response('ok', status=200)

In the end, if you were to type “are you alive?” to your telegram bot, it will receive your text and reply “yes, I am alive”.

Note: I have placed my bot token in my environment variable file.

Github Source Code: https://github.com/jonathantan12/telegrambot_flask_setup

--

--

Jonathan Tan

👋 I'm Jonathan, a software engineer from Singapore. I am passionate about learning and crafting new solutions. Feel free to connect with me!