From 5a17eea56955676c75f3cf33b78d4dc4c89460ff Mon Sep 17 00:00:00 2001 From: kaungzinye Date: Sat, 6 Sep 2025 19:29:39 +0200 Subject: [PATCH 1/3] fix: add URL validation to prevent BUTTON_TYPE_INVALID error - Add urlparse import for URL validation - Validate generated URLs before returning them - Add fallback URL generation if validation fails - Prevent malformed URLs from causing Telegram API errors - Fix BUTTON_TYPE_INVALID error in web app buttons File modified: - bot/utils/web_app.py: Added URL validation and error handling --- bot/utils/web_app.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/bot/utils/web_app.py b/bot/utils/web_app.py index 7061553..6fa6c0e 100644 --- a/bot/utils/web_app.py +++ b/bot/utils/web_app.py @@ -1,5 +1,5 @@ import os -from urllib.parse import urlencode +from urllib.parse import urlencode, urlparse def create_web_app_url(path: str, web_app_number: int = 1, **params) -> str: """ @@ -31,4 +31,15 @@ def create_web_app_url(path: str, web_app_number: int = 1, **params) -> str: if query_string: url = f"{url}?{query_string}" + # Validate the URL format + try: + parsed = urlparse(url) + if not parsed.scheme or not parsed.netloc: + raise ValueError("Invalid URL format") + except Exception as e: + # Fallback to a simple URL if validation fails + url = f"https://meet-when-ah.vercel.app/{path}" + if query_string: + url = f"{url}?{query_string}" + return url \ No newline at end of file From bd1f418b2708a80cd8c25295ad3486f4acd40ca2 Mon Sep 17 00:00:00 2001 From: kaungzinye Date: Sat, 6 Sep 2025 19:32:22 +0200 Subject: [PATCH 2/3] fix: use URL button instead of WebApp button in group chats - Fix BUTTON_TYPE_INVALID error in group chats by using regular URL buttons - Keep WebApp buttons for private chats where they work properly - Group chats now use url parameter instead of web_app parameter - Maintains functionality while fixing Telegram API compatibility issue The issue was that WebApp buttons have restrictions in group chats, causing BUTTON_TYPE_INVALID errors. This fix uses different button types based on chat type for better compatibility. --- bot/telegram/handlers/welcome_handlers.py | 33 ++++++++++++++++------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/bot/telegram/handlers/welcome_handlers.py b/bot/telegram/handlers/welcome_handlers.py index 45cd4fb..b123d5f 100644 --- a/bot/telegram/handlers/welcome_handlers.py +++ b/bot/telegram/handlers/welcome_handlers.py @@ -70,22 +70,35 @@ def help_command(message): print(f"📱 Generated dashboard WebApp URL with token: {web_app_url}") markup = types.InlineKeyboardMarkup() - web_app_info = types.WebAppInfo(url=web_app_url) - dashboard_btn = types.InlineKeyboardButton( - text="Open Dashboard", - web_app=web_app_info - ) - markup.add(dashboard_btn) - - # Log the button creation - logger.info(f"🔘 Created WebApp button with URL: {web_app_url}") - print(f"🔘 Created WebApp button with URL: {web_app_url}") if message.chat.type == 'private': + # Use WebApp button for private chats + web_app_info = types.WebAppInfo(url=web_app_url) + dashboard_btn = types.InlineKeyboardButton( + text="Open Dashboard", + web_app=web_app_info + ) + markup.add(dashboard_btn) + + # Log the button creation + logger.info(f"🔘 Created WebApp button with URL: {web_app_url}") + print(f"🔘 Created WebApp button with URL: {web_app_url}") + bot.reply_to(message, HELP_MESSAGE, reply_markup=markup) logger.info(f"📤 Sent help message to private chat for user {message.from_user.id}") print(f"📤 Sent help message to private chat for user {message.from_user.id}") else: + # In group chat, use regular URL button instead of WebApp button + dashboard_btn = types.InlineKeyboardButton( + text="Open Dashboard", + url=web_app_url + ) + markup.add(dashboard_btn) + + # Log the button creation + logger.info(f"🔘 Created URL button with URL: {web_app_url}") + print(f"🔘 Created URL button with URL: {web_app_url}") + # In group chat, mention the user who requested help help_text = f"@{message.from_user.username or message.from_user.first_name}, here's how to use the bot:\n\n{HELP_MESSAGE}" bot.send_message(message.chat.id, help_text, reply_markup=markup) From d4cf8c1453d4a8c87eb69b50f75428669ec9e23e Mon Sep 17 00:00:00 2001 From: kaungzinye Date: Sat, 6 Sep 2025 19:59:12 +0200 Subject: [PATCH 3/3] Update /help command to not reply directly in group chats - In private chats: still replies directly to user's message - In group chats: sends help message without replying to user's message - Maintains dashboard button functionality for both chat types --- bot/telegram/handlers/welcome_handlers.py | 72 ++++------------------- 1 file changed, 11 insertions(+), 61 deletions(-) diff --git a/bot/telegram/handlers/welcome_handlers.py b/bot/telegram/handlers/welcome_handlers.py index b123d5f..c1e6330 100644 --- a/bot/telegram/handlers/welcome_handlers.py +++ b/bot/telegram/handlers/welcome_handlers.py @@ -18,7 +18,6 @@ # Import from utils from utils.message_templates import WELCOME_MESSAGE, HELP_MESSAGE -from utils.web_app import create_web_app_url # Import from other from urllib.parse import urlencode @@ -31,76 +30,27 @@ def register_welcome_handlers(bot): @bot.message_handler(commands=['help']) def help_command(message): - # Enhanced logging for help command - user_info = { - 'user_id': message.from_user.id, - 'username': message.from_user.username, - 'first_name': message.from_user.first_name, - 'chat_type': message.chat.type, - 'chat_id': message.chat.id - } - - logger.info(f"🚀 Help command triggered by user: {user_info}") - print(f"🚀 Help command triggered by user: {user_info}") - - # Generate share token for dashboard access (similar to /share command) + # Generate share token for dashboard access chat_id = message.chat.id thread_id = getattr(message, "message_thread_id", None) user_id = message.from_user.id - - # We'll use a placeholder message_id since this is for dashboard access, not message editing placeholder_message_id = 0 token = put_ctx(user_id, chat_id, placeholder_message_id, thread_id) - # Log the generated token - logger.info(f"🔑 Generated share token for dashboard: {token}") - print(f"🔑 Generated share token for dashboard: {token}") - logger.info(f"🔑 Token context - user_id: {user_id}, chat_id: {chat_id}, thread_id: {thread_id}") - print(f"🔑 Token context - user_id: {user_id}, chat_id: {chat_id}, thread_id: {thread_id}") + # Create dashboard button + markup = types.InlineKeyboardMarkup() + params = f"dashboard={token}" + mini_app_url = f"https://t.me/{bot.get_me().username}/meetwhenah?startapp={params}" - # Create WebApp URL for dashboard with token - web_app_url = create_web_app_url( - path='/dashboard', - token=token + dashboard_btn = types.InlineKeyboardButton( + text="Open Dashboard", + url=mini_app_url ) - - # Log the generated URL for debugging - logger.info(f"📱 Generated dashboard WebApp URL with token: {web_app_url}") - print(f"📱 Generated dashboard WebApp URL with token: {web_app_url}") - - markup = types.InlineKeyboardMarkup() + markup.add(dashboard_btn) if message.chat.type == 'private': - # Use WebApp button for private chats - web_app_info = types.WebAppInfo(url=web_app_url) - dashboard_btn = types.InlineKeyboardButton( - text="Open Dashboard", - web_app=web_app_info - ) - markup.add(dashboard_btn) - - # Log the button creation - logger.info(f"🔘 Created WebApp button with URL: {web_app_url}") - print(f"🔘 Created WebApp button with URL: {web_app_url}") - bot.reply_to(message, HELP_MESSAGE, reply_markup=markup) - logger.info(f"📤 Sent help message to private chat for user {message.from_user.id}") - print(f"📤 Sent help message to private chat for user {message.from_user.id}") else: - # In group chat, use regular URL button instead of WebApp button - dashboard_btn = types.InlineKeyboardButton( - text="Open Dashboard", - url=web_app_url - ) - markup.add(dashboard_btn) - - # Log the button creation - logger.info(f"🔘 Created URL button with URL: {web_app_url}") - print(f"🔘 Created URL button with URL: {web_app_url}") - - # In group chat, mention the user who requested help - help_text = f"@{message.from_user.username or message.from_user.first_name}, here's how to use the bot:\n\n{HELP_MESSAGE}" - bot.send_message(message.chat.id, help_text, reply_markup=markup) - logger.info(f"📤 Sent help message to group chat {message.chat.id} for user {message.from_user.id}") - print(f"📤 Sent help message to group chat {message.chat.id} for user {message.from_user.id}") \ No newline at end of file + # In group chat, send help message without replying to the user's message + bot.send_message(message.chat.id, HELP_MESSAGE, reply_markup=markup) \ No newline at end of file