如何在discord.py中实现向服务器所有用户发送DM的命令
Discord 服务器全员DM命令实现方案
原有代码已知问题
你之前提交的代码存在以下可优化/错误点:
- 没有对成员列表做过滤,会向服务器内的机器人账号也发送DM,浪费请求资源
user.send()调用时使用了错误的参数nick,实际传递消息内容应使用content参数- 缺少请求间隔控制,短时间内大量发送DM会触发Discord速率限制,甚至导致机器人账号被封禁
- 命令参数仅接收单个字符串,无法发送包含空格的长消息
前置配置要求
- 前往Discord开发者平台的机器人管理页,开启
Server Members Intent权限,否则无法获取完整的服务器成员列表 - 注意:全员DM属于高风险操作,Discord官方对批量私信行为管控极严,仅建议在小型私人服务器使用,频繁使用大概率会触发账号封禁
可用实现代码
import asyncio from discord.ext import commands # 可自定义配置项 timeout = 30 # 确认等待超时时间,单位秒 waitmsg = "正在开始发送全员DM,请耐心等待..." donemsg = "全员DM已发送完成,部分用户可能因隐私设置未收到消息" no_msg = "操作已取消" timeout_msg = "操作超时已取消" send_interval = 1 # 每条DM发送间隔,单位秒,避免触发速率限制 class DMCog(commands.Cog): def __init__(self, bot): self.bot = bot @commands.command(aliases=["senddm", "alldm"]) async def all_dm(self, ctx, *, message): # 仅允许服务器管理员使用该命令,防止滥用 if not ctx.author.guild_permissions.administrator: await ctx.send("你没有权限使用该命令") return await ctx.send(f"是否要向 `{ctx.guild.name}` 的所有成员发送DM:`{message}`?[y/n]") def check_data(msg): return msg.author == ctx.author and msg.channel == ctx.channel try: msg = await self.bot.wait_for('message', check=check_data, timeout=timeout) if msg.content.lower() == "y": await ctx.send(waitmsg) send_count = 0 fail_count = 0 # 遍历成员,过滤掉机器人账号 for user in ctx.guild.members: if not user.bot: try: await user.send(content=message) send_count += 1 # 发送间隔控制 await asyncio.sleep(send_interval) except Exception: fail_count += 1 continue await ctx.send(f"{donemsg}\n成功发送:{send_count} 人\n发送失败(用户关闭了陌生人DM):{fail_count} 人") return elif msg.content.lower() == "n": await ctx.send(no_msg) return else: await ctx.send("无效输入,操作已取消") return except asyncio.TimeoutError: await ctx.send(timeout_msg) return async def setup(bot): await bot.add_cog(DMCog(bot))
使用说明
- 命令使用格式:
!alldm 你要发送的消息内容,支持发送带空格的长消息 - 增加了管理员权限校验,只有服务器管理员可以调用该命令
- 增加了发送成功/失败统计,可直观看到送达情况
- 可根据服务器大小调整
send_interval参数,服务器人数大于100人建议调大到2秒以上
内容的提问来源于stack exchange,提问作者Vodka
相关产品推荐
相关产品推荐

