【问题标题】:Discord.js Sorting through all text channels on a serverDiscord.js 对服务器上的所有文本通道进行排序
【发布时间】:2021-01-22 15:34:06
【问题描述】:
module.exports = {
 name: 'cleartextchats',
 description:
  'clears desired amount of text chats created by the bot. usage: cleartextchats <amount>',
 execute(message, args) {
  var channelAmount = args[0];
  console.log('executing cleartextchats');
  for (var i = 0; i < channelAmount; i++) {
   var textChat = message.guild.channels.cache
    .filter((ch) => ch.type === 'text')
    .find(
     (targetch) => targetch.topic == 'volturnbot' && targetch.deleted == false
    );
   message.channel.send(`deleting ` + textChat.name);
   textChat.delete();
  }
 },
};

for 循环不会越过第一个删除的通道。 我认为这是因为缓存不会更新,除非我使用不同的/新消息,但该命令应该从消息中运行。我想不出一种适用于任何数量的渠道的方法。

目前,每当我的机器人创建文本频道时,它都会更新主题以包含“volturnbot”,这样它就可以在没有类别的情况下删除自己的频道。

【问题讨论】:

    标签: javascript node.js discord discord.js


    【解决方案1】:

    我认为这是因为缓存不会更新,除非我使用不同的/新消息,但命令应该从消息中运行。

    我相信这个假设是正确的。这可能是因为channel.deleted 属性仍然是false,即使您在 for 循环中删除了通道,因为可能存在与通道删除相关的轻微延迟。我能想到的解决方案有两种:

    A) 除了使用for 循环,您也许可以使用setInterval 作为延迟1000 毫秒左右的循环(可能必须根据工作原理增加或减少)。您需要创建两个新变量:一个包含setInterval 循环,另一个用于跟踪循环的迭代次数。当迭代变量等于 channelAmount 变量时,即使用 return clearInterval(intervalVariable) 其中 intervalVariable 是包含循环的变量。 (这是假设超时给缓存足够的时间在频道被删除后更新)。

    B) 循环遍历缓存的文本通道,而不是每次从缓存中获取一个通道。示例:

    var channelAmount = Number(args[0]);
    console.log("executing cleartextchats")
    
    var channels = message.guild.channels.cache.filter(ch => ch.deleted == false && ch.type === 'text' && ch.topic && ch.topic.match("volturnbot"));
    var iterations = 0;
    
    for (var textChat of channels) {
        iterations++;
        message.channel.send(`deleting ` + textChat.name)
        textChat.delete()
    
        if (iterations == channelAmount) break;
    }
    

    老实说,我更喜欢选项 B,而且我很肯定选项 B 会更好地实现您想要在这里实现的目标。您还提到频道主题“包含”短语“volturnbot”,我不确定这是否表明描述可能不仅仅是“volturnbot”,因此我让选项 B 使用 topic.match("volturnbot")

    【讨论】:

    • 谢谢你的回答,我几乎完全放弃了这个问题。但是,似乎 match 方法给出了错误TypeError: Cannot read property 'match' of null at message.guild.channels.cache.filter.ch 测试服务器上有没有主题的频道,我猜他们的主题等于 null 这给出了这个错误。
    • 无论我现在使用什么排序方法,topic 的值似乎总是未定义或什么的。 `` for (let channel of message.guild.channels.cache) { if (channel.topic && channel.topic.includes("volturnbot")) message.channel.send(channel.name); }`` 如果它必须通读channel.topic,它只会返回未定义,对于任何看起来的频道都是一样的。
    • 有趣。我不确定为什么会这样。我发现有关堆栈溢出的问题也有同样的问题,但他们的答案不是很清楚。如果您最终找到了解决方案,请告诉我,我会更新答案以包含它。
    • 您可能还想尝试console.log(channel.topic)console.log(Object.keys(channel)) 之类的方法,以确保我们拥有的频道对象包含“主题”属性。
    • 发现channels.cache返回的是一个集合而不是一个数组,所以你必须用.array()进行转换,用不同的答案修复它,它可以工作
    【解决方案2】:

    因为guild.channels.cache返回一个集合,你必须使用.array() 另外,不要找到单个通道然后搜索同一个缓存,而是将所有通道放在一个数组中并循环遍历。

        var channelAmount = Number(args[0]);
        var textChats = message.guild.channels.cache
            .filter((ch) => ch.type === 'text' && ch.topic === 'volturnbot')
            .array()
            
        for (var i = 0; i <= channelAmount; i++) {
            message.channel.send("deleting " + textChats[i].name)
            //textChats[i].delete()
        }
    

    【讨论】:

    • 请注意,您需要在for 循环中检查i &lt; channelAmount,而不是i &lt;= channelAmount。例如,如果channelAmount 等于 1(意味着我们要删除 1 个通道),则循环将在 i == 0 执行一次,在 i == 1 执行另一次(意味着删除 2 个通道,而不是只删除 1 个)。把&lt;=改成&lt;,然后这个答案就正确了。
    猜你喜欢
    • 2021-06-04
    • 2018-06-22
    • 2021-01-07
    • 2020-12-13
    • 2022-01-20
    • 2011-11-08
    • 2020-08-29
    • 1970-01-01
    • 2020-08-23
    相关资源
    最近更新 更多