-
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_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
- Both the
putandgetfunctions 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_dataandchat_datais deleted when the bot process ends. If you don't want this, have a look at the persistent page. - 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