I'm not sure if the code won't work because of the on_message(ctx)
or not, either way, is what I have done:
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")
If I remove everything inside the on_message(ctx)
(also the event) then it works.
I have tried everything but it won't work.
Example:
await bot.process_commands(message)
That does not work either because I am using ctx
not message
. I think...
If you have an answer to this please help me with this.
There's several issues with your on_message
event:
on_message
comes with a message
, not a ctx
client
, not bot
process_commands
line is indented too far. It needs to be on the outmost indentation layer of the event definition, otherwise it can end up not being triggered for each message, which leads the bot to ignore some or all commands (in your case, the only time the bot would recognize a command is if the user levelled up in the same message)You can fix your code by making it something like the below:
@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)
Side note: you don't need to check if the message author is your bot separately, as the message.author.bot
check will ignore it anyway
Your code shows a straight error.
When we use event
then the argument: message
is used and then we use command()
then the argument: ctx
is used.
You are using the ctx
argument for an event in your bot. It won't simply work.
You need to change it to message
.
Also the statement:
await bot.process_command(ctx)
Here too ctx
has to be changed to message
and it should be used with else
and not inside if
.
Your bot is not bot
variable but is client
. So replace the bot
in on_message
to client
After all of the above changes the code is:
@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)
Hope this helps. Thank You: :D
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.