1

我正在尝试使用 nginx+gunicorn 在 django 上部署电报机器人(usign pyTelegramBotApi)。我已经有 fomain 和 Let's Encrypt 证书,https 正在工作并且 django 呈现的页面可以访问。但我不知道,为什么机器人没有收到任何数据。我在部署步骤上做错了吗?

处理 webhook 的 Django 视图:

def telegram(request):
    if request.method == 'POST':
        json_string = request.POST.get()
        update = telebot.types.Update.de_json(json_string)
        bot.process_new_updates([update])
    return HttpResponse('')


def set_hook(request):
    bot.remove_webhook()
    bot.set_webhook(url='https://<my domain>.tk/bot{}'.format(API_TOKEN))
    return HttpResponse('')

nginx配置:

server {
    server_name <my domain>.tk www.<my domain>.tk default_server;
    listen 80;

    return 301 https://<my domain>.tk;
}

server {
    server_name www.<my domain>.tk;
    listen 443 ssl http2;

    ssl_certificate /etc/letsencrypt/live/<my domain>.tk/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/<my domain>.tk/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/<my domain>.tk/chain.pem;

    ssl_stapling on;
    ssl_stapling_verify on;

    add_header Strict-Transport-Security "max-age=31536000";

    return 301 https://<my domain>.tk$request_uri;
}

server {

    server_name <my domain>.tk;
    listen 443 ssl http2;

    ssl_certificate /etc/letsencrypt/live/<my domain>.tk/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/<my domain>.tk/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/<my domain>.tk/chain.pem;

    ssl_stapling on;
    ssl_stapling_verify on;

    add_header Strict-Transport-Security "max-age=31536000";

    add_header X-Frame-Options "SAMEORIGIN";

    location /.well-known {
        root /var/www/html; # Понадобится для letsencrypt
    }

    location = /favicon.ico {
        alias /home/ubuntu/<my domain>/static/favicon.ico;
    }
    location = /robots.txt {
        alias /home/ubuntu/<my domain>/static/robots.txt;
    }

    location /static/ {
        root /home/ubuntu/<my domain>/;
    }
    location /media/ {
        root /home/ubuntu/<my domain>/;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/home/ubuntu/<my domain>/socket.sock;
    }
}

GUnicorn 服务配置:

[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/<my domain>/
ExecStart=/home/ubuntu/<my domain>/venv/bin/gunicorn --access-logfile - --error-logfile error.log --workers 2 --bind unix:/home/ubuntu/<my domain>/socket.sock fri_weekend_bot.wsgi:application

[Install]
WantedBy=multi-user.target
4

1 回答 1

0

我的问题隐藏在 django 部分。默认情况下,所有 django 视图都需要 CSRF 身份验证。我所要做的就是将 @csrf_exempt 装饰器放在 telegram() 视图上以避免这种情况。

@csrf_exempt
def telegram(request):
    if request.method == 'POST':
        json_string = json.dumps(json.loads(request.body))
        update = telebot.types.Update.de_json(json_string)
        bot.process_new_updates([update])
    return HttpResponse('')
于 2019-04-23T11:19:16.197 回答