The logic is the following:
- With the /start command the bot shows the Main Menu with buttons (each button represents a file the user wants to get access to);
- When any button is pressed, the conversation starts where the bot asks for a gmail address;
- The user sends their gmail address, the bot checks it, if the address format is correct then the bot grants the permission to view the file and posts the link to the chat.
I used these examples as my starting point:
- https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/conversationbot.py
- https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/conversationbot2.py
My code is this one:
from telegram import (
Bot,
Update,
InlineKeyboardMarkup,
InlineKeyboardButton,
)
from telegram.ext import (
Updater,
CommandHandler,
MessageHandler,
Filters,
CallbackContext,
CallbackQueryHandler,
ConversationHandler,
)
def startCommand(update: Update, context: CallbackContext):
keyboardMarkup = InlineKeyboardMarkup(
[[InlineKeyboardButton('Share File 1', callback_data='sharingFile1')]]
)
update.message.reply_text(f'Howdy, {update.effective_user.first_name}.\nThis is the Main Menu.',
reply_markup=keyboardMarkup)
def convGetGMailAddr(update: Update, context: CallbackContext):
update.message.reply_text('Waiting for your gmail address.\n\nSend /end and I\'ll stop waiting.')
return convEmailAddr
def convMismatch(update: Update, context: CallbackContext):
text = f"""Sorry, I don't understand this gmail address.
Please, send me your gmail address again.\n\nSend /end and I\'ll stop waiting.
"""
update.message.reply_text(text)
return convEmailAddr
def convGiveLink(update: Update, context: CallbackContext):
link = 'https://docs.google.com/spreadsheets/d/1ZP1xZ0WaH8w2yaQTSx99gafNZWawQabcdVW5DSngavQ'
update.message.reply_text(f'Thank you! Here\'s your link to the shared file:\n{link}')
return ConversationHandler.END
def convEnd(update: Update, context: CallbackContext):
update.message.reply_text('I\'ve stopped waiting.\n\nSend /start to go to the Main Menu.')
return ConversationHandler.END
def sharingFileHandler(update: Update, context: CallbackContext):
if update.callback_query.data == 'sharingFile1':
update.callback_query.edit_message_text(
update.effective_message.text,
reply_markup=InlineKeyboardMarkup([])
)
conv_sharing = ConversationHandler(
entry_points=[MessageHandler(Filters.regex('.*[File 1]*.*'), convGetGMailAddr)],
states={
convEmailAddr: [
MessageHandler(~Filters.regex('.*@gmail.com$') & ~Filters.command, convMismatch),
MessageHandler(Filters.regex('.*@gmail.com$'), convGiveLink),
],
},
fallbacks=[CommandHandler('end', convEnd)],
)
disp.add_handler(conv_sharing)
bot.send_message(update.effective_chat.id, 'I\'ll share the File 1 with you.')
bot_token = 'abcd1234'
bot = Bot(bot_token)
updater = Updater(bot_token, use_context=True)
convEmailAddr = ''
disp = updater.dispatcher
disp.add_handler(CommandHandler('start', startCommand))
disp.add_handler(CallbackQueryHandler(sharingFileHandler))
updater.start_polling(drop_pending_updates=True)
updater.idle()
The issue is that the bot doesn't read it's own reply in the function sharingFileHandler to start the conversation handler. The entry point of the conversation is posting the string "File 1" and when I send something like "asdklhasdlkh file 1 asdaskldha" then everything works fine.
Another question is is it possible for the bot to listen to email addresses only inside of the conversation? Right now the function convGetGMailAddr starts at any moment.
Update 1 (2021-10-20)
Based on the CallMeStag's answer I changed my code.
Deleted the function convGetGMailAddr and modified the function sharingFileHandler:
def sharingFileHandler(update: Update, context: CallbackContext):
if update.callback_query.data == 'sharingFile1':
update.callback_query.edit_message_text(
update.effective_message.text,
reply_markup=InlineKeyboardMarkup([])
)
text = f"""I\'ll share the File 1 with you to your Google account.
Please, send me your gmail address.\n\nSend /end and I\'ll stop waiting."""
bot.send_message(update.effective_chat.id, text)
return convEmailAddr
bot_token = '1234abcd'
bot = Bot(bot_token)
updater = Updater(bot_token, use_context=True)
convEmailAddr = ''
disp = updater.dispatcher
disp.add_handler(CommandHandler('start', startCommand))
conv_sharing = ConversationHandler(
entry_points=[CallbackQueryHandler(sharingFileHandler)],
states={
convEmailAddr: [
MessageHandler(~Filters.regex('.*@gmail.com$') & ~Filters.command, convMismatch),
MessageHandler(Filters.regex('.*@gmail.com$'), convGiveLink),
],
},
fallbacks=[CommandHandler('end', convEnd)],
)
disp.add_handler(conv_sharing)
updater.start_polling(drop_pending_updates=True)
updater.idle()
Now my bot does exactly what I want and it stopped doing what I wanted it to stop doing.
Thank you, CallMeStag!