You learned how to secure your Telegram Bot app with simple authentication in the previous article. This article will teach you how to create an option list for your users to choose from. The simple question, ‘Which fruit do you like the most?’ will be asked, and three options @Apple, @Watermelon, and @Mango will be provided to the users. In the end, we will echo the answer to the user.
Step 1: After registration, the question ‘Which fruit do you like the most?’ with options will be shown to the user. The ReplyKeyboardMarkup function is used to create a button list for your users on Telegram. Modify the line from the previous article from
await message.answer('Added your user id to the whitelist.')
to
fruitOptions = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True)
fruitOptions.add('@Apple')
fruitOptions.add('@Watermelon')
fruitOptions.add('@Mango')
await message.answer('Added your user id to the whitelist. Which fruit do you like the most?', reply_markup = fruitOptions)
else: #authorized user
fruitOptions = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True)
fruitOptions.add('@Apple')
fruitOptions.add('@Watermelon')
fruitOptions.add('@Mango')
await message.answer('Which fruit do you like the most?', reply_markup = fruitOptions)
Step 2: The reason why an @ is added to each option is we would like to create another message handler with a filter. It will have higher priority than the default message handle. Any messages start with @ will go to that message handler. You may modify it to other function later if you want.
@dp.message_handler(regexp=r'^@')
async def question(message: types.Message):
Step 3: In the beginning of the @ message handler, you have to ensure the user is whitelisted. To begin with, similar to the previous article, you have to synchronize your whitelist user from Google Spreadsheet (user database) first. If it is not an authenticated user. Ask the user to enter a passcode.
########################################
########################################
########################################
#
# sync whitelisted_user from Google cloud
#
########################################
########################################
########################################
try:
spreadsheet = gs_client.open_by_key(docid)
export_file = spreadsheet.export(format=gspread.utils.ExportFormat.TSV)
f = open(userid_tsv_location, 'wb')
f.write(export_file)
f.close()
except:
traceback.print_exc()
uid = []
########################################
########################################
########################################
#
# Auth
#
########################################
########################################
########################################
try:
with open(userid_tsv_location, 'r', encoding="utf8") as f:
for line in f:
filtered_data = line.replace("\n","").split('\t')
uid.append(filtered_data[0])
except Exception:
print("No data!")
if(str(message.from_user.id) not in uid and message.text not in password):
await message.answer("Your user id is not in the whitelist. Please enter the passcode.")
Step 4: Continue the if case with a else case, if the user is whitelisted, reply the user message by echoing the choice.
else:
#do sth here
answer = message.text.replace('@','')
await message.answer("".join(["Wow! You like ",answer, " the most."]))
Execute the program and give it a try.
Congratulation! You learned how to add an option list and filter to a message handler. You may now try to create a simple Telegram bot automation program with the code provided.
The complete Python code
import logging
from aiogram import Bot, Dispatcher, executor, types
from aiogram.types import ReplyKeyboardMarkup
import gspread
from oauth2client.service_account import ServiceAccountCredentials
import traceback
import keyring
# Configure logging, initialize the bot and the dispatcher
logging.basicConfig(level=logging.INFO)
API_TOKEN = keyring.get_password("api", "telegram")
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)
@dp.message_handler(regexp=r'^@')
async def question(message: types.Message):
await message.answer('Handling your request. Please wait.')
########################################
########################################
########################################
#
# sync whitelisted_user from Google cloud
#
########################################
########################################
########################################
try:
spreadsheet = gs_client.open_by_key(docid)
export_file = spreadsheet.export(format=gspread.utils.ExportFormat.TSV)
f = open(userid_tsv_location, 'wb')
f.write(export_file)
f.close()
except:
traceback.print_exc()
uid = []
########################################
########################################
########################################
#
# Auth
#
########################################
########################################
########################################
try:
with open(userid_tsv_location, 'r', encoding="utf8") as f:
for line in f:
filtered_data = line.replace("\n","").split('\t')
uid.append(filtered_data[0])
except Exception:
print("No data!")
if(str(message.from_user.id) not in uid and message.text not in password):
await message.answer("Your user id is not in the whitelist. Please enter the passcode.")
else:
#do sth here
answer = message.text.replace('@','')
await message.answer("".join(["Wow! You like ",answer, " the most."]))
@dp.message_handler()
async def default(message: types.Message):
########################################
########################################
########################################
#
# sync whitelisted_user from Google cloud
#
########################################
########################################
########################################
try:
spreadsheet = gs_client.open_by_key(docid)
export_file = spreadsheet.export(format=gspread.utils.ExportFormat.TSV)
f = open(userid_tsv_location, 'wb')
f.write(export_file)
f.close()
except:
traceback.print_exc()
uid = []
########################################
########################################
########################################
#
# Auth
#
########################################
########################################
########################################
try:
with open(userid_tsv_location, 'r', encoding="utf8") as f:
for line in f:
filtered_data = line.replace("\n","").split('\t')
uid.append(filtered_data[0])
except Exception:
print("No data!")
if(str(message.from_user.id) not in uid and message.text not in password):
await message.answer("Your user id is not in the whitelist. Please enter the passcode.")
elif(str(message.from_user.id) not in uid and message.text in password): #add user to the whitelist
uid.append(message.from_user.id)
########################################
########################################
########################################
#
# write lastest whitelist to local file
#
########################################
########################################
########################################
count = 0
with open(userid_tsv_location, 'w', encoding="utf8") as f:
while count < len(uid):
data = "".join([str(uid[count]),'\n'])
f.write(data)
count+=1
print("".join(["Added ",str(uid)," to the whitelist!"]))
########################################
########################################
########################################
#
# sync whitelisted_user to Google Spreadsheet
#
########################################
########################################
########################################
content = open(userid_tsv_location, 'r', encoding="utf8").read()
gs_client.import_csv(docid, content)
print("Uploaded to cloud")
fruitOptions = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True)
fruitOptions.add('@Apple')
fruitOptions.add('@Watermelon')
fruitOptions.add('@Mango')
await message.answer('Added your user id to the whitelist. Which fruit do you like the most?', reply_markup = fruitOptions)
else: #authorized user
fruitOptions = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True)
fruitOptions.add('@Apple')
fruitOptions.add('@Watermelon')
fruitOptions.add('@Mango')
await message.answer('Which fruit do you like the most?', reply_markup = fruitOptions)
if __name__ == '__main__':
answers = [] # store the answers they have given
password = "silicon.blog"
scope = ["https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/drive"]
credentials = ServiceAccountCredentials.from_json_keyfile_name('genuine-amulet-386508-e126616283cf.json', scope)
gs_client = gspread.authorize(credentials)
docid = "1BVg-WgsDEjembne02KQ7F7U3EQLq33BG7uuybmFAZXs"
userid_tsv_location = 'whitelisted_user.tsv'
executor.start_polling(dp, skip_updates=True)