Discord.py 特定时间后向成员发送直接消息
Discord.py send members a direct message after certain time
我想在 1 周后向没有“额外”角色的所有服务器成员发送一条直接消息,提醒他们在我的服务器上选择额外角色。 这可能吗?
我已经搜索了教程,但找不到方法。
也许“额外”角色可以是角色 ID 列表或其他东西。
是的,这是可能的。
在很长一段时间内,您可能希望使用某种持久性数据存储来跟踪事物,但您可以合理地这样做 in-memory 只要您的机器人永远不会宕机(或者如果您可以接受重置的后果)
为此使用的一个关键机制是 tasks。您可以定期 运行 安排一项任务,以跟踪没有 'extra' 角色的人。
请记住,任务安排应少于一天的时间。因此,在这种情况下,我们 运行 每 ~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 天后,下一次任务 运行s 时,将更新成员列表并向仍在列表中的成员发送提醒。
我想在 1 周后向没有“额外”角色的所有服务器成员发送一条直接消息,提醒他们在我的服务器上选择额外角色。 这可能吗?
我已经搜索了教程,但找不到方法。
也许“额外”角色可以是角色 ID 列表或其他东西。
是的,这是可能的。
在很长一段时间内,您可能希望使用某种持久性数据存储来跟踪事物,但您可以合理地这样做 in-memory 只要您的机器人永远不会宕机(或者如果您可以接受重置的后果)
为此使用的一个关键机制是 tasks。您可以定期 运行 安排一项任务,以跟踪没有 'extra' 角色的人。
请记住,任务安排应少于一天的时间。因此,在这种情况下,我们 运行 每 ~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 天后,下一次任务 运行s 时,将更新成员列表并向仍在列表中的成员发送提醒。