[ZILANT] изменение регистрации респондер-бота для корректного проброса секретного кода
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
+41
-23
@@ -2,6 +2,7 @@ import os
|
|||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
import errno
|
import errno
|
||||||
|
import asyncio
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
import telebot
|
import telebot
|
||||||
from telebot import apihelper
|
from telebot import apihelper
|
||||||
@@ -14,7 +15,7 @@ import requests
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from flask import Flask, request
|
from flask import Flask, request
|
||||||
from formatter import get_post_text, get_event_text
|
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 на верхнем уровне для экспорта
|
# Создаем Flask app на верхнем уровне для экспорта
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
@@ -1435,31 +1436,18 @@ def handle_callback(call):
|
|||||||
bot.answer_callback_query(call.id, "Произошла ошибка. Пожалуйста, попробуйте позже.")
|
bot.answer_callback_query(call.id, "Произошла ошибка. Пожалуйста, попробуйте позже.")
|
||||||
|
|
||||||
def setup_webhook():
|
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")
|
logger.info("starting setup_webhook")
|
||||||
last_error = None
|
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):
|
for attempt in range(1, 6):
|
||||||
try:
|
try:
|
||||||
resp = requests.post(api_url, json=payload, timeout=60)
|
asyncio.run(_setup_webhook_ptb())
|
||||||
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}")
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Вебхук установлен через ретранслятор {get_relay_url()}: "
|
f"Вебхук установлен через ретранслятор {get_relay_url()}: "
|
||||||
f"локальная доставка {WEBHOOK_URL}"
|
f"локальная доставка {WEBHOOK_URL}"
|
||||||
@@ -1486,6 +1474,37 @@ def setup_webhook():
|
|||||||
raise RuntimeError(error_msg) from last_error
|
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):
|
def _webhook_retry_after(exc):
|
||||||
"""Извлекает секунды ожидания из 429 / 'retry after N', иначе None."""
|
"""Извлекает секунды ожидания из 429 / 'retry after N', иначе None."""
|
||||||
text = str(exc)
|
text = str(exc)
|
||||||
@@ -1506,8 +1525,7 @@ def webhook():
|
|||||||
if received_secret != WEBHOOK_SECRET:
|
if received_secret != WEBHOOK_SECRET:
|
||||||
if not received_secret:
|
if not received_secret:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"Секретный токен отсутствует в заголовке "
|
"Секретный токен отсутствует в заголовке X-Telegram-Bot-Api-Secret-Token"
|
||||||
"(не зарегистрирован в Telegram или relay его не пробросил)"
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
|
|||||||
Reference in New Issue
Block a user