This commit is contained in:
@@ -6,6 +6,9 @@ LOG_FILE = /opt/testbot-git/logs/testzilantposter.log
|
|||||||
WORKMODE = "ZILANT"
|
WORKMODE = "ZILANT"
|
||||||
# WORKMODE = "VOLK"
|
# WORKMODE = "VOLK"
|
||||||
|
|
||||||
|
# Код сезона для deep link / callback подписок (zk2026_post_…, zk2026_event_…)
|
||||||
|
SEASON = "zk2026"
|
||||||
|
|
||||||
# Telegram API через internal_relay (retransbot) — обязательно
|
# Telegram API через internal_relay (retransbot) — обязательно
|
||||||
# Нужна схема http:// или https:// (если без схемы — подставится http://)
|
# Нужна схема http:// или https:// (если без схемы — подставится http://)
|
||||||
# Локально: http://127.0.0.1:5100 или http://192.168.0.109:5100
|
# Локально: http://127.0.0.1:5100 или http://192.168.0.109:5100
|
||||||
|
|||||||
Binary file not shown.
+7
-2
@@ -9,6 +9,7 @@ from datetime import datetime, timezone, timedelta
|
|||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from formatter import get_event_text
|
from formatter import get_event_text
|
||||||
from telegram_relay import bot_api_method_url
|
from telegram_relay import bot_api_method_url
|
||||||
|
from season_links import subscription_start_link
|
||||||
|
|
||||||
# Загрузка переменных окружения
|
# Загрузка переменных окружения
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
@@ -149,7 +150,9 @@ async def tg_post_event(httpx_client, event_data):
|
|||||||
links_parts.append(f'🔎 <a href="{DESC_PREFIX}{number}/">Инфо</a>')
|
links_parts.append(f'🔎 <a href="{DESC_PREFIX}{number}/">Инфо</a>')
|
||||||
if USE_SUBSCRIPTION_BOT:
|
if USE_SUBSCRIPTION_BOT:
|
||||||
links_parts.append(f'📌 <a href="{PZK_PREFIX}{number}/">Иду</a>')
|
links_parts.append(f'📌 <a href="{PZK_PREFIX}{number}/">Иду</a>')
|
||||||
links_parts.append(f'🔜 <a href="https://t.me/{RESPONDER_BOT_NAME}?start=event_{placeholder_message_id}">Подписка</a>')
|
links_parts.append(
|
||||||
|
f'🔜 <a href="{subscription_start_link(RESPONDER_BOT_NAME, "event", placeholder_message_id)}">Подписка</a>'
|
||||||
|
)
|
||||||
|
|
||||||
if links_parts:
|
if links_parts:
|
||||||
links_line_placeholder = ' | '.join(links_parts)
|
links_line_placeholder = ' | '.join(links_parts)
|
||||||
@@ -357,7 +360,9 @@ async def tg_post_event(httpx_client, event_data):
|
|||||||
links_parts.append(f'🔎 <a href="{DESC_PREFIX}{number}/">Инфо</a>')
|
links_parts.append(f'🔎 <a href="{DESC_PREFIX}{number}/">Инфо</a>')
|
||||||
if USE_SUBSCRIPTION_BOT:
|
if USE_SUBSCRIPTION_BOT:
|
||||||
links_parts.append(f'📌 <a href="{PZK_PREFIX}{number}/">Иду</a>')
|
links_parts.append(f'📌 <a href="{PZK_PREFIX}{number}/">Иду</a>')
|
||||||
links_parts.append(f'🔜 <a href="https://t.me/{RESPONDER_BOT_NAME}?start=event_{message_id}">Подписка</a>')
|
links_parts.append(
|
||||||
|
f'🔜 <a href="{subscription_start_link(RESPONDER_BOT_NAME, "event", message_id)}">Подписка</a>'
|
||||||
|
)
|
||||||
|
|
||||||
if links_parts:
|
if links_parts:
|
||||||
links_line = ' | '.join(links_parts)
|
links_line = ' | '.join(links_parts)
|
||||||
|
|||||||
+127
@@ -0,0 +1,127 @@
|
|||||||
|
"""
|
||||||
|
Сезонные deep link и callback для подписок.
|
||||||
|
|
||||||
|
Формат текущего сезона (SEASON=zk2026):
|
||||||
|
start=zk2026_post_{tg_message_id}
|
||||||
|
start=zk2026_event_{tg_message_id}
|
||||||
|
callback: subscribe_zk2026_{id} / unsubscribe_zk2026_{id}
|
||||||
|
callback: subscribe_evt_zk2026_{id} / unsubscribe_evt_zk2026_{id}
|
||||||
|
|
||||||
|
Старые форматы (post_123, event_123, subscribe_123, …) и чужой сезон
|
||||||
|
считаются завершённым прошлым сезоном.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
from typing import Optional, Tuple
|
||||||
|
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
_ENV_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), ".env")
|
||||||
|
load_dotenv(_ENV_PATH)
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
SEASON = (os.getenv("SEASON") or "zk2026").strip().strip('"').strip("'")
|
||||||
|
|
||||||
|
# start: zk2026_post_123 / zk2026_event_123
|
||||||
|
_START_RE = re.compile(
|
||||||
|
rf"^(?P<season>[A-Za-z0-9]+)_((?P<kind>post|event)_)(?P<id>\d+)$"
|
||||||
|
)
|
||||||
|
# legacy start: post_123 / event_123
|
||||||
|
_START_LEGACY_RE = re.compile(r"^(?P<kind>post|event)_(?P<id>\d+)$")
|
||||||
|
|
||||||
|
# callback posts: subscribe_zk2026_123
|
||||||
|
_CB_POST_RE = re.compile(
|
||||||
|
r"^(?P<action>subscribe|unsubscribe)_(?P<season>[A-Za-z0-9]+)_(?P<id>\d+)$"
|
||||||
|
)
|
||||||
|
# legacy: subscribe_123
|
||||||
|
_CB_POST_LEGACY_RE = re.compile(r"^(?P<action>subscribe|unsubscribe)_(?P<id>\d+)$")
|
||||||
|
|
||||||
|
# callback events: subscribe_evt_zk2026_123
|
||||||
|
_CB_EVT_RE = re.compile(
|
||||||
|
r"^(?P<action>subscribe|unsubscribe)_evt_(?P<season>[A-Za-z0-9]+)_(?P<id>\d+)$"
|
||||||
|
)
|
||||||
|
# legacy: subscribe_evt_123
|
||||||
|
_CB_EVT_LEGACY_RE = re.compile(r"^(?P<action>subscribe|unsubscribe)_evt_(?P<id>\d+)$")
|
||||||
|
|
||||||
|
|
||||||
|
def subscription_start_link(bot_name: str, kind: str, message_id) -> str:
|
||||||
|
"""HTTPS deep link на бота: kind = 'post' | 'event'."""
|
||||||
|
payload = f"{SEASON}_{kind}_{message_id}"
|
||||||
|
return f"https://t.me/{bot_name}?start={payload}"
|
||||||
|
|
||||||
|
|
||||||
|
def callback_subscribe_post(message_id) -> str:
|
||||||
|
return f"subscribe_{SEASON}_{message_id}"
|
||||||
|
|
||||||
|
|
||||||
|
def callback_unsubscribe_post(message_id) -> str:
|
||||||
|
return f"unsubscribe_{SEASON}_{message_id}"
|
||||||
|
|
||||||
|
|
||||||
|
def callback_subscribe_event(message_id) -> str:
|
||||||
|
return f"subscribe_evt_{SEASON}_{message_id}"
|
||||||
|
|
||||||
|
|
||||||
|
def callback_unsubscribe_event(message_id) -> str:
|
||||||
|
return f"unsubscribe_evt_{SEASON}_{message_id}"
|
||||||
|
|
||||||
|
|
||||||
|
def parse_start_payload(payload: str) -> Tuple[Optional[str], Optional[str], bool]:
|
||||||
|
"""
|
||||||
|
Разбор аргумента /start.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
(kind, id, is_current_season)
|
||||||
|
kind: 'post' | 'event' | None
|
||||||
|
is_current_season: False → показать «сезон завершён»
|
||||||
|
"""
|
||||||
|
if not payload:
|
||||||
|
return None, None, True
|
||||||
|
|
||||||
|
m = _START_RE.match(payload)
|
||||||
|
if m:
|
||||||
|
return m.group("kind"), m.group("id"), m.group("season") == SEASON
|
||||||
|
|
||||||
|
m = _START_LEGACY_RE.match(payload)
|
||||||
|
if m:
|
||||||
|
return m.group("kind"), m.group("id"), False
|
||||||
|
|
||||||
|
# Неизвестный payload — считаем устаревшим/чужим, без действия по id
|
||||||
|
return None, None, False
|
||||||
|
|
||||||
|
|
||||||
|
def parse_post_callback(data: str) -> Tuple[Optional[str], Optional[str], bool]:
|
||||||
|
"""
|
||||||
|
Returns:
|
||||||
|
(action, id, is_current_season) для кнопок подписки на посты.
|
||||||
|
action: 'subscribe' | 'unsubscribe' | None
|
||||||
|
"""
|
||||||
|
if data.startswith("subscribe_evt_") or data.startswith("unsubscribe_evt_"):
|
||||||
|
return None, None, True
|
||||||
|
|
||||||
|
m = _CB_POST_RE.match(data)
|
||||||
|
if m:
|
||||||
|
return m.group("action"), m.group("id"), m.group("season") == SEASON
|
||||||
|
|
||||||
|
m = _CB_POST_LEGACY_RE.match(data)
|
||||||
|
if m:
|
||||||
|
return m.group("action"), m.group("id"), False
|
||||||
|
|
||||||
|
return None, None, True
|
||||||
|
|
||||||
|
|
||||||
|
def parse_event_callback(data: str) -> Tuple[Optional[str], Optional[str], bool]:
|
||||||
|
"""
|
||||||
|
Returns:
|
||||||
|
(action, id, is_current_season) для кнопок подписки на события.
|
||||||
|
"""
|
||||||
|
m = _CB_EVT_RE.match(data)
|
||||||
|
if m:
|
||||||
|
return m.group("action"), m.group("id"), m.group("season") == SEASON
|
||||||
|
|
||||||
|
m = _CB_EVT_LEGACY_RE.match(data)
|
||||||
|
if m:
|
||||||
|
return m.group("action"), m.group("id"), False
|
||||||
|
|
||||||
|
return None, None, True
|
||||||
+116
-35
@@ -16,6 +16,16 @@ 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, bot_api_method_url
|
||||||
|
from season_links import (
|
||||||
|
SEASON,
|
||||||
|
callback_subscribe_post,
|
||||||
|
callback_unsubscribe_post,
|
||||||
|
callback_subscribe_event,
|
||||||
|
callback_unsubscribe_event,
|
||||||
|
parse_start_payload,
|
||||||
|
parse_post_callback,
|
||||||
|
parse_event_callback,
|
||||||
|
)
|
||||||
|
|
||||||
# Создаем Flask app на верхнем уровне для экспорта
|
# Создаем Flask app на верхнем уровне для экспорта
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
@@ -179,6 +189,7 @@ logger.info(f"Telegram Bot API через ретранслятор: {relay}")
|
|||||||
|
|
||||||
# Создаем экземпляр бота
|
# Создаем экземпляр бота
|
||||||
bot = telebot.TeleBot(RESPONDER_BOT_TOKEN)
|
bot = telebot.TeleBot(RESPONDER_BOT_TOKEN)
|
||||||
|
logger.info(f"Сезон подписок SEASON={SEASON}")
|
||||||
|
|
||||||
def get_user_name(user):
|
def get_user_name(user):
|
||||||
"""Форматирует имя пользователя для записи в БД"""
|
"""Форматирует имя пользователя для записи в БД"""
|
||||||
@@ -572,6 +583,65 @@ def format_channel_link(post_id=None):
|
|||||||
else:
|
else:
|
||||||
return f"https://t.me/c/{CHANNEL_ID}"
|
return f"https://t.me/c/{CHANNEL_ID}"
|
||||||
|
|
||||||
|
|
||||||
|
def get_last_channel_message_id():
|
||||||
|
"""Максимальный tg_message_id среди опубликованных постов и событий (текущая БД)."""
|
||||||
|
conn = create_db_connection()
|
||||||
|
if conn is None:
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
with conn.cursor() as cursor:
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
SELECT MAX(mid) AS last_id FROM (
|
||||||
|
SELECT MAX(tg_message_id) AS mid FROM posts
|
||||||
|
WHERE tg_message_id IS NOT NULL AND tg_message_id > 0
|
||||||
|
UNION ALL
|
||||||
|
SELECT MAX(tg_message_id) AS mid FROM events
|
||||||
|
WHERE tg_message_id IS NOT NULL AND tg_message_id > 0
|
||||||
|
) t
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
row = cursor.fetchone()
|
||||||
|
last_id = row["last_id"] if row else None
|
||||||
|
return int(last_id) if last_id else None
|
||||||
|
except pymysql.Error as e:
|
||||||
|
logger.error(f"Ошибка получения последнего message_id канала: {e}")
|
||||||
|
return None
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
def get_return_to_channel_link():
|
||||||
|
"""Ссылка на последнее известное сообщение в канале или на сам канал."""
|
||||||
|
last_id = get_last_channel_message_id()
|
||||||
|
if last_id:
|
||||||
|
return format_channel_link(last_id)
|
||||||
|
return format_channel_link()
|
||||||
|
|
||||||
|
|
||||||
|
def create_season_ended_keyboard():
|
||||||
|
keyboard = InlineKeyboardMarkup()
|
||||||
|
keyboard.row(
|
||||||
|
InlineKeyboardButton("↩ Вернуться в канал", url=get_return_to_channel_link())
|
||||||
|
)
|
||||||
|
return keyboard
|
||||||
|
|
||||||
|
|
||||||
|
def send_season_ended_message(chat_id):
|
||||||
|
"""Ответ на клик по подписке прошлого сезона (или без префикса SEASON)."""
|
||||||
|
logger.info(f"send_season_ended_message chat_id={chat_id}, current SEASON={SEASON}")
|
||||||
|
text = (
|
||||||
|
"Этот сезон уже завершён.\n\n"
|
||||||
|
"Подписки и кнопки из прошлых анонсов больше не работают. "
|
||||||
|
"Актуальные события — в канале."
|
||||||
|
)
|
||||||
|
bot.send_message(
|
||||||
|
chat_id,
|
||||||
|
text,
|
||||||
|
reply_markup=create_season_ended_keyboard(),
|
||||||
|
)
|
||||||
|
|
||||||
def create_help_keyboard():
|
def create_help_keyboard():
|
||||||
"""Создает клавиатуру для справки"""
|
"""Создает клавиатуру для справки"""
|
||||||
logger.info(f"starting create_help_keyboard")
|
logger.info(f"starting create_help_keyboard")
|
||||||
@@ -601,13 +671,13 @@ def create_manage_keyboard(post_id, is_subscribed):
|
|||||||
if is_subscribed:
|
if is_subscribed:
|
||||||
keyboard.row(
|
keyboard.row(
|
||||||
InlineKeyboardButton("❓ Справка", callback_data="cmd_help"),
|
InlineKeyboardButton("❓ Справка", callback_data="cmd_help"),
|
||||||
InlineKeyboardButton("❌ Отписаться", callback_data=f"unsubscribe_{post_id}"),
|
InlineKeyboardButton("❌ Отписаться", callback_data=callback_unsubscribe_post(post_id)),
|
||||||
InlineKeyboardButton("↪ Назад", url=channel_link)
|
InlineKeyboardButton("↪ Назад", url=channel_link)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
keyboard.row(
|
keyboard.row(
|
||||||
InlineKeyboardButton("❓ Справка", callback_data="cmd_help"),
|
InlineKeyboardButton("❓ Справка", callback_data="cmd_help"),
|
||||||
InlineKeyboardButton("✔ Подписаться", callback_data=f"subscribe_{post_id}"),
|
InlineKeyboardButton("✔ Подписаться", callback_data=callback_subscribe_post(post_id)),
|
||||||
InlineKeyboardButton("↪ Назад", url=channel_link)
|
InlineKeyboardButton("↪ Назад", url=channel_link)
|
||||||
)
|
)
|
||||||
return keyboard
|
return keyboard
|
||||||
@@ -621,13 +691,13 @@ def create_manage_keyboard_evt(event_id, is_subscribed):
|
|||||||
if is_subscribed:
|
if is_subscribed:
|
||||||
keyboard.row(
|
keyboard.row(
|
||||||
InlineKeyboardButton("❓ Справка", callback_data="cmd_help"),
|
InlineKeyboardButton("❓ Справка", callback_data="cmd_help"),
|
||||||
InlineKeyboardButton("❌ Отписаться", callback_data=f"unsubscribe_evt_{event_id}"),
|
InlineKeyboardButton("❌ Отписаться", callback_data=callback_unsubscribe_event(event_id)),
|
||||||
InlineKeyboardButton("↪ Назад", url=channel_link)
|
InlineKeyboardButton("↪ Назад", url=channel_link)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
keyboard.row(
|
keyboard.row(
|
||||||
InlineKeyboardButton("❓ Справка", callback_data="cmd_help"),
|
InlineKeyboardButton("❓ Справка", callback_data="cmd_help"),
|
||||||
InlineKeyboardButton("✔ Подписаться", callback_data=f"subscribe_evt_{event_id}"),
|
InlineKeyboardButton("✔ Подписаться", callback_data=callback_subscribe_event(event_id)),
|
||||||
InlineKeyboardButton("↪ Назад", url=channel_link)
|
InlineKeyboardButton("↪ Назад", url=channel_link)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1028,17 +1098,18 @@ def handle_start(message):
|
|||||||
user_name = get_user_name(user)
|
user_name = get_user_name(user)
|
||||||
|
|
||||||
if len(args) > 1:
|
if len(args) > 1:
|
||||||
# Обработка команды подписки на посты
|
kind, entity_id, is_current = parse_start_payload(args[1])
|
||||||
if args[1].startswith('post_'):
|
if not is_current:
|
||||||
post_id = args[1].split('_')[1]
|
send_season_ended_message(message.chat.id)
|
||||||
# Отправляем сообщение управления подпиской
|
|
||||||
send_management_message(message.chat.id, post_id, user_id, user_name)
|
|
||||||
return
|
return
|
||||||
# Обработка команды подписки на события
|
if kind == "post" and entity_id:
|
||||||
elif args[1].startswith('event_'):
|
send_management_message(message.chat.id, entity_id, user_id, user_name)
|
||||||
event_id = args[1].split('_')[1]
|
return
|
||||||
# Отправляем сообщение управления подпиской
|
if kind == "event" and entity_id:
|
||||||
send_management_message_evt(message.chat.id, event_id, user_id, user_name)
|
send_management_message_evt(message.chat.id, entity_id, user_id, user_name)
|
||||||
|
return
|
||||||
|
# Неизвестный payload текущего сезона
|
||||||
|
send_season_ended_message(message.chat.id)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Команда /start без параметров
|
# Команда /start без параметров
|
||||||
@@ -1312,17 +1383,26 @@ def handle_callback(call):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Обработка кнопок управления подпиской на посты
|
# Обработка кнопок управления подпиской на посты
|
||||||
if (call.data.startswith("subscribe_") or call.data.startswith("unsubscribe_")) and not call.data.startswith(("subscribe_evt_", "unsubscribe_evt_")):
|
action, post_id, is_current = parse_post_callback(call.data)
|
||||||
|
if action and post_id:
|
||||||
|
if not is_current:
|
||||||
|
bot.answer_callback_query(call.id, "Этот сезон уже завершён")
|
||||||
|
send_season_ended_message(call.message.chat.id)
|
||||||
|
return
|
||||||
|
|
||||||
user = call.from_user
|
user = call.from_user
|
||||||
user_id = user.id
|
user_id = user.id
|
||||||
user_name = get_user_name(user)
|
user_name = get_user_name(user)
|
||||||
|
|
||||||
# Разделяем данные callback
|
if not get_post_data(post_id):
|
||||||
parts = call.data.split('_', 1)
|
bot.answer_callback_query(call.id, "Анонс не найден")
|
||||||
action = parts[0]
|
bot.send_message(
|
||||||
post_id = parts[1]
|
call.message.chat.id,
|
||||||
|
"❌ Анонс не найден в базе данных текущего сезона.",
|
||||||
|
reply_markup=create_season_ended_keyboard(),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
# Выполняем действие
|
|
||||||
if action == "subscribe":
|
if action == "subscribe":
|
||||||
save_mark_to_db(post_id, user_id, user_name)
|
save_mark_to_db(post_id, user_id, user_name)
|
||||||
result_text = "✅ Вы успешно подписались!"
|
result_text = "✅ Вы успешно подписались!"
|
||||||
@@ -1371,15 +1451,26 @@ def handle_callback(call):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Обработка кнопок управления подпиской на события
|
# Обработка кнопок управления подпиской на события
|
||||||
if call.data.startswith("subscribe_evt_") or call.data.startswith("unsubscribe_evt_"):
|
action, event_id, is_current = parse_event_callback(call.data)
|
||||||
|
if action and event_id:
|
||||||
|
if not is_current:
|
||||||
|
bot.answer_callback_query(call.id, "Этот сезон уже завершён")
|
||||||
|
send_season_ended_message(call.message.chat.id)
|
||||||
|
return
|
||||||
|
|
||||||
user = call.from_user
|
user = call.from_user
|
||||||
user_id = user.id
|
user_id = user.id
|
||||||
user_name = get_user_name(user)
|
user_name = get_user_name(user)
|
||||||
parts = call.data.split('_', 2)
|
|
||||||
action = parts[0]
|
|
||||||
event_id = parts[2]
|
|
||||||
|
|
||||||
# Выполняем действие
|
if not get_event_data(event_id):
|
||||||
|
bot.answer_callback_query(call.id, "Событие не найдено")
|
||||||
|
bot.send_message(
|
||||||
|
call.message.chat.id,
|
||||||
|
"❌ Событие не найдено в базе данных текущего сезона.",
|
||||||
|
reply_markup=create_season_ended_keyboard(),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
if action == "subscribe":
|
if action == "subscribe":
|
||||||
save_mark_to_db_evt(event_id, user_id, user_name)
|
save_mark_to_db_evt(event_id, user_id, user_name)
|
||||||
result_text = "✅ Вы успешно подписались!"
|
result_text = "✅ Вы успешно подписались!"
|
||||||
@@ -1387,22 +1478,14 @@ def handle_callback(call):
|
|||||||
remove_mark_from_db_evt(event_id, user_id, user_name)
|
remove_mark_from_db_evt(event_id, user_id, user_name)
|
||||||
result_text = "✅ Вы успешно отписались!"
|
result_text = "✅ Вы успешно отписались!"
|
||||||
|
|
||||||
# Обновляем сообщение с новым статусом
|
|
||||||
try:
|
try:
|
||||||
# Получаем текущие данные о событии
|
|
||||||
event_data = format_event_message(event_id)
|
event_data = format_event_message(event_id)
|
||||||
text = event_data['text']
|
text = event_data['text']
|
||||||
|
|
||||||
# Создаем новую клавиатуру
|
|
||||||
is_subscribed = action == "subscribe"
|
is_subscribed = action == "subscribe"
|
||||||
keyboard = create_manage_keyboard_evt(event_id, is_subscribed)
|
keyboard = create_manage_keyboard_evt(event_id, is_subscribed)
|
||||||
|
|
||||||
# Для сообщений с изображением
|
|
||||||
if call.message.content_type == 'photo':
|
if call.message.content_type == 'photo':
|
||||||
# Получаем file_id существующего изображения
|
|
||||||
file_id = call.message.photo[-1].file_id
|
|
||||||
|
|
||||||
# Редактируем подпись к изображению
|
|
||||||
bot.edit_message_caption(
|
bot.edit_message_caption(
|
||||||
chat_id=call.message.chat.id,
|
chat_id=call.message.chat.id,
|
||||||
message_id=call.message.message_id,
|
message_id=call.message.message_id,
|
||||||
@@ -1411,7 +1494,6 @@ def handle_callback(call):
|
|||||||
parse_mode='HTML'
|
parse_mode='HTML'
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# Редактируем текстовое сообщение
|
|
||||||
bot.edit_message_text(
|
bot.edit_message_text(
|
||||||
chat_id=call.message.chat.id,
|
chat_id=call.message.chat.id,
|
||||||
message_id=call.message.message_id,
|
message_id=call.message.message_id,
|
||||||
@@ -1420,7 +1502,6 @@ def handle_callback(call):
|
|||||||
parse_mode='HTML'
|
parse_mode='HTML'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Отправляем отдельное сообщение о результате
|
|
||||||
bot.answer_callback_query(call.id, result_text)
|
bot.answer_callback_query(call.id, result_text)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Ошибка обновления сообщения (events): {e}")
|
logger.error(f"Ошибка обновления сообщения (events): {e}")
|
||||||
|
|||||||
+7
-2
@@ -17,6 +17,7 @@ from telegram import Bot
|
|||||||
from telegram.error import TelegramError, TimedOut
|
from telegram.error import TelegramError, TimedOut
|
||||||
from telegram.request import HTTPXRequest
|
from telegram.request import HTTPXRequest
|
||||||
from telegram_relay import get_ptb_base_urls, get_relay_url
|
from telegram_relay import get_ptb_base_urls, get_relay_url
|
||||||
|
from season_links import subscription_start_link
|
||||||
|
|
||||||
# Настройка anyio для правильной работы в отдельном потоке
|
# Настройка anyio для правильной работы в отдельном потоке
|
||||||
# Устанавливаем правильный backend для anyio (используем asyncio)
|
# Устанавливаем правильный backend для anyio (используем asyncio)
|
||||||
@@ -232,7 +233,9 @@ async def publish_to_tg(vk_post_id):
|
|||||||
|
|
||||||
# Ссылка на подписку (только для событий и если включен бот подписки)
|
# Ссылка на подписку (только для событий и если включен бот подписки)
|
||||||
if post['is_event'] and USE_SUBSCRIPTION_BOT:
|
if post['is_event'] and USE_SUBSCRIPTION_BOT:
|
||||||
links.append(f'<a href="https://t.me/{RESPONDER_BOT_NAME}?start=post_{placeholder_message_id}">🔜 Подписка</a>')
|
links.append(
|
||||||
|
f'<a href="{subscription_start_link(RESPONDER_BOT_NAME, "post", placeholder_message_id)}">🔜 Подписка</a>'
|
||||||
|
)
|
||||||
|
|
||||||
# Формируем строку ссылок
|
# Формируем строку ссылок
|
||||||
links_line = " | ".join(links) if links else ""
|
links_line = " | ".join(links) if links else ""
|
||||||
@@ -419,7 +422,9 @@ async def publish_to_tg(vk_post_id):
|
|||||||
updated_links.append(f'<a href="{post["vk_post_url"]}">Оригинал в ВК</a>')
|
updated_links.append(f'<a href="{post["vk_post_url"]}">Оригинал в ВК</a>')
|
||||||
|
|
||||||
if post['is_event'] and USE_SUBSCRIPTION_BOT:
|
if post['is_event'] and USE_SUBSCRIPTION_BOT:
|
||||||
updated_links.append(f'<a href="https://t.me/{RESPONDER_BOT_NAME}?start=post_{message_id}">🔜 Подписка</a>')
|
updated_links.append(
|
||||||
|
f'<a href="{subscription_start_link(RESPONDER_BOT_NAME, "post", message_id)}">🔜 Подписка</a>'
|
||||||
|
)
|
||||||
|
|
||||||
links_line = " | ".join(updated_links)
|
links_line = " | ".join(updated_links)
|
||||||
final_text = f"{text}\n\n{links_line}"
|
final_text = f"{text}\n\n{links_line}"
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import json
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from telegram_relay import bot_api_method_url, get_relay_url
|
from telegram_relay import bot_api_method_url, get_relay_url
|
||||||
|
from season_links import subscription_start_link
|
||||||
|
|
||||||
# Загрузка переменных окружения
|
# Загрузка переменных окружения
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
@@ -94,7 +95,11 @@ async def test_telegram_publish():
|
|||||||
# Формируем строку ссылок
|
# Формируем строку ссылок
|
||||||
placeholder_message_id = '1234567890'
|
placeholder_message_id = '1234567890'
|
||||||
if USE_SUBSCRIPTION_BOT:
|
if USE_SUBSCRIPTION_BOT:
|
||||||
links_line = f'🔎 <a href="{DESC_PREFIX}{test_number}/">Инфо</a> | 📌 <a href="{PZK_PREFIX}{test_number}/">Иду</a> | 🔜 <a href="https://t.me/{RESPONDER_BOT_NAME}?start=event_{placeholder_message_id}">Подписка</a>'
|
links_line = (
|
||||||
|
f'🔎 <a href="{DESC_PREFIX}{test_number}/">Инфо</a> | '
|
||||||
|
f'📌 <a href="{PZK_PREFIX}{test_number}/">Иду</a> | '
|
||||||
|
f'🔜 <a href="{subscription_start_link(RESPONDER_BOT_NAME, "event", placeholder_message_id)}">Подписка</a>'
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
links_line = f'🔎 <a href="{DESC_PREFIX}{test_number}/">Инфо</a>'
|
links_line = f'🔎 <a href="{DESC_PREFIX}{test_number}/">Инфо</a>'
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user