diff --git a/tg_mainbot.py b/tg_mainbot.py index 878f833..cf6d015 100644 --- a/tg_mainbot.py +++ b/tg_mainbot.py @@ -2,6 +2,7 @@ import os import logging import time import errno +import asyncio from dotenv import load_dotenv import telebot from telebot import apihelper @@ -14,7 +15,7 @@ import requests from io import BytesIO from flask import Flask, request from formatter import get_post_text, get_event_text -from telegram_relay import configure_telebot_api, get_relay_url, bot_api_method_url +from telegram_relay import configure_telebot_api, get_relay_url # Создаем Flask app на верхнем уровне для экспорта app = Flask(__name__) @@ -1435,31 +1436,18 @@ def handle_callback(call): bot.answer_callback_query(call.id, "Произошла ошибка. Пожалуйста, попробуйте позже.") def setup_webhook(): - """Настройка вебхука через ретранслятор (доставка на WEBHOOK_URL).""" + """ + Настройка вебхука через ретранслятор — как в retransbot/testunit/echobot.py: + python-telegram-bot Bot.set_webhook(url=..., secret_token=...). + PTB передаёт параметры form-urlencoded (httpx data=), и relay их корректно + пробрасывает в Telegram вместе с secret_token. + """ logger.info("starting setup_webhook") last_error = None - # Явный JSON POST: telebot часто шлёт form/query, и secret_token может не дойти - # до Telegram через перехватчик relay — тогда апдейты приходят без заголовка. - api_url = bot_api_method_url(RESPONDER_BOT_TOKEN, "setWebhook") - payload = { - "url": WEBHOOK_URL, - "max_connections": 40, - } - if WEBHOOK_SECRET: - payload["secret_token"] = WEBHOOK_SECRET for attempt in range(1, 6): try: - resp = requests.post(api_url, json=payload, timeout=60) - try: - data = resp.json() - except Exception: - data = {"ok": False, "description": resp.text[:500]} - desc = str(data.get("description", "")) if isinstance(data, dict) else "" - if resp.status_code == 429 or "retry after" in desc.lower(): - raise RuntimeError(desc or f"HTTP {resp.status_code}") - if not (isinstance(data, dict) and data.get("ok")): - raise RuntimeError(f"setWebhook failed: HTTP {resp.status_code} {data}") + asyncio.run(_setup_webhook_ptb()) logger.info( f"Вебхук установлен через ретранслятор {get_relay_url()}: " f"локальная доставка {WEBHOOK_URL}" @@ -1486,6 +1474,37 @@ def setup_webhook(): raise RuntimeError(error_msg) from last_error +async def _setup_webhook_ptb(): + """Регистрация webhook через PTB — тот же стек, что у проверенного echobot.""" + from telegram import Bot + from telegram.request import HTTPXRequest + from telegram_relay import get_ptb_base_urls + + base_url, base_file_url = get_ptb_base_urls() + request_kw = HTTPXRequest( + connect_timeout=30.0, + read_timeout=60.0, + write_timeout=60.0, + pool_timeout=10.0, + ) + tg_bot = Bot( + token=RESPONDER_BOT_TOKEN, + base_url=base_url, + base_file_url=base_file_url, + request=request_kw, + ) + try: + ok = await tg_bot.set_webhook( + url=WEBHOOK_URL, + secret_token=WEBHOOK_SECRET, + max_connections=40, + ) + if not ok: + raise RuntimeError("set_webhook returned False") + finally: + await tg_bot.shutdown() + + def _webhook_retry_after(exc): """Извлекает секунды ожидания из 429 / 'retry after N', иначе None.""" text = str(exc) @@ -1506,8 +1525,7 @@ def webhook(): if received_secret != WEBHOOK_SECRET: if not received_secret: logger.warning( - "Секретный токен отсутствует в заголовке " - "(не зарегистрирован в Telegram или relay его не пробросил)" + "Секретный токен отсутствует в заголовке X-Telegram-Bot-Api-Secret-Token" ) else: logger.warning(