运行自己的基于 PTB 13x 的 Telgram 机器人和 nginx 后面的本地 Telegram 机器人 API

问题描述 投票:0回答:1

尝试使用本地 Telegram 机器人 API 来利用较大的文件来为我的机器人提供服务并帮助超级组中的用户处理文件如此处所述 使用 Telegram Bot API 构建堆栈,nginx 作为反向代理,我的机器人工作正常,基于 docker-compose 模板:

version: '3.7'

networks:
  int:
    name: internal
    driver: bridge

services:
  api:
    hostname: local-api
    image: aiogram/telegram-bot-api:latest
    restart: always
    networks:
      - int
    environment:
      TELEGRAM_API_ID: BOT_ID
      TELEGRAM_API_HASH: BOT_HASH
      TELEGRAM_LOCAL: "true"
      TELEGRAM_HTTP_IP_ADDRESS: 0.0.0.0
      TELEGRAM_HTTP_PORT: 8081
      TELEGRAM_MAX_FILESIZE: 1000000000 # задава максимален размер на файла на 1GB
    volumes:
      - telegram-bot-api-data:/var/lib/telegram-bot-api

  nginx:
    hostname: nginx
    image: nginx:1.19-alpine
    restart: always
    depends_on:
      - api
    volumes:
      - telegram-bot-api-data:/var/lib/telegram-bot-api
      - ./nginx:/etc/nginx/conf.d/
    ports:
      - "88:88"
    networks:
      - int

  telegram-bot:
    depends_on:
     - api
     - nginx
    hostname : telegram-bot
    networks:
      - int
    restart: unless-stopped
    build:
      context: /root/docker/telegram-bot
      dockerfile: Dockerfile
    image: telegram-bot/latest
    environment:
      LOCAL_API_URL: http://nginx:88/bot
      LOCAL_API_FILES: http://nginx:88/file/bot
    labels:
      - "com.centurylinklabs.watchtower.enable=false"
    volumes:
      - /root/docker/telegram-bot/:/app/

volumes:
  telegram-bot-api-data:

并根据 nginx 配置进行重定向:

# use $sanitized_request instead of $request to hide Telegram token
log_format token_filter '$remote_addr - $remote_user [$time_local] '
                        '"$sanitized_request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent"';

upstream telegram-bot-api {
    server local-api:8081;
}

server {
    listen 88;

    chunked_transfer_encoding on;
    proxy_connect_timeout 600;
    proxy_send_timeout 600;
    proxy_read_timeout 600;
    send_timeout 600;
    client_max_body_size 2G;
    client_body_buffer_size 30M;
    keepalive_timeout 0;
    proxy_http_version 1.1;

    rewrite_log on;

    set $sanitized_request $request;
    if ( $sanitized_request ~ (\w+)\s(\/bot\d+):[-\w]+\/(\S+)\s(.*) ) {
        set $sanitized_request "$1 $2:<hidden-token>/$3 $4";
    }
    access_log /var/log/nginx/access.log token_filter;
    error_log /var/log/nginx/error.log notice;

    location ~* \/file\/bot\d+:(.*) {
        rewrite ^/file\/bot(.*) /$1 break;
        proxy_http_version  1.1;
        try_files $uri @files;
    }

    location / {
        try_files $uri @api;
        proxy_http_version  1.1;
    }

    location @files {
        root /var/lib/telegram-bot-api;
        gzip on;
        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 6;
        gzip_buffers 64 8k;
        gzip_http_version 1.1;
        gzip_min_length 1100;
    }

    location @api {
        proxy_pass  http://telegram-bot-api;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $server_name;
    }
}

最后 Telegram 机器人已设置为可与本地 Telegram Bot API 配合使用:

.env
LOCAL_API=True
LOCAL_API_URL=http://nginx:88/bot
LOCAL_API_FILES=http://nginx:88/file/bot

PTB 电报机器人设置

updater = Updater(config["BOT_TOKEN"], use_context = True, base_url = config["LOCAL_API_URL"], base_file_url = config["LOCAL_API_FILES"], arbitrary_callback_data = True)

一切正常,但文件重定向无法按预期工作 - 限制仍然存在,无法获取从机器人文件接收的本地链接

2023/04/04 11:15:52 [错误] 30#30: *15 open() “/var/lib/telegram-bot-api/TOKEN_ID:TOKEN_HASH/var/lib/telegram-bot-api/TOKEN_ID:TOKEN_HASH/documents/file_16.apk” 失败(2:没有这样的文件或目录),客户端:172.19.0.4,服务器:_, 请求:“获取 /file/botTOKEN_ID%3ATOKEN_HASH//var/lib/telegram-bot-api/TOKEN_ID%3ATOKEN_HASH/documents/file_16.apk HTTP/1.1”,主机:“nginx:81” 172.19.0.4 - - [04/Apr/2023:11:15:52 +0000]“获取/file/botTOKEN_ID%3ATOKEN_HASH//var/lib/telegram-bot-api/TOKEN_ID%3ATOKEN_HASH/documents/file_16.apk HTTP/1.1" 404 154 "-" "Python Telegram 机器人 (https://github.com/python-telegram-bot/python-telegram-bot)”

日志中有“重复路径” /var/lib/telegram-bot-api/TOKEN_ID:TOKEN_HASH/var/lib/telegram-bot-api/TOKEN_ID:TOKEN_HASH/documents/file_16.apk

尽管如此,curl 请求仍按预期工作

curl -i http://nginx:81/file/botTOKEN_ID:TOKEN_HASH/documents/file_16.apk

HTTP/1.1 200 OK 服务器:nginx/1.19.10 日期:2023 年 4 月 4 日星期二 14:31:01 GMT 内容类型:application/octet-stream 内容长度:10066456 最后修改时间:2023 年 4 月 4 日星期二 06:26:47 GMT 连接:关闭 ETag: “642bc327-999a18”接受范围:字节

警告:二进制输出可能会弄乱您的终端。使用“--输出-”来 告诉警告:卷曲将其输出到您的终端,或者考虑 “--output警告:”保存到文件。

无法意识到错误从哪里开始,机器人本身请求本地 API 或 nginx 重定向? 由于没有足够的时间进行 Probono 项目,因此无法在 PTB 20.x 上重写机器人。 欢迎任何想法!

编辑:错误的路径来自 context.bot.get_file(file_id) 并返回 file_path !

python nginx telegram telegram-bot python-telegram-bot
1个回答
0
投票

致其他遇到该用例的人 nginx.conf

# use $sanitized_request instead of $request to hide Telegram token
log_format token_filter '$remote_addr - $remote_user [$time_local] '
                        '"$sanitized_request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent"';

upstream telegram-bot-api {
    server local-api:8081;
}

server {
    listen 88;
    listen 8443 ssl;

    ssl_certificate /etc/nginx/conf.d/PUBLIC.pem;
    ssl_certificate_key /etc/nginx/conf.d/PRIVATE.key;
    ssl_session_timeout 5m;
    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
    ssl_prefer_server_ciphers on;

    server_name api.thetopper.eu;

    chunked_transfer_encoding on;
    proxy_connect_timeout 600;
    proxy_send_timeout 600;
    proxy_read_timeout 600;
    send_timeout 600;
    client_max_body_size 2G;
    client_body_buffer_size 30M;
    keepalive_timeout 0;

    set $sanitized_request $request;
    if ( $sanitized_request ~ (\w+)\s(\/bot\d+):[-\w]+\/(\S+)\s(.*) ) {
        set $sanitized_request "$1 $2:<hidden-token>/$3 $4";
    }
    access_log /var/log/nginx/access.log token_filter;

    location ~* \/file\/bot\d+:(.*) {
        rewrite ^/file\/bot(.*) /$1 break;
        try_files $uri @files;
    }

    location / {
        try_files $uri @api;
    }

    location @files {
        root /var/lib/telegram-bot-api;
        gzip on;
        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 6;
        gzip_buffers 64 8k;
        gzip_http_version 1.1;
        gzip_min_length 1100;
        # Remove /var/lib/telegram-bot-api/TOKEN_ID:TOKEN_HASH prefix from file path
        #rewrite ^/file/bot(.*)/(.*)$ /$1/$2 break;
        # Log $uri variable to Nginx error log
        error_log /var/log/nginx/error.log info;
        error_log /var/log/nginx/error.log debug_http;
    }

    location @api {
        proxy_pass  http://telegram-bot-api;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $server_name;
    }
}

config.env

LOCAL_API=True
LOCAL_API_URL=http://nginx:88/bot
LOCAL_API_FILES=http://nginx:88/file/bot

bot.py(PTB v13.15)

updater = Updater(config["BOT_TOKEN"], use_context=True, base_url=config["LOCAL_API_URL"],arbitrary_callback_data=True, base_file_url=config["LOCAL_API_FILES"])
....
file_name = update.message.document.file_name
file_name_id = update.message.document.file_id
file_path = f"/var/lib/telegram-bot-api/{config["BOT_TOKEN"]}/documents/{update.message.document.file_id.file_path.split('/')[-1]}"
© www.soinside.com 2019 - 2024. All rights reserved.