+1 vote
by
Good afternoon!

I want to translate my telegram bot to webhook, so I took the webhook_flask_echo_bot.py example from the pyTelegramBotAPI module for testing.
I rented a VPS, bound it to duckdns.org, got a certificate with certbot --nginx, certificate rating A+
Switched the bot to webhook while in the directory with the certificate:
https://api.telegram.org/botBOT_TOKEN/setWebhook?url=https://my-host.duckdns.org:8443/BOT_TOKEN/


I run a test bot on a VPS:
import logging
import time
import flask
import telebot

API_TOKEN = 'BOT_TOKEN'

WEBHOOK_HOST = 'my-host.duckdns.org'
WEBHOOK_PORT = 8443
WEBHOOK_LISTEN = '0.0.0.0'

WEBHOOK_SSL_CERT = '/etc/letcencrypt/archive/my-host.duckdns.org/fullchain1.pem'
WEBHOOK_SSL_PRIV = '/etc/letcencrypt/archive/my-host.duckdns.org/privkey1.pem'

WEBHOOK_URL_BASE = "https://%s:%s" % (WEBHOOK_HOST, WEBHOOK_PORT)
WEBHOOK_URL_PATH = "/%s/" % (API_TOKEN)

logger = telebot.logger
telebot.logger.setLevel(logging.INFO)

bot = telebot.TeleBot(API_TOKEN)

app = flask.Flask(__name__)

# Empty webserver index, return nothing, just http 200
@app.route('/', methods=['GET', 'HEAD'])
def index():
return ''

Process webhook calls
@app.route(WEBHOOK_URL_PATH, methods=['POST'])
def webhook():
if flask.request.headers.get('content-type') == 'application/json':
json_string = flask.request.get_data().decode('utf-8')
update = telebot.types.Update.de_json(json_string)
bot.process_new_updates([update])
return ''
else:
flask.abort(403)

# Handle '/start' and '/help'
@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
bot.reply_to(message,
("Hi there, I am EchoBot.\n"
"I am here to echo your kind words back to you."))

# Handle all other messages
@bot.message_handler(func=lambda message: True, content_types=['text'])
def echo_message(message):
bot.reply_to(message, message.text)

# Remove webhook, it fails sometimes the set if there is a previous webhook
bot.remove_webhook()

time.sleep(1)

# Set webhook
bot.set_webhook(url=WEBHOOK_URL_BASE + WEBHOOK_URL_PATH,
certificate=open(WEBHOOK_SSL_CERT, 'r'))

# Start flask server
app.run(host=WEBHOOK_LISTEN,
port=WEBHOOK_PORT,
ssl_context=(WEBHOOK_SSL_CERT, WEBHOOK_SSL_PRIV),
debug=True)
After starting, GET requests are displayed in the logs, if the browser is addressed to https://my-host.duckdns.org:8443 But it does not respond to commands sent to the bot. When checking the status of the bot, I get:
{
"ok":true,
"result":{"url":"https://my-host.duckdns.org:8443/BOT_TOKEN/",
"has_custom_certificate":true,
"pending_update_count":19,
"last_error_date":1587364313,
"last_error_message":"SSL error {error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed}",
"max_connections":40}
}
Checking through the recommended bot in the documentation @CanofWormsBot I get: "This certified certificate is valid. Can you please tell me what the problem could be? Is it possible because the certificate is obtained on nginx and the webhook is up on flask?

1 Answer

0 votes
by
Telegram doesn't digest certificates well, especially self-signed ones. You can try to feed the certificate by passing the file in the parameter when installing webhook. If that doesn't help, check your certificate via openssl. The returned code should be 0 if the certificate is validated

An example of the commandoronsl s_client -connect my-host:duckdns.org:8443
...