skip to Main Content

Here’s my code:

from telegram import *
from telegram.ext import *
import telegram, telegram.ext

u = Updater('TOKEN', use_context=True)
j=u.job_queue

def set(update: Update, context: CallbackContext):
    user_says=' '.join(context.args)
    user_says=user_says.split(' ')
    global item, chat_id
    item=user_says[1:]
    chat_id=update.effective_chat.id
    j.run_once(callback, int(user_says[0]))

def callback(context: telegram.ext.CallbackContext):
    context.bot.send_message(chat_id=chat_id, text=f'Great you won {item}')

if __name__ == '__main__':
    dp = u.dispatcher
    dp.add_handler(CommandHandler('set', set))
    u.start_polling()
    u.idle()

So the problem is if someone start the timer and in the mean time when the timer is running someone else (or the same person) start different timer the value of item get replaced with the newest one, it will display wrong item value for all the timers which are already running in that time (except for the latest one) how can I store items and show them with their corresponding timer’s callback

Hope you understood my question 🙂

2

Answers


  1. You may simply use a dict to store the items and the chat_id with an UUID as a key, then, pass the UUID to the callback function and retrieve the items from the dict.

    from uuid import uuid4
    items = {}
    
    def set(update: Update, context: CallbackContext):
        user_says=' '.join(context.args)
        user_says=user_says.split(' ')
        chat_id=update.effective_chat.id
        uid = uuid4()
        items[uid] = {"id": chat_id, "item": user_says[1:]}
        j.run_once(callback, int(user_says[0]), context=uid)
    
    def callback(context: telegram.ext.CallbackContext):
        uid = context.job.context
        chat_id = items[uid]["id"]
        context.bot.send_message(chat_id=chat_id, text=f'Great you won {items[uid]["item"]}')
        del items[uid]
    

    Read more about multi-users handling in How to manage more users in a telegram bot?

    Login or Signup to reply.
  2. IMHO Knugis answer is unnecessarily complicated. Instead of storing some data in a global dict and then passing the key to context, you might as well just pass the data directly, e.g. as tuple:

    j.run_once(callback, int(user_says[0]), context=(chat_id, user_says[1:]))
    

    and then

    def callback(context: telegram.ext.CallbackContext):
        uid, user_says = context.job.context
        ...
    

    On a somewhat related note I’d like to point out that PTB already comes with a built-in mechanism to store user/chat-related data. See this wiki page for details.


    Disclaimer: I’m currently the maintainer of python-telegram-bot.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search