on_message 不适用于命令 discord.py

时间:2021-05-06 08:56:43

标签: python discord.py

我不确定代码是否因为 on_message(ctx) 而无法工作,无论哪种方式,都是我所做的:

import discord 
from discord.ext import commands 
import pymongo 
import os
from pymongo import MongoClient

mango_url = "mongodb+srv://<usernamehere>:<password>@discordbot.kllv6.mongodb.net/discordbot? 
retryWrites=true&w=majority"
cluster = MongoClient(mango_url)
db = cluster["discordbot"]
collection = db["discordbot"]

client = commands.Bot(command_prefix = '$')

@client.event
async def on_ready():
    print("bot is online")


@client.command()
async def _ping(ctx):
    await ctx.send('discord sucks :(')

@client.event
async def on_message(ctx):
    author_id = ctx.author.id
    guild_id = ctx.guild.id 
    author = ctx.author
    user_id = {"_id": author_id}

    if ctx.author == client.user:
        return

    if ctx.author.bot:
        return

    if(collection.count_documents({}) == 0):
        user_info = {"_id": author_id, "GuildID": guild_id, "Level": 1, "XP": 0}
        collection.insert_one(user_info)

    if(collection.count_documents(user_id) == 0):
        user_info = {"_id": author_id, "GuildID": guild_id, "Level": 1, "XP": 0}
        collection.insert_one(user_info)

    exp = collection.find(user_id)
    for xp in exp:
        cur_xp = xp["XP"]

        new_xp = cur_xp + 1 

    collection.update_one({"_id": author_id}, {"$set":{"XP":new_xp}}, upsert=True)

    #await ctx.channel.send("1 xp up")

    lvl = collection.find(user_id)
    for levl in lvl:
        lvl_start = levl["Level"]

        new_level = lvl_start + 1

    if cur_xp >= round(5 * (lvl_start ** 4 / 5)):
        collection.update_one({"_id": author_id}, {"$set":{"Level":new_level}}, upsert=True)
        await ctx.channel.send(f"{author.name} has leveled up to {new_level}!")

        await bot.process_commands(ctx)



client.run("token")

如果我删除 on_message(ctx) 中的所有内容(也是事件),那么它就可以工作了。

我已经尝试了所有方法,但它不起作用。

示例:

await bot.process_commands(message)

这也不起作用,因为我使用的是 ctx 而不是 message。我觉得……

如果您对此有答案,请帮助我。

2 个答案:

答案 0 :(得分:1)

您的 on_message 活动有几个问题:

  1. on_message 带有 message,而不是 ctx
  2. 您的机器人客户端名为 client,而不是 bot
  3. process_commands 行缩进太多。它需要在事件定义的最外层缩进层上,否则它最终可能不会被每条消息触发,这会导致机器人忽略部分或全部命令(在您的情况下,机器人识别命令的唯一时间是如果用户在同一条消息中升级)

您可以通过如下方式修复您的代码:

@client.event
async def on_message(message):
    author_id = message.author.id
    guild_id = message.guild.id 
    author = message.author
    user_id = {"_id": author_id}

    if message.author.bot:
        return
    
    # rest of your code goes here

    # notice the indentation layer. This needs to be at the top layer of your function
    await client.process_commands(message)

旁注:您不需要单独检查消息作者是否是您的机器人,因为 message.author.bot 检查无论如何都会忽略它

答案 1 :(得分:0)

您的代码显示了一个直接错误。

当我们使用 event 时,使用参数:message,然后使用 command() 时使用参数:ctx

您正在为机器人中的事件使用 ctx 参数。它不会简单地工作。

您需要将其更改为 message

还有声明:

await bot.process_command(ctx)

这里的 ctx 也必须改为 message 并且它应该与 else 一起使用,而不是在 if 内使用。

您的机器人不是 bot 变量而是 client。因此将 bot 中的 on_message 替换为 client

经过上述所有更改后,代码为:

@client.event
async def on_message(message):
    author_id = message.author.id
    guild_id = message.guild.id 
    author = message.author
    user_id = {"_id": author_id}

    if message.author == client.user:
        return

    if message.author.bot:
        return

    if(collection.count_documents({}) == 0):
        user_info = {"_id": author_id, "GuildID": guild_id, "Level": 1, "XP": 0}
        collection.insert_one(user_info)

    if(collection.count_documents(user_id) == 0):
        user_info = {"_id": author_id, "GuildID": guild_id, "Level": 1, "XP": 0}
        collection.insert_one(user_info)

    exp = collection.find(user_id)
    for xp in exp:
        cur_xp = xp["XP"]

        new_xp = cur_xp + 1 

    collection.update_one({"_id": author_id}, {"$set":{"XP":new_xp}}, upsert=True)

    await message.channel.send("1 xp up")

    lvl = collection.find(user_id)
    for levl in lvl:
        lvl_start = levl["Level"]

        new_level = lvl_start + 1

    if cur_xp >= round(5 * (lvl_start ** 4 / 5)):
        collection.update_one({"_id": author_id}, {"$set":{"Level":new_level}}, upsert=True)
        await message.channel.send(f"{author.name} has leveled up to {new_level}!")
    
    await client.process_commands(message)

希望这会有所帮助。谢谢! :D