Discord.py在特定时间后向成员发送直接消息

时间:2020-10-31 13:08:00

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

我希望在1周后向所有服务器成员发送没有“额外”角色的直接消息,并提醒您选择服务器上的其他角色。 这可能吗?

我已经在搜索教程,但是找不到解决方法。

也许“额外”角色可以是角色ID列表或其他内容。

1 个答案:

答案 0 :(得分:1)

是的,这是可能的。

很长一段时间内,您可能想使用某种持久性数据存储来跟踪事物,但是只要您的僵尸程序永远不会崩溃(或者如果您还可以的话),就可以在内存中合理地执行此操作并产生重设的后果)

为此使用的一种关键机制是tasks。您可以安排任务定期运行,以跟踪没有“额外”角色的人员。

请记住,任务计划应少于一天的时间。因此,在这种情况下,我们每3小时运行一次任务,但是该任务仅每7天发送一次消息。

针对单个公会的想法草图可能如下所示:


# the names of the roles to look for. You could also get these some other way.
EXTRA_ROLE_NAMES = {'foo', 'bar', 'baz'} 

import discord
from discord.ext import tasks


class MyBot(discord.Client):
    def __init__(self, *args, **kwargs):
        self._next_message_time = datetime.datetime.now()  # send reminder right away when the bot starts
        self.without_extra_role = set()  # set of members without an 'extra' role
        self._message_interval = datetime.timedelta(days=7)
        # if you don't want to send the message right away when the bot starts:
        # self._next_message_time = self._next_message_time + self._message_interval
        super().__init__(*args, **kwargs)
    @staticmethod
    def has_extra_role(member: discord.Member):
        for role in member.roles:
            if role.name in EXTRA_ROLE_NAMES:
                return True
        return False
    
    async def send_reminder(self, member):
        msg = "Don't forget to pick a role!"
        await member.send(msg)
    
    @tasks.loop(minutes=180)  # run this every 3 hours
    async def check_roles(self):
        guild = ... # get the discord guild object here
        # remove members that have picked a role
        to_remove = []
        for member in self.without_extra_role:
            if self.has_extra_role(member):
                to_remove.append(member)
        for member in to_remove:
            self.without_extra_role.remove(member)

        # Find members who still need to pick a role
        async for member in guild.fetch_members():
            if not self.has_extra_role(member):
                self.without_extra_role.add(member)

        # if it's time to send messages to everyone without a role...
        if datetime.datetime.now() >= self._next_message_time:
            # reset the next time to send the message
            self._next_message_time = datetime.datetime.now() + self._message_interval
            # send the messages
            for member in self.without_extra_role:
                # schedule reminder to be sent in the event loop
                self.loop.create_task(self.send_reminder(member))

在这里,self._next_message_time跟踪何时发送下一个提醒。理想情况下,如果您的漫游器掉线了,应该以某种方式坚持下去,以避免出现不一致的情况。

self.without_extra_role集可跟踪尚未选择额外角色的成员。该列表每3小时更新一次(根据任务时间表)。经过7天后,下次任务运行时,它将更新成员列表,并向仍在列表中的成员发送提醒。