-
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(update, context):
"""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(update, context):
"""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', use_context=True)
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(update, context):
"""Usage: /put value"""
# Generate ID and seperate value from command
key = str(uuid4())
value = update.message.text.partition(' ')[2]
# Store value
context.user_data[key] = value
update.message.reply_text(key)
def get(update, context):
"""Usage: /get uuid"""
# Seperate ID from command
key = update.message.text.partition(' ')[2]
# Load value
try:
value = context.user_data[key]
update.message.reply_text(value)
except KeyError:
update.message.reply_text('Not found')
if __name__ == '__main__':
updater = Updater('TOKEN', use_context=True)
dp = updater.dispatcher
dp.add_handler(CommandHandler('put', put))
dp.add_handler(CommandHandler('get', get))
updater.start_polling()
updater.idle()
Note the following differences:
- The global variable
all_user_data
was removed - The repeated code to get the storage of the current user was removed
- The code to ensure that the storage exists was removed
- Both the
put
andget
functions use context.user_data
By using context.user_data
in any Handler
callback, you have access to a user-specific dict
.
Every time the bot receives a message, the handler for that message finds (or creates) the user_data
of the user who sent the message. 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 context.chat_data
to get access to this dict.
-
Everything is stored in memory. This means that all
user_data
andchat_data
is deleted when the bot process ends. If you don't want this, have a look at the persistent page. - Empty
user_data
andchat_data
dictionaries are automatically deleted from memory after the update is processed. - If not empty,
user_data
andchat_data
will be kept until the process ends. -
user_data
andchat_data
are different dictionaries even for private chats. - You can not assign a new value to
user_data
orchat_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