Ive seen a lot of questions about this and none of them worked for me, I don't understand why something that sounds this simple is that complicated, alredy spent more than 4 hours on this, I want to make a basic bot to make new users accept the rules:
Not much to explain, just a basic bot that when you say accept in a special channel it should add you a role.
import discord
from discord.utils import get
client = discord.Client()
TOKEN = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXX'
#client.event
async def on_ready():
#creates a message for users to react to
guild = client.guilds
channel = client.get_channel(836583535981608530)
Text= "Type accept below if you understand and `accept` ALL the rules in <#836600011484785843>, in order to gain access to the server:"
await channel.send(Text)
#client.event
async def on_message(message):
if message.author == client.user:
return
channel = message.channel
if channel.id == 836593532981608530 and message.content.lower() == ('accept'):
await message.delete()
user_role = discord.utils.get(message.guild.roles, name = "role name")
new_member = message.author
new_member.add_role(user_role, reason = "new member")
elif channel.id == 836593532981608530:
await message.delete()
The problem here in your command is that you have not awaited statement(s) that had to be awaited for library to work.
So, let's start.
The statement(s) that needs to be awaited:
new_member.add_role(user_role, reason = "new member")
How to fix this error?
You need to await it just like you have awaited other statements in your code.
Just change the line to:
await new_member.add_roles(user_role, reason="new member")
This would solve the problem you have facing.
Why do you need to await some statements?
Read the docs from the following link to see why some statements are needed to be awaited. This would help you to figure out what commands has to be awaited in future.
Hope it helps. If still you have any problem, feel free to ask me in the comments. :)
Thank You! :D
Related
I need help making a afk command for my discord server. When the afk command is triggered, my bot doesn't respond with a reasoning when you ping the person whos afk. Also, when you return from being afk and type, the bot doesn't send a message saying "(user) is no longer afk". Please help me and tell me what i'm doing wrong and how can I fix this?
afkdict = {User: "their reason"} # somewhere in the code
#bot.command("afk")
async def afk(ctx, reason=None):
afkdict[ctx.user] = reason
await ctx.send("You are now afk. Beware of the real world!")
#bot.event
async def on_message(message):
afkdict = {user: "their reason"}
# some other checks here
for user, reason in afkdict.items():
if user in message.mentions:
if reason is None:
reason = ""
embed = discord.Embed(title=f"{user} is AFK", color=0xFF0000, description=reason[:2500])
await message.reply()
I was expecting this to work, the way dyno works. When i ran the command i got a message back saying user has no context. I dont know what to do anymore.
I think there's a couple of issues. Firstly, you are redefining afkdict in your on_message function it doesn't matter that you're adding users to it in the afk command. Secondly, when you're doing await message.reply(), you're not actually sending the created embed along with it.
I've resolved those problems and changed the logic slightly. Instead of iterating over the users in the afk_dict and checking if they're mentioned, we're iterating over the mentions and seeing if they're in the afk_dict. I'm also using user.id rather user objects as keys.
# defined somewhere
afk_dict = {}
#bot.command()
async def afk(ctx, reason=None):
afk_dict[ctx.user.id] = reason
await ctx.send("You are now afk. Beware of the real world!")
#bot.event
async def on_message(message):
# do whatever else you're doing here
for user in message.mentions:
if user.id not in afk_dict:
continue
# mentioned used is "afk"
reason = afk_dict[user.id] or ""
embed = discord.Embed(title=f"{user.mention} is AFK", color=0xFF0000, description=reason[:2500])
await message.reply(embed=embed)
It looks like you are missing some pieces in your code. Here is an updated version of the code:
afkdict = {}
#bot.command("afk")
async def afk(ctx, reason=None):
user = ctx.message.author
afkdict[user] = reason
await ctx.send(f"You are now AFK. {'Reason: ' + reason if reason else ''}")
#bot.event
async def on_message(message):
for user, reason in afkdict.items():
if user in message.mentions:
if reason is None:
reason = ""
embed = discord.Embed(title=f"{user} is AFK", color=0xFF0000, description=reason[:2500])
await message.channel.send(embed=embed)
if message.author in afkdict:
afkdict.pop(message.author)
await message.channel.send(f"{message.author} is no longer AFK")
In this code, the afk command will add the user who runs the command to the afkdict dictionary along with the reason for being AFK. The on_message event handler will then check if any of the mentioned users are in the afkdict and if so, it will send an embed with the AFK status and reason. Finally, if the author of the message is in the afkdict, it will remove them from the dictionary and send a message indicating that they are no longer AFK.
im trying to create a chatbot that has conversations sequentially like this. this works with one user fine but if another user tries to use the bot at the same time it interferes with the first user. I understand I would have to use some sort of asynchronous programming to fix this but I'm not sure how. any help would be appreciated
#client.event
async def on_message(msg):
if msg.author.bot:
return
if msg.content == "hey":
await msg.channel.send('hi')
response = await client.wait_for('message')
if response.content =="how are you":
await response.channel.send('good')
client.run(token)
Explanation
response = await client.wait_for('message') will catch any message sent after the command is executed, regardless of whom it's from.
This can be rectified by adding a check to wait_for, like in the code below.
Code
response = await client.wait_for('message', check=lambda message: message.author == msg.author)
Reference
wait_for
lambda expressions
I tried this but it can only answer in a specific person
message.author == client.user:
return
if message.content.startswith('slap <#!479915823897640972>'):
await message.channel.send( "{0.author.mention} slapped <#!479915823897640972>".format(message))
I recommend using commands.
If you do, it would be something like this:
#commands.command() # This can be whatever you bot variable is
async def slap(self, ctx, user): # You can change the name to whatever
await ctx.send(f"{ctx.author.mention} slapped {user}") # The only issue is that the user can be anything, from a number to a word, and not always a mention
I'm currently trying to make a bot in Discord using python (something almost brand new for me). I was trying to make an AFK function (similar to Dyno's). This is my code:
afkdict = {}
#client.command(name = "afk", brief = "Away From Keyboard",
description = "I'll give you the afk status and if someone pings you before you come back, I'll tell "
"them that you are not available. You can add your own afk message!")
async def afk(ctx, message = "They didn't leave a message!"):
global afkdict
if ctx.message.author in afkdict:
afkdict.pop(ctx.message.author)
await ctx.send('Welcome back! You are no longer afk.')
else:
afkdict[ctx.message.author] = message
await ctx.send("You are now afk. Beware of the real world!")
#client.event
async def on_message(message):
global afkdict
for member in message.mentions:
if member != message.author:
if member in afkdict:
afkmsg = afkdict[member]
await message.channel.send(f"Oh noes! {member} is afk. {afkmsg}")
await client.process_commands(message)
My issue here is that the user that uses this function will be AFK until they write again >afk. My intention was to make the bot able to remove the AFK status whenever the user talked again in the server, regardless they used a bot function or not. I know it's possible because other bots do so, but I'm lost and can't think of a way to do so.
Thanks in advance!
async def on_message(message):
global afkdict
if message.author in afkdict:
afkdict.pop(message.author)
for member in message.mentions:
if member != message.author:
if member in afkdict:
afkmsg = afkdict[member]
await message.channel.send(f"Oh noes! {member} is afk. {afkmsg}")
await client.process_commands(message)
I think that should do it, but you could as well pass the ctx again or save ctx as an parameter to access.
But this version does not notify the user, that they are not afk anymore
So I am just wondering, how can I create an event in discord.py where if a user pings the bot it will respond with a message?
I have not found anything concrete anywhere on how to do this and I would appreciate it if someone could help get my feet wet on how to do this. I appreciate it!
I found that the default function discord.User.mentioned_in works
In order for it to check for our bot, we add client.user (which is our bot) in front of the function, making it client.user.mentioned_in(message). The argument message, should be the same argument that you gave for the async def on_message(message) line
Example:
#client.event
async def on_message(message):
if client.user.mentioned_in(message):
await message.channel.send('You mentioned me!')
I'm not sure why but I haven't seen any others use this function though. Maybe they just aren't aware of this, and instead use client.user.id in message.content
#bot.event
async def on_message(message):
mention = f'<#!{bot.user.id}>'
if mention in message.content:
await message.channel.send("You mentioned me")
Some thing that I found to work was:
if str(client.user.id) in message.content:
await message.channel.send('You mentioned me!')
Discord pings in pure text are done with special strings. Luckily you don't have to generate these yourself as discord.py has user.mention (documentation). Your clientuser has this too documentation. So we just get the string of our own mention via client.user.mention
Now we just have to check if this particular string is in the message:
#client.event
async def on_message(message):
if client.user.mention in message.content.split():
await message.channel.send('You mentioned me!')