Discord.js如何突破100条限制获取所有归档线程?
解决Discord.js获取超过100条归档线程的限制问题
问题描述
开发Discord机器人命令时,尝试获取服务器所有归档线程,但受限于API的100条单次获取限制,无法拿到全部数据。尝试参考获取超过100条消息的逻辑改写,但未能成功,同时遇到线程日期顺序不一致、数据获取困难的问题。当前代码仅能获取单频道最多100条归档线程:
client.on('messageCreate', async function (message) { if(message.content === "!test"){ const guild = client.guilds.cache.get("GUILD_ID_HERE"); // 已隐藏隐私信息 var textChannels = message.guild.channels.cache.filter(c => c.type === ChannelType.GuildText); textChannels.forEach(async (channel, limit = 500) => { let archivedThreads = await channel.threads.fetchArchived({limit: 100}); console.log(archivedThreads); }); } }
解决方案
要绕过100条限制,需要通过迭代分页的方式,每次获取一批线程后,用上一批最后一条线程的归档时间作为下一次请求的before参数,循环直到没有新线程返回。同时注意:
- 避免用
forEach处理异步操作,改用for...of循环确保异步等待顺序执行 - 统一收集所有线程数据,避免打印时的顺序混乱
完整代码示例
client.on('messageCreate', async function (message) { if (message.content === "!test") { const allArchivedThreads = []; // 获取服务器所有文本频道 const textChannels = message.guild.channels.cache.filter(c => c.type === ChannelType.GuildText); // 遍历每个文本频道,用for...of确保异步等待 for (const channel of textChannels.values()) { let lastThreadTimestamp = null; let hasMoreThreads = true; while (hasMoreThreads) { // 构造请求参数,第一次不带before,后续带上上一批最后一个线程的归档时间 const fetchOptions = lastThreadTimestamp ? { limit: 100, before: lastThreadTimestamp } : { limit: 100 }; const fetchedThreads = await channel.threads.fetchArchived(fetchOptions); // 将当前批次的线程添加到总列表 allArchivedThreads.push(...fetchedThreads.threads.values()); // 检查是否还有更多线程:如果返回的线程数量小于100,说明已经取完 if (fetchedThreads.threads.size < 100) { hasMoreThreads = false; } else { // 更新lastThreadTimestamp为当前批次最后一个线程的归档时间 const lastThread = Array.from(fetchedThreads.threads.values()).pop(); lastThreadTimestamp = lastThread.archiveTimestamp; } } } // 这里可以将allArchivedThreads写入文本文件,替代控制台打印 console.log(`总共获取到 ${allArchivedThreads.length} 条归档线程`); } });
关键说明
- 分页逻辑:Discord API的
fetchArchived支持before参数,传入一个ISO时间戳,会返回该时间之前归档的线程。每次循环更新这个时间戳,直到返回的线程数不足100,说明已获取完该频道的所有归档线程。 - 异步处理:用
for...of替代forEach,因为forEach不会等待内部的async/await完成,会导致并发请求和顺序混乱,for...of能确保按频道顺序依次处理。 - 数据收集:用数组统一收集所有线程,最后再进行写入文件等操作,避免分批打印带来的顺序问题。
内容的提问来源于stack exchange,提问作者Eevee
相关产品推荐
相关产品推荐

