Having issues with processing user input in private chat #4656
-
|
Hello everyone, I'm practicing in writing the bot for telegram group that functions on the following "algorythm'/conditions:
I strugle with processing user input from the created private chat. My "bot" creates the private conversation with newcomer at join request, sends to the candidate the message, but doesn't accept the responce. The logging doesn't capture the fact that user is responding. The currenc code is: from os import getenv
from enum import Enum
import logging
from telegram import Update, Bot
from telegram.ext import ApplicationBuilder, CommandHandler, ChatJoinRequestHandler, ConversationHandler, MessageHandler
from telegram.ext import Updater, ContextTypes, filters
passphrase=r"I want to join the channel"
TOKEN = getenv('TELEGRAM_BOT_TOKEN')
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
class States(Enum):
WAITING_FOR_VERIFICATION = 1
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
await update.message.reply_text(f'I am the bot, type me something!')
# Processing user's join request
async def join_request(update: Update, context: ContextTypes.DEFAULT_TYPE):
logging.info(f"Captured attempt of user to join the group.\n\tUser : {update.effective_user.id}\n\tGroup: {update.effective_chat.id}")
# sending user a private message
await context.bot.send_message(
chat_id=update.effective_user.id,text=
f"Dummy captcha. Just respond '{passphrase}' (without brackets) to this message"
)
# Store chat join request details in context for later use
context.user_data['join_request_chat_id'] = update.effective_chat.id
context.user_data['join_request_user_id'] = update.effective_user.id
return States.WAITING_FOR_VERIFICATION
async def verify_user_response(update: Update, context: ContextTypes.DEFAULT_TYPE):
logging.info(f"Verification state triggered")
logging.info(f"Update details: {update}")
logging.info(f"Context user data: {context.user_data}")
user_response = update.message.text
logging.info(f"Captured responce of user : {update.effective_user.id}\n\tResponce: {user_response}")
if user_response == passphrase:
# Approve join request using stored details
await context.bot.approve_chat_join_request(
chat_id=context.user_data['join_request_chat_id'],
user_id=context.user_data['join_request_user_id']
)
await update.message.reply_text("Verification successful! You'll be forwarded to group now.")
logging.info(f"User passed the verification and added to group:\n\t {update.effective_user.id}")
return ConversationHandler.END
else:
# Decline join request
await context.bot.decline_chat_join_request(
chat_id=context.user_data['join_request_chat_id'],
user_id=context.user_data['join_request_user_id']
)
await update.message.reply_text("Verification failed. You cannot join the group.")
logging.info(f"User FAILED the verification and NOT added to group:\n\t {update.effective_user.id}")
return ConversationHandler.END
if __name__ == '__main__':
default_bot = Bot(TOKEN)
logging.info("Succesfully retrieved token")
app = ApplicationBuilder().bot(default_bot).build()
logging.info("Succesfully created application")
# Create a handler for private mesage to user
conv_handler = ConversationHandler(
entry_points=[ChatJoinRequestHandler(join_request)],
states={
States.WAITING_FOR_VERIFICATION: [
# Only plain text, no edited messages, no commands in privat conversation
MessageHandler( filters.TEXT & ~filters.COMMAND & ~filters.UpdateType.EDITED_MESSAGE, verify_user_response)
]
},
fallbacks=[]
)
# Commands
app.add_handler(CommandHandler("start", start))
# Conversations
app.add_handler(conv_handler)
# Finally run!
app.run_polling(allowed_updates=Update.ALL_TYPES)Please, advice. Used versions:
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
|
The conversation handler is bound to the group chat, since per_chat is True. I would personally probably make a conversation handler with a message handler with a user filter to which I add a user id when I expect a captcha response (and remove when the conversation flow is done). If you want to be able to debug these issues yourself, set the logging level to debug to see where the update is handled (or in this case, isn't) |
Beta Was this translation helpful? Give feedback.
-
|
The Problem: Context Mismatch The Request (Entry Point): The Join Request happens in the Group. Context: (Group_ID, User_ID) The bot saves the state WAITING_FOR_VERIFICATION under this key. The Response: The user replies in a Private Chat (DM). Context: (Private_Chat_ID, User_ID) The bot looks for a state under this new key, finds nothing, and ignores the message. The Solution Step 1: Modify ConversationHandler Step 2: Add a Filter (Safety) Fixed Code Python if name == 'main':
Python context.user_data['join_request_chat_id'] = update.effective_chat.id |
Beta Was this translation helpful? Give feedback.
The Problem: Context Mismatch
In python-telegram-bot, a ConversationHandler tracks the state of a conversation based on a "key". By default, this key is a combination of (Chat ID + User ID).
The Request (Entry Point): The Join Request happens in the Group.
Context: (Group_ID, User_ID)
The bot saves the state WAITING_FOR_VERIFICATION under this key.
The Response: The user replies in a Private Chat (DM).
Context: (Private_Chat_ID, User_ID)
The bot looks for a state under this new key, finds nothing, and ignores the message.
The Solution
You must tell the ConversationHandler to ignore the "Chat ID" and track the state based only on the User ID. This allows the conversation to start in the Gr…