2

Context

I'm currently following this tutorial. - Telegram Bot with Python Tutorial #3: Creating Bot and Webhook | Project


FIRST STEP

I have set-up a Flask server using the following python code:

from flask import Flask
from flask import request
from flask import Response
import json

app = Flask(__name__)


@app.route('/', methods=['POST', 'GET'])
def index():
    if request.method == 'POST':

        print(request)

        message = request.json()

        with open('telegram_request.json', 'w', encoding='utf-8') as filename:
            json.dump(message, filename, ensure_ascii=False, indent=4)

        # prevents telegram from spamming
        return Response('Ok', status=200)
    else:
        return """
            <h1> Flask Server </h1>
            <h2> Up and running </h2>
        """


if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=8443)


SECOND STEP

I port forwarded port 8443 in my router to make the server visible to the outside world (tunneling step in tutorial).

The domain name "myprivatedomain.com:8443" now redirects/refers to the flask server that is set-up.


THIRD STEP

I set-up the Telegram-API webhook correctly, getting the following response code from Telegram:

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


NOW

Before sending a message in the Telegram chat: there were no errors.

After sending a message in the chat, the following errors popped up:

code 400, message Bad HTTP/0.9 request type ('RANDOM BYTE VALUES like \x00\x03')

code 400, message Bad request syntax ('RANDOM BYTE VALUES like \x00\x03')

code 400, message Bad request version ('RANDOM BYTE VALUES like \x00\x03')


WHAT I WANT

According to the tutorial, you can write a .json file when Telegram makes a POST request (see example: here). I want to save the message object provided by the Telegram webhook (as showcased in the tutorial video). Using the webhook for getting updates is better than constantly querying the getUpdates() method; that method returns old messages also.


WHAT I'VE TRIED

I've tried to add:

ssl_context='adhoc'

to

app.run(debug=True, host='0.0.0.0', port=8443)

to make the connection HTTPS.

While using this ssl_context, loading the homepage isn't possible either..


PREFERABLE OUTPUT

When the user sends a message inside the Telegram chat --> Python saves a .json file of the message object.

JaFizz
  • 328
  • 2
  • 20

1 Answers1

3

You need to have SSL enabled for this to work. Telegram is trying to initiate an SSL session with your server, but you don't have SSL enabled, so you are seeing the bad request.

ssl_context='adhoc' may work for a test app, but I also have a hunch that telegram requires a VALID SSL certificate, not just an ad-hoc (or self-signed one). Notice the lock to the left of the URL in the video and the lack of a security warning that would be present with an invalid or self-signed certificate.

To make sure SSL is working set the ssl_context to adhoc, start the app, and browse to https://myprivatedomain.com:8443/index. If you can browse to it, then Telegram will also be able to browse to it, after getting a valid certificate, of course.

Next, to get a valid (and free) SSL certificate you can use LetsEncrypt.

Once you have a valid SSL certificate and key file you can pass the ssl_context argument to app.run with a tuple of the path to the certificate file and the path to the key file ("/path/to/fullchain.pem", "/path/to/privkey.pem")

Your full run function should look like this

app.run(debug=True, host='0.0.0.0', port=8443, ssl_context=("/path/to/fullchain.pem", "/path/to/privkey.pem"))

Alternatively you can use Apache or Nginx to secure your site with SSL, and reverse proxy to your bot. Those options would normally be used in a final product, so I understand if you don't want to get into the weeds with them right now, but it is good practice regardless.

Hopefully that helps.

jgeigerm
  • 140
  • 5
  • Thanks for your answer! Telegram indeed was expecting a SSL certificate. I played around with certbot, let'sEncrypt and sslforfree with Flask but nothing worked.. Finally, I chose to set-up the webhook using PHP (which was easier because I already have shared hosting with PHP running on it). Setting-up nginx or apache with reverse proxy will maybe be something for later :D... For now, I'm getting my messages :) – JaFizz Dec 22 '19 at 22:04