NOTE: I am using discord.Client for my code.
So, when we are sending a message, we can use delete_after=secs parameter to delete a message after some time.
channel = await message.author.create_dm()
await channel.send("test dm (deletes after 60 secs)", delete_after=60)
But, do we have thing like that with discord.Role, or is there another solution to remove a role after some time?
This is docs for discord.Role.delete.
If you look there, you can see that it is not build in, so you'd have to implement the solution yourself.
Luckly its not too bad.
import asyncio
...
await asyncio.sleep(delay)
await discord.Role.delete(discord.Role.id, reason=None)
Hope this helps.
Related
I'm trying to dm a mentioned user in discord.
I need something like
class MyClient(discord.Client):
# ...
client = MyClient()
client.run("Token")
not discord.ext because it would ruin my code.
I tried:
if message.content.lower().startswith("/trade"):
mention = message.author.mention
await client.send(mention, message.author + " will mit dir traden!")
but it doesn't work.
I don't really recommend using / as a prefix due to the potential confusion of the built in slash commands (coming in d.py 2.0 for bots).
You probably are better using ext.commands eventually though as you can type hint the user much easier within the command signature.
e.g.
#commands.command()
async def trade(self, ctx, member: discord.Member):
# Code here
await member.send("message")
In your example though you will want to use message.mentions to get a list of users mentioned in the message. If you want just the first mention then you can use the index 0 message.mentions[0]
mentioned_member = message.mentions[0]
await mentioned_member.send("Message")
My python discord bot keeps getting errors when I tell it to send a message in a channel
#client.command()
async def log(ctx, msg):
channel = client.get_channel(852610465871036416)
await channel.message.send(msg)
PS: its fixed now
Try This:
#client.command()
async def log(ctx, msg):
await ctx.send(msg)
I'm Pretty Sure You Needed to Use ctx.send
Tortle.py is completely right, however, you can do many forms of the ctx.___("stuff") . The first and simplest example would be ctx.send("stuff") , this will send the "stuff" in the channel where the user called the function (the thing the bot is doing.)
You could also do ctx.author.send this will DM (direct message) the author that called the function.
You could also do ctx.reply this will reply to the message that the user sends.
I hope you found this useful and feel free to like on this message for any extra support!
in last line
await channel.message.send(msg)
?
try it
await channel.send(msg)
#client.command()
async def log(ctx, message):
await ctx.get_channel(852610465871036416).send(“your message”)
This would work
possible cause #2 is probably what's happening
Why I am using this:
I am trying to get my bot to detect a bot's embed message (to get the in-game currency of a player) using
await client.wait_for
Problem
However, it somehow does not detect the embeds sent by the bot. It still acknowledges it as long as it has plain text sent together with the embed or it sends the plain text on its own. The
#client.event
async def on_message(message):
code will still work if the bot has sent embeds with or without the text.
Possible causes:
1. ❌Already tested and proven not the cause❌ That my bot cannot read messages from bots
2. Possible: That my bot is slower that the bot I am testing with, so once my bot detects a message sent by a user for the bot to react, the bot has already responded with another message, so the bot is still waiting for a non-existent message. I have not found a viable, not time-consuming way to test this
3. Possible: {this question}
Others
All help will be appreciated! Please also point out any errors in my code here and whether I am using the right code to detect embeds and/or messages by bots. I would also appreciate alternative ways of doing my code.
Code
A portion of my current code is:
def pred(m):
return m.author == client.get_user(490707751832649738)
try:
msg = await client.wait_for('message', check=pred, timeout=10.0)
except asyncio.TimeoutError:
await message.channel.send('Looks like Taco-shack is down :/')
else:
await message.channel.send('You said {0.content}, {0.author}.'.format(msg))
Please ignore the indentations. It was fresh copypasta from my code. I modified it from the API https://discordpy.readthedocs.io/en/latest/migrating.html#waiting-for-events
output:
Looks like taco-shack is down which is the output of an asyncio timeout error
P.S. This is my first question after creating my stack overflow account, I realised that there were already so many articles that I could refer to. So I kept searching, but I could only not find the solution to this question. Please ignore my poor formatting!
Edit:
in response to my comments, I shall make it more clear
I have amended my above code because of Eric's help. He commented something that led me to improve my code ;)
Thanks
In response to Patrick's comment (thanks a lot for directing me to the https://stackoverflow.com/help/minimal-reproducible-examrple help page, really appreciate it ;)), here are a few steps you can go to reproduce the code.
Steps to reproduce the problem
Step 1:
Go to the Discord developer portal and create 2 bots, one for sending the embed and the other for this testing thing (one if you have a random bot that can send embeds
Step 2:
Invite the bot(s) to your server
Step 3:
Code the first bot to send an embed once you sent a message inside any channel maybe a simple embed like the one in How can I send an embed via my Discord bot, w/python? and also maybe an else added to it and that else sends some plain text. Remember to use client.run()!
Step 4
Code the second bot like this:
#client.event
async def on_message(message):
def pred(m):
return m.author == client.get_user(490707751832649738)
try:
msg = await client.wait_for('message', check=pred, timeout=10.0)
except asyncio.TimeoutError:
await message.channel.send('Looks like Taco-shack is down :/')
else:
await message.channel.send('You said {0.content}, {0.author}.'.format(msg))
client.run('token')
Step 5:
Run the two bots!
More questions:
I don't seem to understand whats the use of using message.embeds. I am trying to wait for a message to be sent under the on.message to continue the thread after someone types .balance to see the value of their account so that the bot can get the information. However, it does not recognise a message was sent by the bot
Legality/ethicality
The idea of making this bot came because Carl could not send the message ID.
This part is to see how much money the user has left along with whether the person has successfully sent the donation so that false donations do not clutter the channel
This bot is not meant to be a self bot.
and should not be thought as one.
** If and when you find out that this is not legal, please give a 'no' answer or comment that it is not legal (I prefer the latter) **
I can't reproduce this. Here's what I'm doing
#bot.event
async def on_message(message):
if message.author.id == bot.user.id:
print(message.content)
print(message.embeds)
await bot.process_commands(message)
#bot.command()
async def comm(ctx):
msg = await bot.wait_for('message', check=lambda m: m.author.id == bot.user.id)
await ctx.send(f"{msg.content} {msg.embeds}")
#bot.command()
async def send_content(ctx):
await ctx.send("content1")
#bot.command()
async def send_embed(ctx):
embed = Embed(title="Title1")
await ctx.send(embed=embed)
#bot.command()
async def send_both(ctx):
embed = Embed(title="Title2")
await ctx.send("content2", embed=embed)
I only have the one bot, so maybe that's the problem, but by running !comm and then !send_embed, the bot will detect its own embed-only message from wait_for. One thing I do in this code is to compare objects by id instead of by simple equality.
I edited my on_message to detect the response the second it hears the message. Thanks for all your help :) It was the 2nd thing I ruled out
TIA for your help and apologies, I'm a newbie so this may be a foolish question. I've searched through and can't find anything specific on how to make a discord bot (in Python) delete messages only within a specific channel. I want all messages sent to a specific channel to be deleted, their contents sent via PM to the user and the user's role changed.
Is there a way to use on_message and specify in an specific channel?
#client.event
async def on_message(message):
user = message.author
if message.content.startswith("Cluebot:"):
await message.delete()
await user.send("Yes?")
await user.remove_roles(get(user.guild.roles, "Investigator"))
The problem I'm having is I'm also using commands which now no longer work because the bot only responds if the message begins with "Cluebot:" Can I have the bot only look for "Cluebot:" in a specific channel?
Is it possible to make this work through a command instead of an event?
Thanks for your help. :)
The problem I'm having is I'm also using commands which now no longer work because the bot only responds if the message begins with "Cluebot:" Can I have the bot only look for "Cluebot:" in a specific channel?
About this problem the clue is:
await bot.process_commands(message)
as docs says Without this coroutine, none of the commands will be triggered.
about the main question you could try using get_channel by ID and then purge it:
eg.
#client.event
async def on_message(message):
purgeChannel = client.get_channel([CHANNEL ID]])
await purgeChannel.purge(limit=1)
you can add check to purge() to check for deleting specific message:
eg.:
def check(message):
return message.author.id == [author's ID]
#client.event
async def on_message(message):
purgeChannel = client.get_channel([CHANNEL ID]])
await purgeChannel.purge(limit=1, check=check)
Say I want to make a bot with a "poke" feature (aka sends a pm to a user saying "Boop" when someone says "!poke #user#0000"), how would I do this? It works perfectly when I do this:
#bot.command(pass_context=True)
async def poke(ctx, message):
await client.send_message(ctx.message.author, 'boop')
but only if I want to poke the author of the message. I want to poke whoever's being #'d.
I know the discord.py documents say I can use this:
start_private_message(user)
but I don't know what to put in place of user.
It's actually simpler than that
#bot.command(pass_context=True)
async def poke(ctx, member: discord.Member):
await bot.send_message(member, 'boop')
send_message contains logic for private messages, so you don't have to use start_private_message yourself. The : discord.Member is called a converter, and is described in the documentation here
I might be necroing this post a bit, but the recent version of this would look like this:
#bot.command():
async def poke(ctx, user: discord.Member=None):
if user is None:
await ctx.send("Incorrect Syntax:\nUsage: `!poke [user]`")
await user.send("boop")
The if user is None: block is optional, but is useful if you want to have an error message if a command isn't used correctly.