How do i code an afk command like dynos afk command - python

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 im doing wrong and how can i fix this?
afkdict = {}
#bot.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!")
I expected this to run a afk command like the one dyno bot has, but instead its a timer. Please help me code an afk command where if someones afk and gets pinged the bot tells them theyre afk with reasoning and when someone comes back from being afk the bot says welcome back

You can use the on_message event and check if the message mentions an afk user. While you can use a command to "set" a user AFK
afkdict = {} # somewhere in the code
#bot.event
async def on_message(self, message):
# 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(embed=embed)
#bot.command("afk")
async def afk(self, ctx: commands.Context, reason=None):
afkdict[ctx.author] = reason
await ctx.send("You are now afk. Beware of the real world!")
Read more about the on_message event: https://discordpy.readthedocs.io/en/latest/api.html#discord.on_message
Reading the docs about the Message object might also help: https://discordpy.readthedocs.io/en/latest/api.html#discord.Message

Related

How do i code an afk command that comes out the way dyno runs

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.

discord.py kick command thats sends a dm to user that is kicked

I am trying to make a discord.py bot with a kick command. So when you do ;kick (member) it will kick the mentioned user and send that user a dm telling them they are kicked from the server. However it only dms the user if the dm is a normal message and not embed. I'm still pretty new to python so I don't understand whats wrong with the code. Here is my code:
#commands.guild_only()
#has_permissions(kick_members = True)
async def kick(self, ctx, member : discord.Member=None, *, reason="No reason was provided"):
aA=ctx.author.avatar_url
desc1=f"You are missing the following argument(s): `Member`\n```{prefix}kick <member> [reason]```"
embed1=discord.Embed(title="Missing Argument",description=desc1,color=rC)
embed1.set_author(name="Error",icon_url=aA)
try:
if member == None:
await ctx.send(embed=embed1)
return
if member == ctx.author:
await ctx.send(f"You can't kick yourself.")
return
try:
em1=discord.Embed(description=f"You were kicked out from **{ctx.guild.name}**\nReason: `{reason}`.",color=rC)
em1.set_author(icon_url=aA)
await member.send(embed=em1)
except:
pass
em2=discord.Embed(description=f"{tick} {member.mention} has been kicked out of **{ctx.guild.name}**. Reason: `{reason}`",color=gC)
await member.kick(reason = reason)
await ctx.send(embed=em2)
except:
await ctx.send("An unknown error occured.)
There isn't any errors sent in the console when I run the bot or use the command
you can use:
await member.send(embed=em2)
ctx will send in the channel where the command was done.

discord.py add role on message

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

AFK function in Discord Bot

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

DM commands to discord bot

I recently had the idea of DMing my bot commands. For example, a command which would unban me from every server that the bot is on.
Unfortunately I don't have any starting point for the command because I'm not even sure DMing commands is possible.
Keywords like discord.py, command or DM are so common in google that finding any good info on the topic is very hard.
I'm looking for a way for the bot to receive DMs as commands and only accept them from me (my ID is stored in the variable ownerID if anyone wants to share any code).
While I'm mostly looking for the above, some code for the DM unban command would also be very helpful.
EDIT: I was asked to show some example code from my bot. Here is the code for the command number which generates a random number and sends it in a message. I hope this gives you an idea of how my bot is made:
#BSL.command(pass_context = True)
async def number(ctx, minInt, maxInt):
if ctx.message.author.server_permissions.send_messages or ctx.message.author.id == ownerID:
maxInt = int(maxInt)
minInt = int(minInt)
randomInt = random.randint(minInt, maxInt)
randomInt = str(randomInt)
await BSL.send_message(ctx.message.channel, 'Your random number is: ' + randomInt)
else:
await BSL.send_message(ctx.message.channel, 'Sorry, you do not have the permissions to do that #{}!'.format(ctx.message.author))
You can send commands in private messages. Something like
#BSL.command(pass_context=True)
async def unban(ctx):
if ctx.message.channel.is_private and ctx.message.author.id == ownerID:
owner = await BSL.get_user_info(ownerID)
await BSL.say('Ok {}, unbanning you.'.format(owner.name))
for server in BSL.servers:
try:
await BSL.unban(server, owner) # I think having the same name should be fine. If you see weird errors this may be why.
await BSL.say('Unbanned from {}'.format(server.name))
except discord.HTTPException as e:
await BSL.say('Unbanning failed in {} because\n{}'.format(server.name, e.text))
except discord.Forbidden:
await BSL.say('Forbidden to unban in {}'.format(server.name))
else:
if ctx.message.author.id != ownerID:
await BSL.say('You are not my owner')
if not ctx.message.channel.is_private:
await BSL.say('This is a public channel')
should work. I'm not sure what happens if you try to unban a user who is not banned, that may be what raises HTTPException

Categories