You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord游戏活动Bot功能开发求助:反应通知与逾期提醒实现

解决方案思路

你的需求需要结合**on_reaction_add事件和异步定时任务**实现,on_thread_create并非必需——核心触发点是用户添加💰反应的行为,以及后续的定时提醒逻辑。

1. 功能实现细节

(1)用户添加💰反应时发送通知

在on_reaction_add事件中区分两种场景:原消息作者添加💰触发线程创建,以及普通用户在线程内添加💰完成反馈。后者触发后直接在线程内发送确认通知即可。

(2)20小时后提醒未反应用户

当线程创建并发送完用户名单后,记录该名单的用户列表和对应消息ID,启动一个20小时的异步定时任务。到时间后,对比名单用户和已添加💰反应的用户,@未完成操作的用户提醒。

2. 修改后的完整代码示例

import discord
import re
import asyncio

# 初始化Bot,确保开启所需权限
intents = discord.Intents.default()
intents.message_content = True
intents.reactions = True
intents.members = True
client = discord.Client(intents=intents)

# 存储跟踪任务:键为线程内名单消息ID,值为(目标用户列表, 线程对象)
tracked_tasks = {}

@client.event
async def on_reaction_add(reaction, user):
    # 跳过Bot自身的反应
    if user.bot:
        return

    # 处理原逻辑:消息作者添加💰创建线程
    if user == reaction.message.author and str(reaction.emoji) == "💰":
        target_channel = client.get_channel(1245389918361092126)  # 💰-payments频道ID
        # 检查是否有☠️反应,无则移除💰
        skull_reaction = discord.utils.get(reaction.message.reactions, emoji='\U00002620\U0000fe0f')
        if not skull_reaction:
            await reaction.remove(user)
            return

        # 过滤消息开头的角色提及
        mention_regex = re.compile(r"^<@&(\d+)> ")
        filtered_content = mention_regex.sub("", reaction.message.content, 1)
        await target_channel.send(f"{filtered_content} by {reaction.message.author.mention}")

        # 收集👍反应的用户对象(而非仅mention,方便后续对比)
        target_users = []
        for msg_reaction in reaction.message.reactions:
            if msg_reaction.emoji == '👍':
                async for react_user in msg_reaction.users():
                    if react_user != client.user:
                        target_users.append(react_user)
        # 转换为mention字符串用于线程内发送
        user_mentions = ", ".join([u.mention for u in target_users])

        # 创建线程并发送用户名单
        thread_name = f"{filtered_content} by {reaction.message.author.display_name}"
        thread = await target_channel.create_thread(
            name=thread_name,
            auto_archive_duration=1440,
            type=discord.ChannelType.public_thread
        )
        # 保存名单消息对象,后续跟踪反应
        list_message = await thread.send(user_mentions)
        await list_message.add_reaction("💰")

        # 记录跟踪任务,启动定时提醒
        tracked_tasks[list_message.id] = (target_users, thread)
        asyncio.create_task(remind_unreacted(list_message.id))

    # 处理线程内用户添加💰的通知
    if str(reaction.emoji) == "💰" and reaction.message.id in tracked_tasks:
        await reaction.message.channel.send(f"{user.mention} 已收到你的完成反馈!")

async def remind_unreacted(message_id):
    # 等待20小时(换算为秒)
    await asyncio.sleep(20 * 3600)
    # 检查任务是否仍存在
    if message_id not in tracked_tasks:
        return
    target_users, thread = tracked_tasks.pop(message_id)

    # 获取线程内的名单消息
    try:
        list_message = await thread.fetch_message(message_id)
    except discord.NotFound:
        return

    # 收集已添加💰反应的用户
    reacted_users = []
    money_reaction = discord.utils.get(list_message.reactions, emoji='💰')
    if money_reaction:
        async for user in money_reaction.users():
            if not user.bot:
                reacted_users.append(user)

    # 筛选未反应用户并发送提醒
    unreacted_users = [u for u in target_users if u not in reacted_users]
    if unreacted_users:
        unreacted_mentions = ", ".join([u.mention for u in unreacted_users])
        await thread.send(f"提醒:{unreacted_mentions} 请尽快提交截图并添加💰反应确认!")

# 运行Bot
client.run("你的Bot令牌")

3. 关键注意事项

  • 权限配置:确保Bot开启了message_content、reactions、members这三个Intents,否则无法获取反应内容和用户信息。
  • 数据持久化:当前tracked_tasks是内存存储,Bot重启后数据会丢失。如果需要持久化,可以用JSON文件或轻量数据库(如SQLite)保存任务信息。
  • 时间调整:定时任务的等待时间20*3600可直接修改数值调整提醒间隔。

内容的提问来源于stack exchange,提问作者Rivendare

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 13:16:17