如何使用discord.py读取Discord论坛频道中帖子里的所有消息?
如何使用discord.py读取Discord论坛频道中帖子里的所有消息?
别担心,我来帮你一步步解决这个问题!Discord的论坛线程和普通文本频道的消息读取逻辑有点不一样,但理清步骤后其实很简单~
首先要确认:你得用discord.py v2.0及以上版本,因为论坛线程是比较新的功能,旧版本压根不支持这个特性哦。
接下来是具体的操作步骤和示例:
1. 准备工作:配置Bot权限和意图
首先要确保你的Bot开启了message_content意图(不然读不到消息内容),并且在Discord开发者平台给Bot分配了Read Message History和Send Messages的权限,这样才能顺利读取消息和反馈结果。
2. 获取论坛频道对象
先通过频道ID找到对应的论坛频道,比如用bot.get_channel(频道ID)的方式,或者在事件触发时直接获取频道对象。
3. 获取论坛里的所有线程
论坛里的每个帖子都是一个Thread对象,分为活跃线程和归档线程两种:
- 活跃线程可以直接通过
forum_channel.threads属性获取; - 归档线程需要用异步方法
forum_channel.archived_threads(limit=None)来获取,记得加await哦。
4. 读取线程内的所有消息
对于每个线程,使用thread.history(limit=None)来获取全部消息——这里limit=None很重要,默认只返回最近100条,设置成None才能拿到所有消息。另外注意这个方法返回的是异步迭代器,需要用循环或者列表推导式来遍历。
完整示例代码
import discord from discord.ext import commands # 配置Bot所需的意图 intents = discord.Intents.default() intents.message_content = True # 必须开启这个才能读取消息内容 bot = commands.Bot(command_prefix="!", intents=intents) @bot.command() async def read_all_threads(ctx, forum_channel_id: int): # 获取目标论坛频道 forum_channel = bot.get_channel(forum_channel_id) if not isinstance(forum_channel, discord.ForumChannel): await ctx.send("这不是一个有效的论坛频道ID哦,请检查后重试!") return # 收集所有活跃线程和归档线程 active_threads = list(forum_channel.threads) # 异步获取归档线程 archived_threads = [thread async for thread in forum_channel.archived_threads(limit=None)] all_threads = active_threads + archived_threads # 遍历每个线程读取消息 for thread in all_threads: await ctx.send(f"===== 正在读取线程:{thread.name}(ID:{thread.id}) =====") # 获取线程内所有消息,默认是从最新到最旧,反转后变成从最早到最新 messages = [msg async for msg in thread.history(limit=None)] messages.reverse() # 这里可以根据需求处理消息,比如打印到控制台、保存到文件,或者发送到频道 for msg in messages: await ctx.send(f"[{msg.created_at.strftime('%Y-%m-%d %H:%M')}] {msg.author.display_name}:{msg.content}") await ctx.send(f"线程{thread.name}读取完成,共{len(messages)}条消息\n") # 替换成你的Bot令牌 bot.run("你的Bot令牌")
一些需要注意的小细节
- 速率限制:如果某个线程里有几百上千条消息,直接全部发送到频道可能会触发Discord的速率限制,建议改成把消息保存到本地文本文件,或者分批次发送。
- 异步操作:所有涉及
history()和archived_threads()的方法都是异步的,一定要用await或者异步列表推导式,不然会报错。 - 权限检查:运行前务必确认Bot在目标论坛频道里有足够的权限,不然会遇到读取失败的问题。
备注:内容来源于stack exchange,提问作者Ahmed Hussein
相关产品推荐
相关产品推荐

