【问题标题】:Background Loop with Reactions Discord.Py带有反应 Discord.Py 的背景循环
【发布时间】:2019-02-16 15:23:12
【问题描述】:

我有一个后台循环,每隔 X 分钟会吐出一个表情符号,并附有一个反应。我希望当有人按下消息的反应时,它会删除该消息,然后发送另一条消息说“消息作者已经抓住了战利品”,然后将金额添加到现金 json 文件中。

现在,我的代码正在使后台循环工作,但我不确定如何获取关于后台循环的 message.author.id,以便我可以在 on_reaction_add 中引用它。当前代码使机器人在吐出后台循环时做出反应,然后在 on_reaction_add 中再次做出反应。我试图让它等待用户使用相同的表情符号而不是机器人对后台循环消息做出反应。

client = discord.Client()
emoji_msg_grab = {}


try:
    with open("cash.json") as fp:
        cash = json.load(fp)
except Exception:
    cash = {}

def save_cash():
    with open("cash.json", "w+") as fp:
        json.dump(cash, fp, sort_keys=True, indent=4)

def add_dollars(user: discord.User, dollars: int):
    id = user.id
    if id not in cash:
        cash[id] = {}
    cash[id]["dollars"] = cash[id].get("dollars", 0) + dollars
    print("{} now has {} dollars".format(user.name, cash[id]["dollars"]))
    save_cash()


async def background_loop():
    await client.wait_until_ready()
    while not client.is_closed:
        channel = client.get_channel("479919577279758340")
        emojigrab = '????'
        emojimsgid = await client.send_message(channel, emojigrab)
        await client.add_reaction(emojimsgid, "????")
        user_id = emojimsgid.author.id
        emoji_msg_grab[user_id] = {"emoji_msg_id": emojimsgid.id, "emoji_user_id": user_id}
        await asyncio.sleep(600)

@client.event
async def on_reaction_add(reaction, user):
    msgid = reaction.message.id
    chat = reaction.message.channel

    if reaction.emoji == "????" and msgid == emoji_msg_grab[user.id]["emoji_msg_id"] and user.id == emoji_msg_grab[user.id]["emoji_user_id"]:
        emoji_msg_grab[user.id]["emoji_msg_id"] = None
        await client.send_message(chat, "{} has grabbed the loot!".format(user.mention))
        await client.delete_message(reaction.message)
        add_dollars(user, 250)

client.loop.create_task(background_loop())

【问题讨论】:

    标签: python python-3.x discord discord.py


    【解决方案1】:

    我会使用Client.wait_for_reaction 而不是on_reaction_add

    async def background_loop():
        await client.wait_until_ready()
        channel = client.get_channel("479919577279758340")
        while not client.is_closed:
            emojigrab = '?'
            emojimsg = await client.send_message(channel, emojigrab)
            await client.add_reaction(emojimsg, "?")
            res = await client.wait_for_reaction(emoji="?", message=emojimsg, timeout=600, 
                                                 check=lambda reaction, user: user != client.user)
            if res:  # not None
                await client.delete_message(emojimsg)
                await client.send_message(channel, "{} has grabbed the loot!".format(res.user.mention))
                await asyncio.sleep(1)
                add_dollars(res.user, 250)
    

    【讨论】:

    • 谢谢帕特里克。这就说得通了。我相信我在机器人对消息本身做出反应时遇到了问题。我对 on_message 进行了检查,但是当我尝试在 if int(client.user.id) == 478423970572664853: return else: res = await client.wait_for_reaction 等后台循环中添加检查时,它不会通过我的检查并执行“res”。
    • client.user 将永远是你的机器人,所以它的 id 不太可能改变。您可能打算检查if client.user == message.author
    • 嘿帕特里克,是的,我也试过了,但得到了错误undefined variable 'message'。我不确定如何在on_message 之外获取 message.author
    • @hardestchat 我有点困惑。你会在后台循环中检查什么消息?
    • 我试图检查emojimsg,以确保client.user(机器人)无法在后台循环中对其自己的消息做出反应。现在,当机器人吐出?时,它会让后台循环认为有人对它做出了反应,所以它会删除消息,发送消息,并奖励机器人add_dollars
    猜你喜欢
    • 2021-03-22
    • 1970-01-01
    • 2016-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多