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

如何在discord.js v14中实现单成员单账号的账号分发列表?

实现Discord账号专属分配功能(discord.js v14)

核心逻辑

要实现账号仅分配一次的功能,需要维护两个核心数据集合:

  • 可用账号池:存储未被领取的账号
  • 已领取用户记录:存储已获取账号的用户ID,防止重复领取

当用户发送account命令时,按以下流程处理:

  1. 检查用户是否已领取过账号
  2. 检查是否还有可用账号
  3. 分配账号并发送私信
  4. 更新数据集合(持久化场景下同步保存到文件/数据库)

基础内存版实现

适合测试或临时使用,缺点是机器人重启后数据会丢失:

// 初始化可用账号池和已领取用户记录
let availableAccounts = [
  "user1:pass1",
  "user2:pass2",
  "user3:pass3"
];
let claimedUsers = new Set(); // Set查询效率优于数组

client.on("messageCreate", async (message) => {
  if (message.author.bot) return;

  if (message.content.toLowerCase() === "account") {
    // 检查是否已领取
    if (claimedUsers.has(message.author.id)) {
      return message.reply("你已经领取过账号,无法重复领取!");
    }

    // 检查账号池是否为空
    if (availableAccounts.length === 0) {
      return message.reply("抱歉,当前没有可用账号了!");
    }

    // 取出一个账号(这里顺序取第一个,也可以用随机索引取)
    const account = availableAccounts.shift();
    claimedUsers.add(message.author.id);

    try {
      // 发送私信
      await message.author.send(`你的账号:${account}`);
      await message.reply("账号已通过私信发送,请查收!");
    } catch (error) {
      // 私信发送失败(如用户关闭私信),回收账号并取消标记
      await message.reply("无法发送私信,请检查你的隐私设置!");
      availableAccounts.unshift(account);
      claimedUsers.delete(message.author.id);
    }
  }
});

持久化版本(JSON文件)

解决内存版数据丢失问题,将数据保存到本地JSON文件:

const fs = require('fs').promises;
const path = require('path');

// 数据存储文件路径
const dataFilePath = path.join(__dirname, 'accountData.json');

// 全局数据变量
let availableAccounts = [];
let claimedUsers = new Set();

// 加载本地数据
async function loadAccountData() {
  try {
    const rawData = await fs.readFile(dataFilePath, 'utf8');
    const parsedData = JSON.parse(rawData);
    availableAccounts = parsedData.availableAccounts || [];
    claimedUsers = new Set(parsedData.claimedUsers || []);
  } catch (err) {
    // 文件不存在时初始化默认数据
    availableAccounts = ["user1:pass1", "user2:pass2", "user3:pass3"];
    claimedUsers = new Set();
    await saveAccountData();
  }
}

// 保存数据到本地文件
async function saveAccountData() {
  const saveData = {
    availableAccounts: availableAccounts,
    claimedUsers: Array.from(claimedUsers) // Set需转为数组才能存入JSON
  };
  await fs.writeFile(dataFilePath, JSON.stringify(saveData, null, 2));
}

// 机器人启动时加载数据
client.on('ready', async () => {
  await loadAccountData();
  console.log('账号数据加载完成');
});

client.on("messageCreate", async (message) => {
  if (message.author.bot) return;

  if (message.content.toLowerCase() === "account") {
    if (claimedUsers.has(message.author.id)) {
      return message.reply("你已经领取过账号,无法重复领取!");
    }

    if (availableAccounts.length === 0) {
      return message.reply("抱歉,当前没有可用账号了!");
    }

    const account = availableAccounts.shift();
    claimedUsers.add(message.author.id);

    try {
      await message.author.send(`你的账号:${account}`);
      await message.reply("账号已通过私信发送,请查收!");
      // 分配成功后保存数据
      await saveAccountData();
    } catch (error) {
      await message.reply("无法发送私信,请检查你的隐私设置!");
      // 回收账号并取消标记
      availableAccounts.unshift(account);
      claimedUsers.delete(message.author.id);
    }
  }
});

额外优化建议

  • 随机分配账号:如果不想顺序发放,可用Math.floor(Math.random() * availableAccounts.length)生成随机索引,再用splice(index, 1)取出账号
  • 权限控制:可添加角色校验,比如if (!message.member.roles.cache.has('角色ID')) return message.reply("你没有领取权限!")
  • 数据库存储:如果用户量或账号量较大,建议用SQLite、MongoDB等数据库替代JSON文件,提升性能和稳定性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 09:47:41