-
Notifications
You must be signed in to change notification settings - Fork 0
Storing user and chat related data
Sometimes you need to temporarily store some information about the current user and/or chat for later use. An example of this would be a survey bot that asks the user a series of questions one after another and saves them to your database when all answers are collected.
The telegram.ext framework provides a built-in solution for this common task. To understand how it works, let's take a look at a naïve solution using a global variable. In case you're in a hurry, you can also jump straight to the explanation.
The following complete example bot provides a very simple key/value storage. When you use the /put command to store a value, it returns an ID which you can use with the /get command to retrieve the stored value.
It uses a global dictionary named all_user_data that maps a user ID to a dict that represents the user specific storage.
from uuid import uuid4
from telegram.ext import Updater, CommandHandler
all_user_data = dict()
def put(bot, update):
"""Usage: /put value"""
# Generate ID and seperate value from command
key = str(uuid4())
value = update.message.text.partition(' ')[2]
user_id = update.message.from_user.id
# Create user dict if it doesn't exist
if user_id not in all_user_data:
all_user_data[user_id] = dict()
# Store value
user_data = all_user_data[user_id]
user_data[key] = value
update.message.reply_text(key)
def get(bot, update):
"""Usage: /get uuid"""
# Seperate ID from command
key = update.message.text.partition(' ')[2]
user_id = update.message.from_user.id
# Load value
try:
user_data = all_user_data[user_id]
value = user_data[key]
update.message.reply_text(value)
except KeyError:
update.message.reply_text('Not found')
if __name__ == '__main__':
updater = Updater('TOKEN')
dp = updater.dispatcher
dp.add_handler(CommandHandler('put', put))
dp.add_handler(CommandHandler('get', get))
updater.start_polling()
updater.idle()If you read the code carefully, you might have noticed that the code that gets the current user_data from all_user_data is repeated in both callbacks.
from uuid import uuid4
from telegram.ext import Updater, CommandHandler
def put(bot, update, user_data):
"""Usage: /put value"""
# Generate ID and seperate value from command
key = str(uuid4())
value = update.message.text.partition(' ')[2]
# Store value
user_data[key] = value
update.message.reply_text(key)
def get(bot, update, user_data):
"""Usage: /get uuid"""
# Seperate ID from command
key = update.message.text.partition(' ')[2]
# Load value
try:
value = user_data[key]
update.message.reply_text(value)
except KeyError:
update.message.reply_text('Not found')
if __name__ == '__main__':
updater = Updater('TOKEN')
dp = updater.dispatcher
dp.add_handler(CommandHandler(
'put', put, pass_user_data=True))
dp.add_handler(CommandHandler(
'get', get, pass_user_data=True))
updater.start_polling()
updater.idle()Note the following differences:
- The global variable
all_user_datawas removed - The repeated code to get the storage of the current user was removed
- The code to ensure that the storage exists was removed
- The parameter
user_datawas added to theputandgetfunctions - The parameter
pass_user_data=Trueis now passed to bothCommandHandler
By passing pass_user_data=True to any Handler constructor, you instruct the handler to pass a user-specific dict to the handler callback. The callback function must accept a parameter named user_data.
Every time the bot receives a message, the handler for that message checks if it was created with pass_user_data=True. If that is the case, it finds (or creates) the user_data of the user who sent the message and passes it to the callback function as a keyword argument. This dictionary is shared across all handlers of the bot.
chat_data works in the exact same way as user_data, except it is managed per chat instead of every user. Use the pass_chat_data=True parameter in the Handler constructor to have it passed to your callback.
-
Everything is stored in memory. This means that all
user_dataandchat_datais deleted when the bot process ends. - Empty
user_dataandchat_datadictionaries are automatically deleted from memory after the update is processed. - If not empty,
user_dataandchat_datawill be kept until the process ends. -
user_dataandchat_dataare different dictionaries even for private chats. - You can not assign a new value to
user_dataorchat_data. Instead ofuser_data = {}anduser_data = other_dict, useuser_data.clear()and/oruser_data.update(other_dict)respectively.
- Wiki of
python-telegram-bot© Copyright 2015-2025 – Licensed by Creative Commons
- Architecture Overview
- Builder Pattern for
Application - Types of Handlers
- Working with Files and Media
- Exceptions, Warnings and Logging
- Concurrency in PTB
- Advanced Filters
- Storing data
- Making your bot persistent
- Adding Defaults
- Job Queue
- Arbitrary
callback_data - Avoiding flood limits
- Webhooks
- Bot API Forward Compatiblity
- Frequently requested design patterns
- Code snippets
- Performance Optimizations
- Telegram Passport
- Bots built with PTB
- Automated Bot Tests