I need help with a telegram bot workflow using python-telegram-bot. Here’s what I want to achieve:
- User X sends a command to the bot
- Bot stores this in database and tells X it’s waiting for approval from User Y
- Bot contacts User Y with
Approve and Decline inline buttons
- When Y clicks a button, bot records the choice and notifies both users
I got the first part working with ConversationHandler for User X’s request. The problem is starting a second conversation with User Y properly.
I tried using the Bot object to message Y directly, but I can’t figure out how to catch Y’s button response. Both users’ chat IDs are stored in my database.
def handle_user_request(update, context):
# Save request from user X
save_request_to_db(update.message.from_user.id, request_data)
# Reply to X
update.message.reply_text('Request submitted, waiting for approval')
# Send to Y - but how to handle response?
keyboard = [[InlineKeyboardButton('Approve', callback_data='approve'),
InlineKeyboardButton('Decline', callback_data='decline')]]
reply_markup = InlineKeyboardMarkup(keyboard)
context.bot.send_message(chat_id=approver_id,
text='New request needs approval',
reply_markup=reply_markup)
return ConversationHandler.END
What’s the best approach for this multi-user conversation pattern?
The issue you’re facing is quite common when building multi-user approval workflows. The key insight is that CallbackQueryHandlers work globally across all users, not just within a specific conversation. You need to embed context into your callback_data to differentiate between different approval requests. Modify your callback_data to include the request ID or some unique identifier. Instead of just ‘approve’, use something like ‘approve_123’ where 123 is your request ID from the database. Then create a separate CallbackQueryHandler that parses this data and determines which request is being acted upon. In your callback handler, extract the request details from your database using the ID, update the approval status, then send notifications to both users. This approach keeps everything clean without needing nested conversations.
you dont need another conversationhandler for this. just add a callbackqueryhandler to catch the button presses from user Y. store the request id in callback_data so u know which request they’re responding to when they click approve/decline
I ran into this exact scenario when building an expense approval bot for our team. What worked best for me was using a hybrid approach - keep your ConversationHandler for the initial request flow, but handle the approval responses through a dedicated CallbackQueryHandler that operates independently. The trick is maintaining state in your database rather than relying on conversation state. When User X submits their request, generate a unique request_id and store all relevant data in your database with status ‘pending’. Include this request_id in your callback_data like ‘approve_{request_id}’ and ‘decline_{request_id}’. Your CallbackQueryHandler can then parse the callback_data, extract the request_id, look up the request details from the database, and update the status accordingly. This way you avoid the complexity of trying to manage multiple simultaneous conversations while still maintaining full control over the workflow. The database becomes your single source of truth for request states.