0

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 :)

Aditya Yadav
  • 607
  • 1
  • 5
  • 15

2 Answers2

2

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?

Knugi
  • 93
  • 1
  • 8
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.

CallMeStag
  • 5,467
  • 1
  • 7
  • 22