尝试使用Discord.py重写版向特定频道发送消息,但无法正常工作。

9

我目前正在开发一个Discord机器人,尝试使用Discord.py rewrite在用户升级后向特定频道发送消息,但是我遇到了以下错误:

   await channel.message.send(f"{message.author.mention} is now level {self.users[author_id]['level']}! congrats!")
AttributeError: 'NoneType' object has no attribute 'message'

以下是所有的代码:

import discord
from discord.ext import commands

import json
import asyncio

class Levels(commands.Cog):
    @commands.Cog.listener()
    async def on_message(self, message):
        if message.author == self.bot.user:
            return

        author_id = str(message.author.id)
        bot = commands.Bot(command_prefix='!')

        if author_id not in self.users:
            self.users[author_id] = {}
            self.users[author_id]['level'] = 1
            self.users[author_id]['exp'] = 0

        self.users[author_id]['exp'] += 1

        if author_id in self.users:
            if self.lvl_up(author_id):
                channel = bot.get_channel('636399538650742795')
                await channel.message.send(f"{message.author.mention} is now level {self.users[author_id]['level']}! congrats!")

    def __init__(self, bot):
        self.bot = bot

        with open(r"cogs\userdata.json", 'r') as f:
            self.users = json.load(f)

            self.bot.loop.create_task(self.save_users())

    async def save_users(self):
        await self.bot.wait_until_ready()
        while not self.bot.is_closed():
            with open(r"cogs\userdata.json", 'w') as f:
                json.dump(self.users, f, indent=4)

            await asyncio.sleep(5)


    def lvl_up(self, author_id):
        author_id = str(author_id)
        current_xp = self.users[author_id]['exp']
        current_lvl = self.users[author_id]['level']
        if current_xp >= ((3 * (current_lvl ** 2)) / .5):
            self.users[author_id]['level'] += 1
            return True
        else:
            return False


我真的不确定这里的问题是什么,但如果有人知道问题所在,我会非常感激,如果您能让我知道如何纠正这个问题。
感谢您的阅读,我已经试图解决这个问题几个小时了。
编辑:问题仍然存在。
6个回答

15
您因为channel为空而遇到了AttributeError
要修复它,您需要从频道ID中移除引号,就像这样:
channel = bot.get_channel(636399538650742795)

这里有详细说明:https://discordpy.readthedocs.io/en/latest/migrating.html#snowflakes-are-int


而且我注意到下一行还有另一个错误。 channel 也没有 message 属性。我认为您需要像这样修复它:

await channel.send(f"{message.author.mention} is now level {self.users[author_id]['level']}! congrats!")

很遗憾,这个方法没有成功,因为它返回了 AttributeError: 'NoneType' object has no attribute 'send'。 - ilavywavy
这意味着id 636399538650742795 是错误的。机器人无法访问它或此频道不存在。 - Sergree
2
我已经复制了频道ID十几次,机器人也可以访问该频道,因为它可以在频道中接收命令并发送消息。 - ilavywavy

8

3
@bot.command()
async def lvl_up(member: discord.Member):
    """Send a level up message"""
    channel = bot.get_channel(channel_id) # channel id should be an int

    if not channel:
        return
        
    await channel.send(f"GG {member}, u lvled up") # Whatever msg u want to put

尝试使用该通道的代码并发送消息,然后添加您的逻辑。我是 Stack Overflow 的新手,所以不确定我是否正确格式化了该代码。


0

你需要将它放在一个异步函数中

所以,不要这样写:

channel = bot.get_channel(<channel id>)

你应该这样做

async def get_channel():
    channel = bot.get_channel(<channel id>)

asyncio.run(get_channel())

0
channel = discord.utils.get(ctx.guild.channels, id=xxxxxd) await channel.send("pong!")

1
欢迎来到Stack Overflow!虽然这段代码可能解决了问题,但是如果能够包含解释这段代码如何解决问题以及为什么能解决问题,将会极大地提高你的帖子质量,并可能获得更多的赞同。请记住,你的回答是为未来的读者而写的,而不仅仅是为了当前提问的人。请[编辑]你的回答,添加解释,并指出适用的限制和假设。 - undefined
这并没有回答问题。一旦您拥有足够的声望,您将能够对任何帖子发表评论;相反,提供不需要提问者澄清的答案。- 来自审核 - undefined

0

不确定是否已解决(抱歉,我是 Stack Overflow 的新手),但使用这个方法可以解决问题。

@bot.command()
async def Hello(ctx):
  channel = bot.get_channel(Insert Channel ID)
  await channel.send('Hello')

使用这个方法,我没有遇到NoneType错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接