【问题标题】:on_message won't work with command discord.pyon_message 不适用于命令 discord.py
【发布时间】:2021-05-06 17:25:25
【问题描述】:

我不确定代码是否因为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。我觉得……

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

【问题讨论】:

  • 它会抛出任何错误还是不起作用?

标签: python discord.py


【解决方案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 检查无论如何都会忽略它

【讨论】:

  • 这有助于分配!谢谢你 !感谢您的帮助,我感到压力很大:)
【解决方案2】:

您的代码显示直接错误。

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

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

您需要将其更改为message

还有声明:

await bot.process_command(ctx)

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

您的机器人不是bot 变量,而是client。所以将on_message中的bot替换为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

【讨论】:

  • 您仍在使用ctx 中的process_commands,您可能需要更新它。此外,OPs 机器人被称为client,而不是bot。此外,如果用户碰巧在同一条消息中升级,将process_commands 放在 else 子句中将导致机器人忽略任何命令。肯定是边缘情况,但仍然应该考虑它,并且修复就像将行放在函数顶层的任何块之外一样简单
  • 很好。让我进行必要的更改。
  • 终于成功了!!!你们都很乐意帮助我。
猜你喜欢
  • 2021-09-22
  • 2021-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
  • 2021-01-17
  • 1970-01-01
相关资源
最近更新 更多