Hi I'm having an issue when sending a message from a channel to a users direct messages. The message when using #user followed by message should DM the user I'm not sure why this is not working.
The mention in the message should take the user object.
Here is the code:
#commands.Cog.listener()
async def on_message(self, message):
"""Send a message thread reply to user."""
for member in message.mentions: #get user object from mention in message?
if not member.dm_channel:
await member.create_dm()
try:
time = datetime.utcnow()
embed = discord.Embed(title=f"Reply", timestamp=time, colour=discord.Colour(0xff8100))
embed.add_field(name="Message:", value="test message")
await member.dm_channel.send(embed=embed)
except discord.Forbidden:
await message.channel.send(f"Reply cannot be sent because {member.name}'s direct messages are set to private.")
except discord.HTTPException:
await message.channel.send('I failed in sending the message.')
except Exception as e:
await message.channel.send(f'There\'s been a problem while sending the message that\'s not of type "Forbidden" or'
f' "HTTPException", but {e}.')
else:
await message.channel.send(f'Reply sent to {member.name}')
In discord.py you don't really have to create dm channels anymore. Just do a await ctx.author.send(# whatever message you want)
If you're trying to create a command that sends a SPECIFIC DM to the author of the message, you can try this
#client.command()
async def dm(ctx, *, message):
await ctx.author.send(f"This is your dm {message}")
It's extremely simple. Let me know in the comments if you have any questions or I misunderstood your problem.
EDIT:
If you're looking to send a dm to a SPECIFIC MEMBER, you can try this.
#client.command()
async def dm(ctx, member: discord.Member, *, message):
await member.send(message)
Hope your problem has been solved.
PS: In the future, please explain your questions/issues in more detail.
Related
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.
I did a script where you can send a message to a specific dm using my discord bot
#client.command(pass_context=True)
async def dm(ctx, user: discord.User, *, message=None):
await ctx.channel.purge(limit=1)
message = message
await user.send(message)
But how am I to make a script that can delete all messages that was sent by the bot in a specific dm
You can iterate over the DMChannel.history() and delete the messages whose author is your client:
#client.command()
async def clear_dm(ctx, user: discord.User):
async for message in user.dm_channel.history():
if message.author == client.user:
await message.delete()
Keep in mind that you need read_message_history and manage_messages permissions respectively, otherwise a Forbidden exception will be raised.
Also, maybe it's a good idea to catch HTTPException as well, to continue the iteration if the removal of any message fails for some reason.
Never mind I fixed it. Here is the script
#client.command()
async def cleardm(ctx, user: discord.User):
#await ctx.channel.purge(limit=1) remove '#' if you want the bot to delete the command you typed in the discord server
async for message in user.history():
if message.author == client.user:
await message.delete()
I'm setting up a python TwitchIO chat bot. The getting started example has this:
async def event_message(self, message):
print(message.content)
await self.handle_commands(message)
#commands.command(name='test')
async def my_command(self, ctx):
await ctx.send(f'Hello {ctx.author.name}!')
If the incoming message is a command (e.g. !test), a message is sent back to the channel with ctx.send().
I'd like the option to send a message back to the channel (based on come criteria) whenever any message is received, not just commands. For example:
async def event_message(self, message):
print(message.content)
if SOMETHING:
SEND_MESSAGE_HERE
await self.handle_commands(message)
I can't figure out how to do some type of .send to make that happen. This answer: TwitchIO: How to send a chat message? show this:
chan = bot.get_channel("channelname")
loop = asyncio.get_event_loop()
loop.create_task(chan.send("Send this message"))
I tried that and the bot sent a ton of messages instantly and got timed out for an hour.
So, the question is: How do you send a message back to the channel inside event_message
A command passes you a Context (an instance of of Messageable, which defines send()). A Channel is also a Messageable, thus it has a send(). So if your Bot instance is bot:
await bot.connected_channels[0].send('...')
Will send a message to the first channel the bot is connected to.
This is the answer I came up with:
bot_account_name = "BOT_ACCOUNT_NAME"
async def event_message(self, message):
print(message.content)
if message.author.name.lower() != bot_account_name.lower():
ws = self._ws
await ws.send_privmsg('CHANNEL_NAME', 'Message To Send')
await self.handle_commands(message)
You can do other checks, but it's important to do the check against the bot account user name. If you don't the bot will see its own messages and reply to them creating a loop. This is one of the issues I ran into where it send a bunch in no time and got timed out by twitch
I found an alternative. I replace the message with a command that I invented for the purpose. The name of the command is "z" but it could have been anything
async def event_message(self, message):
if message.echo:
return
message.content = f"#z {message.content}" # add command name before message
await self.handle_commands(message)
#commands.command()
async def z(self, ctx: commands.Context):
print(f"Original message is {ctx.message.content[3:]}\n")
I have a command in my bot that allows a user to dm an anonymous message to me. However, when I tested the command my bot only sends the first word of the message to me.
#commands.command(name='msgetika', aliases=['msgmax'])
async def msgetika(self, ctx, message1=None):
'''Send an annonymous message to discord'''
if message1 is None:
await ctx.send('Please specify a message')
maxid = await self.bot.fetch_user('643945264868098049')
await maxid.send('Anonymous message: ' + message1)
msg = await ctx.send('Sending message to max.')
await ctx.message.delete()
await asyncio.sleep(5)
await msg.delete()
You need to add a * if you want to catch the entire phrase. View the docs here about using this and have a look at the example working beneath the code.
#commands.command(name='msgetika', aliases=['msgmax'])
async def msgetika(self, ctx, *, message1=None):
Also, unless you are using an older version of discord.py, user ids are ints.
maxid = await self.bot.fetch_user(USER ID HERE)
Someone asked me to make a bot for him that sends a DM to anyone he specifies through a command, like *send_dm #Jess#6461 hello.
I've searched alot and I came across this code:
async def send_dm(ctx,member:discord.Member,*,content):
await client.send_message(member,content)
but then I got the error:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'Bot' object has no attribute 'send_message'
I want to type for example : *send_dm #Jess#6461 hello and the bot sends a DM saying "hello" to that user.
client.send_message() has been replaced by channel.send() in the version 1 of discord.py
You can use Member.create_dm() to create a channel for sending messages to the user
async def send_dm(ctx, member: discord.Member, *, content):
channel = await member.create_dm()
await channel.send(content)
HI there hope this help you
client.command(aliases=['dm'])
async def DM(ctx, user : discord.User, *, msg):
try:
await user.send(msg)
await ctx.send(f':white_check_mark: Your Message has been sent')
except:
await ctx.send(':x: Member had their dm close, message not sent')
change you client if you use any other str
The easiest way to do is:
async def send_dm(ctx,member:discord.Member,*,content):
await member.send(content)