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

discord.py 2.1.0获取频道最后一条消息的问题及报错排查

Discord.py 2.1.0 获取频道最后一条消息问题解决

问题场景

使用discord.py 2.1.0时,想要获取服务器内指定前缀频道的最后一条消息,尝试两段代码后遇到以下问题:

第一段代码及问题

代码:

@tree.command(guild = discord.Object(id=941748573937209344), name = 'kontrol', description='kontrol') 
async def check(ctx):
    channels = ctx.guild.text_channels
    for channel in channels:
        if channel.name.startswith('test-'):
            last_message = [msg async for msg in channel.history(limit=1)]
            print(last_message)

输出结果:

[<Message id=1060085926157619221 channel=<TextChannel id=1060078850417111112 name='test-supraaaaaa' position=19 nsfw=False news=False category_id=941749835328012328> type=<MessageType.default: 0> author=<User id=323516141777715202 name='supraaaaaa' discriminator='0966' bot=False> flags=<MessageFlags value=0>>]

问题:输出中无法看到消息的创建时间。

第二段代码及报错

代码:

@tree.command(guild = discord.Object(id=941748573937209344), name = 'kontrol', description='kontrol') #guild specific slash command
async def check(ctx):
    channels = ctx.guild.text_channels
    for channel in channels:
        if channel.name.startswith('övgü-'):
            last_message = [msg async for msg in channel.history(limit=1)]
            print(last_message.id)

报错信息:

AttributeError: 'list' object has no attribute 'id'

错误原因

  1. 列表对象导致属性访问错误:channel.history(limit=1)返回异步迭代器,用列表推导式转成的是包含单个Message对象的列表,而非单个Message实例,直接访问.id会触发属性错误。
  2. 默认打印未展示创建时间:Message对象默认打印时不会输出created_at属性,需要主动访问才能获取该信息。

修正后的代码

方式一:通过异步循环取出消息

@tree.command(guild = discord.Object(id=941748573937209344), name = 'kontrol', description='kontrol') 
async def check(ctx):
    channels = ctx.guild.text_channels
    for channel in channels:
        # 匹配目标频道前缀
        if channel.name.startswith('test-') or channel.name.startswith('övgü-'):
            last_message = None
            # 从异步迭代器中取出最后一条消息
            async for msg in channel.history(limit=1):
                last_message = msg
                break
            if not last_message:
                print(f"频道 {channel.name} 无消息")
                continue
            # 输出消息详情
            print(f"频道 {channel.name} 最后一条消息:")
            print(f"消息ID: {last_message.id}")
            print(f"创建时间: {last_message.created_at}")
            # 可选:输出消息内容
            # print(f"消息内容: {last_message.content}")

方式二:使用anext()直接获取消息(更简洁)

@tree.command(guild = discord.Object(id=941748573937209344), name = 'kontrol', description='kontrol') 
async def check(ctx):
    channels = ctx.guild.text_channels
    for channel in channels:
        if channel.name.startswith('test-') or channel.name.startswith('övgü-'):
            try:
                # 从异步迭代器中获取第一条(即最后一条)消息
                last_message = await anext(channel.history(limit=1))
            except StopAsyncIteration:
                print(f"频道 {channel.name} 无消息")
                continue
            print(f"频道 {channel.name} 最后一条消息:")
            print(f"消息ID: {last_message.id}")
            print(f"创建时间: {last_message.created_at}")

关键点说明

  • 避免将异步迭代器转为列表,直接获取单个Message实例才能访问其属性(如.id、.created_at)。
  • Message对象的created_at属性存储了消息的创建时间,需主动调用才能展示。
  • 加入无消息场景的处理,避免程序抛出异常。

内容的提问来源于stack exchange,提问作者ahmet güzel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 17:40:31