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

实现Discord机器人向指定角色成员发私信并统计回复状态

Discord 私信机器人实现方案(Discord.js v14)

以下是基于最新Discord.js v14的完整实现代码,包含私信发送、回复统计和报告生成功能:

1. 核心代码实现

首先确保你已经安装了discord.js和@discordjs/builders:

npm install discord.js @discordjs/builders

完整机器人代码:

const { Client, GatewayIntentBits, EmbedBuilder } = require('discord.js');

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMembers,
    GatewayIntentBits.DirectMessages,
    GatewayIntentBits.MessageContent
  ]
});

// 存储统计数据:key为用户ID,value为状态(delivered/failed/responded)
const statusTracker = new Map();
// 存储当前任务的目标角色和消息内容
let currentTask = null;

client.on('ready', () => {
  console.log(`Logged in as ${client.user.tag}!`);
});

// 处理!send前缀命令
client.on('messageCreate', async (message) => {
  if (!message.content.startsWith('!send') || message.author.bot) return;

  // 解析命令参数:@角色 消息内容
  const args = message.content.slice(6).trim().split(/\s+/);
  const roleMention = args.shift();
  if (!roleMention) {
    return message.reply('格式错误:!send @角色 "消息内容"');
  }

  const roleId = roleMention.match(/\d+/)[0];
  const role = message.guild.roles.cache.get(roleId);
  if (!role) {
    return message.reply('找不到指定角色');
  }

  const messageContent = args.join(' ').replace(/^['"]|['"]$/g, '');
  if (!messageContent) {
    return message.reply('请输入要发送的消息内容');
  }

  // 初始化统计数据
  statusTracker.clear();
  currentTask = { roleId, messageContent };

  // 获取角色成员(排除机器人)
  const members = role.members.filter(m => !m.user.bot);
  const total = members.size;
  message.reply(`开始给${role.name}的${total}名成员发送私信...`);

  // 批量发送,避免触发速率限制
  for (const [userId, member] of members) {
    try {
      const dmChannel = await member.user.createDM();
      await dmChannel.send(messageContent);
      statusTracker.set(userId, 'delivered');
    } catch (err) {
      statusTracker.set(userId, 'failed');
    }
    // 每发送一条暂停1秒
    await new Promise(resolve => setTimeout(resolve, 1000));
  }

  message.reply('私信发送完成,可使用!report查看统计');
});

// 监听用户DM回复
client.on('messageCreate', async (message) => {
  if (!message.guild && !message.author.bot && currentTask) {
    const userId = message.author.id;
    if (statusTracker.has(userId) && statusTracker.get(userId) === 'delivered') {
      statusTracker.set(userId, 'responded');
    }
  }
});

// 生成统计报告命令
client.on('messageCreate', async (message) => {
  if (message.content !== '!report' || message.author.bot || !currentTask) return;

  const role = message.guild.roles.cache.get(currentTask.roleId);
  if (!role) return message.reply('当前任务的角色已不存在');

  const delivered = [];
  const responded = [];
  const notResponded = [];
  const failed = [];

  for (const [userId, status] of statusTracker) {
    const user = await client.users.fetch(userId).catch(() => null);
    const username = user ? `${user.tag}` : `未知用户(${userId})`;

    switch (status) {
      case 'delivered':
        delivered.push(username);
        notResponded.push(username);
        break;
      case 'responded':
        responded.push(username);
        break;
      case 'failed':
        failed.push(username);
        break;
    }
  }

  // 移除未回复列表中的已回复用户
  notResponded.forEach((user, index) => {
    if (responded.includes(user)) notResponded.splice(index, 1);
  });

  // 构建报告内容
  const report = [
    `${role.name}的${delivered.length + failed.length}名成员已收到私信;`,
    `${responded.length}名用户已回复(${responded.join(', ')});`,
    `${notResponded.length}名用户未回复(${notResponded.join(', ')});`,
    `${failed.length}条消息无法送达(${failed.join(', ')})。`
  ].join('\n');

  // 用Embed发送避免内容截断
  const embed = new EmbedBuilder()
    .setTitle('私信回复统计报告')
    .setDescription(report)
    .setColor('#0099ff');

  message.channel.send({ embeds: [embed] });
});

// 替换为你的机器人Token
client.login('YOUR_BOT_TOKEN');

2. 关键功能说明

  • 命令解析:支持!send @角色 "消息内容"格式,自动提取目标角色和消息文本
  • 速率控制:每发送一条私信暂停1秒,规避Discord的API请求限制
  • 状态追踪:用Map实时记录每个用户的私信状态(已送达/发送失败/已回复)
  • 报告生成:通过!report命令生成符合要求的统计报告,使用Embed格式避免内容过长被截断

3. 其他实现方式

  • Slash命令替代前缀命令:Discord官方推荐使用/send这类Slash命令,无需处理前缀解析,更符合平台规范
  • 持久化存储:用SQLite、MongoDB替代内存Map,可保留历史任务数据,重启机器人后不丢失
  • 批量发送优化:使用Promise.allSettled结合分批处理,提升发送效率的同时严格控制请求速率
  • 按钮式回复确认:在私信中添加Discord按钮组件,用户点击按钮即视为回复,无需发送消息,统计更精准

内容的提问来源于stack exchange,提问作者eNFThusiast.eth

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 15:39:20