If Discord.py Bot gets dm - python

Dear stackoverflow community.
I want to add a little 'Easter egg' to my discord.py bot. If one gets a DM from a user, he should reply something like "No private messages while at work". Is that somehow possible? Unfortunately, I have no idea how to do this. That's why I can't attach code. Please help me : )

You can have an on_message event, which will fire each time there is any new message which your bot can read. Then you can check if the message is a direct message:
#bot.event # could be client instead of bot for you
async def on_message(message):
if message.author == bot.user: # Don't reply to itself. Could again be client for you
return
if isinstance(message.channel,discord.DMChannel): #If you want this to work in a group channel, you could also check for discord.GroupChannel
await message.channel.send("No private messages while at work")
await bot.process_commands(message)
Also don't forget to add bot.process_commands(message) add the end of on_message so your commands still work. (Could again be client instead of bot for you)
References:
Message.channel

Related

How do you make your bot ignore reply mentions?

In my bot, I have an event for replying to when the bot is mentioned. The issue is, that it replies when u mention the bot through replying to it. How can I fix this? Here's my code:
#commands.Cog.listener()
async def on_message(self, msg):
guild = msg.guild
prefix = get_prefix(self.client, guild)
if msg.author == self.client.user:
return
if msg.mention_everyone:
return
if self.client.user.mentioned_in(msg):
embed = discord.Embed(description=f"The prefix for this server is `{prefix}` <:info:857962218150953000>", color=0x505050)
await msg.channel.send(embed=embed)
Change
if self.client.user.mentioned_in(msg):
to
if msg.guild.me.mention in msg.content:
Why this happens
discord messages use a special field in it's messages to specify if someone is mentioned or not, if a message has someone in that field then the message will ping that someone. mentioned_in works that way so you can figure out if a certain message pings a certain person. when we use the msg.guild.mention part, we manually check for the mention instead of discord telling us if someone was mentioned since discord counts replies as mentions
I've used the following code for similar applications.
Note - Replace 'client' in client.user.id with what you've used like bot.user.id
#client.event
async def on_message(message):
if message.content in [f'<#{client.user.id}', f'<#!{client.user.id}>']:
await message.channel.send("Hey! My prefix is ```,```")
await client.process_commands(message)

How to make my bot forward DMs sent to it to a channel

So, I've got a bot that can send a user a DM via a very simple command. All I do is "!DM #user message" and it sends them the message. However, people sometimes try responding to the bot in DMs with their questions, but the bot does nothing with that, and I cannot see their replies. Would there be a way for me to make it so that if a user sends a DM to the bot, it will forward their message to a certain channel in my server (Channel ID: 756830076544483339).
If possible, please can someone tell me what code I would have to use to make it forward on all DMs sent to it to my channel 756830076544483339.
Here is my current code:
import discord
from discord.ext import commands
bot = commands.Bot(command_prefix='!')
#bot.event
async def on_ready():
activity = discord.Game(name="DM's being sent", type=3)
await bot.change_presence(
activity=discord.Activity(
type=discord.ActivityType.watching,
name="Pokemon Go Discord Server!"))
print("Bot is ready!")
#bot.command()
async def DM(ctx, user: discord.User, *, message=None):
message = message or "This Message is sent via DM"
await user.send(message)
await ctx.send('DM Sent Succesfully.')
Thank you!
Note: I'm still quite new to discord.py coding, so please could you actually write out the code I would need to add to my script, rather than just telling me bits of it, as I often get confused about that. Thank you!
What you're looking for is the on_message event
#bot.event
async def on_message(message):
# Checking if its a dm channel
if isinstance(message.channel, discord.DMChannel):
# Getting the channel
channel = bot.get_channel(some_id)
await channel.send(f"{message.author} sent:\n```{message.content}```")
# Processing the message so commands will work
await bot.process_commands(message)
Reference

Discord Bot Delete Messages in Specific Channel

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)

Discord.py - How can I have a command invoked in an event?

So I am trying to create an event in discord.py where, whenever a user mentions/pings the bot, it will say something. The code below runs without errors, however the only way this will work is if my command prefix is in the message.
For my bot, the prefix is "/", so whenever I mention the bot with a "/" in the message it will say something. And if I decide to just mention the bot, the bot does not respond. I am pretty sure it's got something to do with the last line of code but I don't know how to fix this issue.
#client.event
async def on_message(message):
if client.user.mention in message.content.split():
await message.channel.send('You mentioned me!')
else:
await client.process_commands(message)
The code is written in Python 3.7.4.
All help would be appreciated!
When someone mentions a user the bot reads <#userid>. So if you want to use an on_message function you would want to include an
if '<#bot/user id>' in message.content:
await message.channel.send('hi')
You can also do something like...
if bot.user in message.mentions:
await message.channel.send('hi')

Stopping a discord bot from responding to itself

I'm really new to coding, and I'm just wondering if I can get some help with a discord bot I've based off of Frost Bot.
The idea is pretty simple, Frost will respond to users, but I've removed the need to mention it to get a response.
I have a twin bot, too, and the idea is to get them to converse, which they do, however it seems that they're trying to respond to what they themselves have said, which causes a backlog of replies to come out.
Here is the bulk of the code, written in Python- if that matters.
#client.event
async def on_ready():
print('Logged in as '+client.user.name+' (ID:'+client.user.id+') | '+str(len(client.servers))+' servers')
await client.change_presence(game=discord.Game(name='chat with me!'))
#client.event
async def on_message(message):
if not message.author.bot == client.user:
await client.send_typing(message.channel)
txt = message.content.replace(message.server.me.mention,'') if message.server else message.content
r = json.loads(requests.post('https://cleverbot.io/1.0/ask', json={'user':user, 'key':key, 'nick':'frost', 'text':txt}).text)
if r['status'] == 'success':
await client.send_message(message.channel, r['response'] )
Any help would seriously be appreciated, as I'm incredibly new to scripting/coding and have spent a few hours already trying to research a solution.
Do a message.author.id == otherBotID: #stuff instead.
If you have more than one other bot to have a conversation with, switch to a NOT operator and place it as your own bot's ID, then check if the message author is a bot.
EDIT
Replace it in if not message.author.bot == client.user:.
Originally, you were checking if the message's author is not a user. And if it was not a user you would do stuff.
But since your own bot is not a user itself, the if statement would pass too when your bot sends a message (and recieves it's own message).
Hence we are placing a if-statement to check if the bot's ID equals to the targeted bot's ID.

Categories

Resources