—Заметки

Свой прокси для Telegram Bot API на nginx

Небольшой гайд, как поднять собственный домен-обёртку над api.telegram.org на своём nginx, без Cloudflare Workers и без единой строчки кода. Идея взята из проекта telegram-bot-api-worker, но реализована средствами самого nginx — воркер там на деле делает одну вещь: подменяет хост в запросе и проксирует его дальше как есть. То же самое proxy_pass умеет из коробки.

Зачем это нужно

Что понадобится

Итоговый результат

Запрос вида

https://api.telegram.org/bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11/getMe

начинает работать через ваш домен:

https://ваш-домен/api/bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11/getMe

и отдаёт ровно тот же ответ — метод, тело запроса, заголовки и файлы (для sendPhoto/sendDocument) прокидываются как есть.

Шаг 1. DNS

Создайте A-запись поддомена (например, bot-api.example.com) на IP вашего сервера. Дайте записи немного времени на распространение перед выпуском сертификата.

Шаг 2. Сертификат

sudo certbot certonly --nginx -d bot-api.example.com

Если у вас уже есть сайт на этом же домене/поддомене с действующим сертификатом — этот шаг можно пропустить и использовать существующие пути к сертификату.

Шаг 3. Конфиг nginx

Замените bot-api.example.com на свой домен.

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

server {
    listen 443 ssl http2;
    server_name bot-api.example.com;

    ssl_certificate     /etc/letsencrypt/live/bot-api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/bot-api.example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location /api/bot {
        # /api/bot123:ABC.../getMe  ->  /bot123:ABC.../getMe
        rewrite ^/api/(bot.*)$ /$1 break;

        proxy_pass https://api.telegram.org;
        proxy_ssl_server_name on;
        proxy_http_version 1.1;
        proxy_set_header Host api.telegram.org;
        proxy_set_header Connection "";

        client_max_body_size 50m;   # sendDocument / sendPhoto — Telegram принимает файлы до 50 МБ
        proxy_read_timeout 60s;
    }

    location / {
        return 404;
    }
}

Почему конфиг устроен именно так

Директива Зачем
location /api/bot Ловит только запросы к боту, не пересекается с остальным сайтом на этом же домене
rewrite ^/api/(bot.*)$ /$1 break Убирает /api спереди, оставляя оригинальный путь /bot<token>/<method>, который ждёт Telegram
proxy_set_header Host api.telegram.org Обязательно: без этого nginx отправит апстриму Host: bot-api.example.com, и Telegram не поймёт запрос
proxy_ssl_server_name on Корректный SNI при TLS-соединении к api.telegram.org
client_max_body_size 50m Иначе загрузка файлов через бота будет обрываться на лимите по умолчанию (1 МБ)
тело, метод, заголовки Прокидываются как есть — proxy_pass копирует запрос без изменений, JSON и multipart работают одинаково

Если у вас на этом домене уже есть сайт — просто добавьте location /api/bot { ... } в существующий server { listen 443 ssl ... } блок, ничего дублировать не нужно.

Применить конфиг:

sudo nginx -t && sudo systemctl reload nginx

Шаг 4. Проверка

curl "https://bot-api.example.com/api/bot<TOKEN>/getMe"

Должен вернуться тот же JSON, что и при прямом запросе к api.telegram.org.

Как переключить на него бота

Большинство библиотек позволяют задать свой apiRoot/baseApiUrl вместо api.telegram.org.

Node.js, node-telegram-bot-api:

const TelegramBot = require('node-telegram-bot-api');

const bot = new TelegramBot(TOKEN, {
  baseApiUrl: 'https://bot-api.example.com/api',
  polling: true,
});

Node.js, telegraf:

const { Telegraf } = require('telegraf');

const bot = new Telegraf(TOKEN, {
  telegram: { apiRoot: 'https://bot-api.example.com/api' },
});

Python, pyTelegramBotAPI (telebot):

import telebot
from telebot import apihelper

apihelper.API_URL = "https://bot-api.example.com/api/bot{0}/{1}"

bot = telebot.TeleBot(TOKEN)

curl / любой HTTP-клиент: просто замените api.telegram.org на bot-api.example.com/api в URL.

Важно понимать перед использованием

Источник идеи

Оригинальная реализация на Cloudflare Workers: manzoorwanijk/telegram-bot-api-worker. Этот гайд — тот же принцип, но без воркера, средствами голого nginx.

← ко всем записям