-
Notifications
You must be signed in to change notification settings - Fork 0
Storing user and chat related data
This wiki page has been updated to work with the beta version 12 of the python-telegram-bot library.
This version has proven to be generally stable enough for most usecases. See the v12 transistion guide for more info.
If you're still using version 11.1.0, please see the old version of this wiki page.
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