为什么我不能在用Flask(Python)编写的电报bot上收到任何POST请求?

2024-05-13 13:51:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我不想使用getUpdates方法从电报中检索更新,而是使用webhook

来自getWebhookInfo的错误是:

has_custom_certificate: false,
pending_update_count: 20,
last_error_date: 1591888018,
last_error_message: "SSL error {error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed}"

我的代码是:

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

app = Flask(__name__)

@app.route('/', methods=['POST', 'GET']) 
def bot():
    if request.method == 'POST':
        return Response('Ok', status=200)
    else:
        return f'--- GET request ----'

if __name__ == "__main__":
    app.run(host='0.0.0.0', port='8443', debug=True, ssl_context=('./contract.crt', '.private.key'))

当我点击https://www.mydomain.ext:8443/时,当我在我的电报聊天机器人上写东西时,我可以看到收到的请求,但看不到发出的请求 这也是我为telegram设置webhook的方式,如下所示:

https://api.telegram.org/botNUMBER:TELEGRAM_KEY/setWebhook?url=https://www.mydomain.ext:8443

结果:

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

有什么建议或我做错了什么吗

https://core.telegram.org/bots/api#setwebhook

我想知道它引起的问题是否是因为我使用了0.0.0,原因是如果我使用127.0.0.0无法访问url/www.mydomain.ext

更新

ca_certitificate = {'certificate': open('./folder/ca.ca-bundle', 'rb')}
r = requests.post(url, files=ca_certitificate)
print(r.text)

那张照片给了我:

{
  "ok": false,
  "error_code": 400,
  "description": "Bad Request: bad webhook: Failed to set custom certificate file"
 }

Tags: fromhttpsimportappurlflaskrequestwww
3条回答

我刚才部署了一个没有烧瓶的电报聊天机器人。 我记得POST和GET请求需要/getUpdates/sendMessage添加到bot url。也许会有帮助

电报机器人程序仅适用于全链证书。以及getWebHookInfo中的错误:

"last_error_message":"SSL error {337047686, error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed}"

是电报说它需要整个证书链(也称为CA包或全链证书)。正如在question上所回答的那样

如果使用SSLlabs验证证书,您将看到您的域存在链问题:

https://www.ssllabs.com/ssltest/analyze.html?d=www.vallotta-party-bot.com&hideResults=on

要解决此问题,您需要设置CA证书。这样,您需要通过CA提供商查找CA证书文件

此外,在生产现场最好的选择是使用gunicorn而不是烧瓶

如果您使用的是gunicorn,则可以使用命令行参数执行此操作:

$ gunicorn  certfile cert.pem  keyfile key.pem  ca_certs cert.ca-bundle -b 0.0.0.0:443 hello:app

或创建具有以下内容的gunicorn.py

import multiprocessing

bind = "0.0.0.0:443"

workers = multiprocessing.cpu_count() * 2 + 1

timeout = 120

certfile = "cert/certfile.crt"

keyfile = "cert/service-key.pem"

ca_certs = "cert/cert.ca-bundle"

loglevel = 'info'

并按如下方式运行:

gunicorn  config=gunicorn.py hello:app

如果您使用Nginx作为反向代理,那么您可以使用Nginx配置证书,然后Nginx可以“终止”加密连接,这意味着它将接受来自外部的加密连接,但随后使用常规的未加密连接与您的后端通信。这是一个非常有用的设置,因为它使您的应用程序不必处理证书和加密。Nginx的配置项如下:

server {
    listen 443 ssl;
    server_name example.com;
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    # ...
}

您需要考虑的另一个重要事项是如何处理通过常规HTTP连接的客户端将被处理。在我看来,最好的解决方案是通过重定向到相同的URL(但使用HTTPS)来响应未加密的请求。对于烧瓶应用,您可以使用烧瓶SSLify扩展来实现这一点。使用Nginx,您可以在配置中包括另一个服务器块:

server {
    listen 80;
    server_name example.com;
    location / {
        return 301 https://$host$request_uri;
    }
}

关于如何使用https设置应用程序的一个很好的教程可以在这里找到:Running Your Flask Application Over HTTPS

我也有类似的情况。我在本地主机上开发bot(但没有SSL),并通过ngrok将其传输到web。一开始一切都还可以,但一旦我发现没有帖子请求就来了。事实证明,挖掘隧道的时间已经过去了。我笑了,重新开始挖隧道。但是请求没有来。结果,我忘了更改webhook的地址(它会切换每个ngrok会话)。不要重复我的错误

相关问题 更多 >