feat: add group support for webinar notifier
This commit is contained in:
@@ -3,7 +3,8 @@ import logging
|
||||
import redis
|
||||
import json
|
||||
|
||||
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup, ChatMember
|
||||
from telegram.constants import ChatType
|
||||
from telegram.ext import Application, CommandHandler, CallbackQueryHandler, ContextTypes
|
||||
from playwright.async_api import async_playwright
|
||||
|
||||
@@ -57,7 +58,7 @@ TRANSLATIONS = {
|
||||
'welcome_admin': "\n\n👑 <b>Режим администратора активен</b>",
|
||||
'access_denied': "⛔ Доступ запрещен. Вас нет в белом списке.",
|
||||
'help_title': "🤖 <b>Помощь по боту</b>\n\n",
|
||||
'help_commands': "/start - Подписаться на уведомления\n/help - Показать это сообщение\n/language - Сменить язык",
|
||||
'help_commands': "/start - Подписаться на уведомления\n/stop - Отписаться от уведомлений\n/help - Показать это сообщение\n/language - Сменить язык",
|
||||
'help_admin': "\n<b>Команды администратора:</b>\n/adduser [user_id] - Добавить пользователя в белый список\n/removeuser [user_id] - Удалить пользователя из белого списка\nИли используйте панель ниже для управления настройками.",
|
||||
'admin_only': "⛔ Только для администратора!",
|
||||
'user_added': "✅ Пользователь {user_id} добавлен в белый список",
|
||||
@@ -94,7 +95,7 @@ TRANSLATIONS = {
|
||||
'welcome_admin': "\n\n👑 <b>Режим адміністратора активний</b>",
|
||||
'access_denied': "⛔ Доступ заборонено. Вас немає в білому списку.",
|
||||
'help_title': "🤖 <b>Довідка по боту</b>\n\n",
|
||||
'help_commands': "/start - Підписатися на сповіщення\n/help - Показати це повідомлення\n/language - Змінити мову",
|
||||
'help_commands': "/start - Підписатися на сповіщення\n/stop - Відписатися від сповіщень\n/help - Показати це повідомлення\n/language - Змінити мову",
|
||||
'help_admin': "\n<b>Команди адміністратора:</b>\n/adduser [user_id] - Додати користувача до білого списку\n/removeuser [user_id] - Видалити користувача з білого списку\nАбо використовуйте панель нижче для керування налаштуваннями.",
|
||||
'admin_only': "⛔ Тільки для адміністратора!",
|
||||
'user_added': "✅ Користувач {user_id} доданий до білого списку",
|
||||
@@ -131,7 +132,7 @@ TRANSLATIONS = {
|
||||
'welcome_admin': "\n\n👑 <b>Admin Mode Active</b>",
|
||||
'access_denied': "⛔ Access denied. You are not on the whitelist.",
|
||||
'help_title': "🤖 <b>Bot Help</b>\n\n",
|
||||
'help_commands': "/start - Subscribe to notifications\n/help - Show this message\n/language - Change language",
|
||||
'help_commands': "/start - Subscribe to notifications\n/stop - Unsubscribe from notifications\n/help - Show this message\n/language - Change language",
|
||||
'help_admin': "\n<b>Admin Commands:</b>\n/adduser [user_id] - Add user to whitelist\n/removeuser [user_id] - Remove user from whitelist\nOr use the panel below to manage settings.",
|
||||
'admin_only': "⛔ Admin only!",
|
||||
'user_added': "✅ User {user_id} added to whitelist",
|
||||
@@ -212,6 +213,21 @@ def is_whitelisted(user_id: int) -> bool:
|
||||
|
||||
return redis_client.sismember(KEY_WHITELIST, str(user_id))
|
||||
|
||||
async def is_group_admin(update: Update, context: ContextTypes.DEFAULT_TYPE) -> bool:
|
||||
"""Check if the user is an administrator in the group."""
|
||||
user = update.effective_user
|
||||
chat = update.effective_chat
|
||||
|
||||
if chat.type in [ChatType.PRIVATE, "private"]:
|
||||
return True
|
||||
|
||||
try:
|
||||
member = await context.bot.get_chat_member(chat.id, user.id)
|
||||
return member.status in [ChatMember.OWNER, ChatMember.ADMINISTRATOR]
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to check admin status: {e}")
|
||||
return False
|
||||
|
||||
def get_admin_keyboard(user_id: int):
|
||||
"""Generate admin panel keyboard."""
|
||||
whitelist_enabled = redis_client.get(KEY_WHITELIST_ENABLED) != "0"
|
||||
@@ -230,19 +246,21 @@ def get_admin_keyboard(user_id: int):
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""Handle /start command."""
|
||||
user = update.effective_user
|
||||
logger.info(f"User {user.id} ({user.username}) started the bot.")
|
||||
chat = update.effective_chat
|
||||
logger.info(f"User {user.id} ({user.username}) started the bot in chat {chat.id} ({chat.type}).")
|
||||
|
||||
# Check whitelist - MUST be the user executing the command
|
||||
if not is_whitelisted(user.id):
|
||||
await update.message.reply_text(t(user.id, 'access_denied'))
|
||||
return
|
||||
|
||||
# Add to subscribers
|
||||
redis_client.sadd(KEY_SUBSCRIBERS, user.id)
|
||||
# Add to subscribers (Chat ID!)
|
||||
redis_client.sadd(KEY_SUBSCRIBERS, chat.id)
|
||||
|
||||
msg = t(user.id, 'welcome', name=user.first_name)
|
||||
msg = t(chat.id, 'welcome', name=user.first_name)
|
||||
|
||||
if user.id == ADMIN_ID:
|
||||
msg += t(user.id, 'welcome_admin')
|
||||
if user.id == ADMIN_ID and chat.type == "private":
|
||||
msg += t(chat.id, 'welcome_admin')
|
||||
await update.message.reply_text(msg, parse_mode='HTML', reply_markup=get_admin_keyboard(user.id))
|
||||
else:
|
||||
await update.message.reply_text(msg, parse_mode='HTML')
|
||||
@@ -250,19 +268,39 @@ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""Handle /help command."""
|
||||
user_id = update.effective_user.id
|
||||
msg = t(user_id, 'help_title') + t(user_id, 'help_commands')
|
||||
chat_id = update.effective_chat.id
|
||||
msg = t(chat_id, 'help_title') + t(chat_id, 'help_commands')
|
||||
|
||||
if user_id == ADMIN_ID:
|
||||
msg += t(user_id, 'help_admin')
|
||||
if user_id == ADMIN_ID and update.effective_chat.type == "private":
|
||||
msg += t(chat_id, 'help_admin')
|
||||
await update.message.reply_text(msg, parse_mode='HTML', reply_markup=get_admin_keyboard(user_id))
|
||||
else:
|
||||
await update.message.reply_text(msg, parse_mode='HTML')
|
||||
|
||||
async def stop_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""Handle /stop command (unsubscribe)."""
|
||||
user = update.effective_user
|
||||
chat = update.effective_chat
|
||||
|
||||
# Permission check: Whitelisted user OR Group Admin
|
||||
if not (is_whitelisted(user.id) or await is_group_admin(update, context)):
|
||||
await update.message.reply_text(t(chat.id, 'access_denied')) # Or specific "admin only" message
|
||||
return
|
||||
|
||||
redis_client.srem(KEY_SUBSCRIBERS, chat.id)
|
||||
await update.message.reply_text(t(chat.id, 'whitelist_disabled').replace(" whitelist", " notifications").replace("Білий список", "Сповіщення").replace("Белый список", "Уведомления") if chat.id else "Unsubscribed")
|
||||
|
||||
async def language_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""Handle /language command."""
|
||||
user_id = update.effective_user.id
|
||||
user = update.effective_user
|
||||
chat = update.effective_chat
|
||||
|
||||
# Permission check for groups
|
||||
if not (is_whitelisted(user.id) or await is_group_admin(update, context)):
|
||||
return
|
||||
|
||||
await update.message.reply_text(
|
||||
t(user_id, 'select_language'),
|
||||
t(chat.id, 'select_language'),
|
||||
parse_mode='HTML',
|
||||
reply_markup=get_language_keyboard()
|
||||
)
|
||||
@@ -544,6 +582,7 @@ async def check_webinars_job(context: ContextTypes.DEFAULT_TYPE):
|
||||
for sub_id in subscribers:
|
||||
try:
|
||||
# Build message in user's language
|
||||
# sub_id comes from redis set as string, convert to int for translation lookup
|
||||
webinar_items = "\n\n".join([
|
||||
t(int(sub_id), 'webinar_item', name=w['name'], url=w['url'])
|
||||
for w in new_webinars
|
||||
@@ -578,6 +617,7 @@ def main():
|
||||
|
||||
# Handlers
|
||||
app.add_handler(CommandHandler("start", start))
|
||||
app.add_handler(CommandHandler("stop", stop_command))
|
||||
app.add_handler(CommandHandler("help", help_command))
|
||||
app.add_handler(CommandHandler("language", language_command))
|
||||
app.add_handler(CommandHandler("adduser", add_user))
|
||||
|
||||
Reference in New Issue
Block a user