[ZILANT] обновление механизма setwebhook с секретным токеном
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
+36
-10
@@ -14,7 +14,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
|
from telegram_relay import configure_telebot_api, get_relay_url, bot_api_method_url
|
||||||
|
|
||||||
# Создаем Flask app на верхнем уровне для экспорта
|
# Создаем Flask app на верхнем уровне для экспорта
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
@@ -28,6 +28,8 @@ CHANNEL_ID = os.getenv('CHANNEL_ID')
|
|||||||
WEBHOOK_URL = os.getenv('WEBHOOK_URL')
|
WEBHOOK_URL = os.getenv('WEBHOOK_URL')
|
||||||
WEBHOOK_PORT = int(os.getenv('WEBHOOK_PORT', '8443'))
|
WEBHOOK_PORT = int(os.getenv('WEBHOOK_PORT', '8443'))
|
||||||
WEBHOOK_SECRET = os.getenv('WEBHOOK_SECRET')
|
WEBHOOK_SECRET = os.getenv('WEBHOOK_SECRET')
|
||||||
|
if WEBHOOK_SECRET:
|
||||||
|
WEBHOOK_SECRET = WEBHOOK_SECRET.strip().strip('"').strip("'")
|
||||||
LOG_FILE = os.getenv('LOG_FILE', 'bot.log')
|
LOG_FILE = os.getenv('LOG_FILE', 'bot.log')
|
||||||
RELAY_URL = os.getenv('RELAY_URL')
|
RELAY_URL = os.getenv('RELAY_URL')
|
||||||
|
|
||||||
@@ -1436,14 +1438,28 @@ def setup_webhook():
|
|||||||
"""Настройка вебхука через ретранслятор (доставка на WEBHOOK_URL)."""
|
"""Настройка вебхука через ретранслятор (доставка на WEBHOOK_URL)."""
|
||||||
logger.info("starting setup_webhook")
|
logger.info("starting setup_webhook")
|
||||||
last_error = None
|
last_error = None
|
||||||
# setWebhook сам заменяет предыдущий URL; deleteWebhook не нужен и удваивает нагрузку на API.
|
# Явный 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:
|
||||||
bot.set_webhook(
|
resp = requests.post(api_url, json=payload, timeout=60)
|
||||||
url=WEBHOOK_URL,
|
try:
|
||||||
secret_token=WEBHOOK_SECRET,
|
data = resp.json()
|
||||||
max_connections=40,
|
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}"
|
||||||
@@ -1485,9 +1501,19 @@ def _webhook_retry_after(exc):
|
|||||||
# Используем путь из WEBHOOK_URL
|
# Используем путь из WEBHOOK_URL
|
||||||
@app.route(WEBHOOK_PATH, methods=['POST'])
|
@app.route(WEBHOOK_PATH, methods=['POST'])
|
||||||
def webhook():
|
def webhook():
|
||||||
logger.info(f"starting webhook")
|
logger.info("starting webhook")
|
||||||
if request.headers.get('X-Telegram-Bot-Api-Secret-Token') != WEBHOOK_SECRET:
|
received_secret = request.headers.get("X-Telegram-Bot-Api-Secret-Token")
|
||||||
logger.warning("Неверный секретный токен!")
|
if received_secret != WEBHOOK_SECRET:
|
||||||
|
if not received_secret:
|
||||||
|
logger.warning(
|
||||||
|
"Секретный токен отсутствует в заголовке "
|
||||||
|
"(не зарегистрирован в Telegram или relay его не пробросил)"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
logger.warning(
|
||||||
|
"Секретный токен не совпадает "
|
||||||
|
f"(получен len={len(received_secret)}, ожидается len={len(WEBHOOK_SECRET or '')})"
|
||||||
|
)
|
||||||
log_event("security", "system", message="Попытка доступа с неверным секретным токеном")
|
log_event("security", "system", message="Попытка доступа с неверным секретным токеном")
|
||||||
return "Unauthorized", 401
|
return "Unauthorized", 401
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user