1
votes

I'm working on a User Discord Bot in Python .If the bot owner types !DM @user then the bot will DM the user that was mentioned by the owner.

@client.event
async def on_message(message):
    if message.content.startswith('!DM'):
        msg = 'This Message is send in DM'
        await client.send_message(message.author, msg)
5

5 Answers

2
votes

The easiest way to do this is with the discord.ext.commands extension. Here we use a converter to get the target user, and a keyword-only argument as an optional message to send them:

from discord.ext import commands
import discord

bot = commands.Bot(command_prefix='!')

@bot.command(pass_context=True)
async def DM(ctx, user: discord.User, *, message=None):
    message = message or "This Message is sent via DM"
    await bot.send_message(user, message)

bot.run("TOKEN")

For the newer 1.0+ versions of discord.py, you should use send instead of send_message

from discord.ext import commands
import discord

bot = commands.Bot(command_prefix='!')

@bot.command()
async def DM(ctx, user: discord.User, *, message=None):
    message = message or "This Message is sent via DM"
    await user.send(message)

bot.run("TOKEN")
3
votes

Since the big migration to v1.0, send_message no longer exists.
Instead, they've migrated to .send() on each respective endpoint (members, guilds etc).

An example for v1.0 would be:

async def on_message(self, message):
    if message.content == '!verify':
        await message.author.send("Your message goes here")

Which would DM the sender of !verify. Like wise, you could do:

for guild in client.guilds:
    for channel in guild.channels:
        channel.send("Hey yall!")

If you wanted to send a "hi yall" message to all your servers and all the channels that the bot is in.

Since it might not have been entirely clear (judging by a comment), the tricky part might get the users identity handle from the client/session. If you need to send a message to a user that hasn't sent a message, and there for is outside of the on_message event. You will have to either:

  1. Loop through your channels and grab the handle based on some criteria
  2. Store user handles/entities and access them with a internal identifier

But the only way to send to a user, is through the client identity handle which, in on_message resides in message.author, or in a channel that's in guild.channels[index].members[index]. To better understand this, i recommend reading the official docs on how to send a DM?.

0
votes

I used this command in the past and it in my opinion it works the best for me:

@bot.command(pass_context=True)
async def mall(ctx, *, message):
  await ctx.message.delete()
  for user in ctx.guild.members:
    try:
      await user.send(message)
      print(f"Successfully DMed users!")
    except:
      print(f"Unsuccessfully DMed users, try again later.")
0
votes
@bot.command()
async def dm(ctx, user: discord.User, *, message=None):
    if message == None:
      message = "Hi!"
    embed = make_embed(title=f"Sent by {user}", desc=message)
    await user.send(embed=embed)
    await ctx.send("Message sent!")```
0
votes

I have noticed that each code I put into my code lines they don't work completely, so I added my own bit to them and bam it works! When adding this to your bot's code, don't forget to add the bot's name where it says bot name here. It will only DM the person who sent it, but you can change what it says each day for a surprise for everyone that used the command. It works every time for me.

@client.command()
async def botdm(ctx):
  await ctx.message.author.send('hi my name is *bot name here* and i am a bot!')