bot accepting user input via DM? - python

Testing out moving some of my setup modules to DMs instead of in a server channel, as if I do it in a channel, people can easily get a bit confused with responses even though I have the bot set to ignore anyone but the original command author
I've tried the usual wait_for handler, but I can't seem to get the bot to catch the input via dm
#commands.command(name="dmstats")
async def stat_dm(self, ctx):
member = ctx.author
stat_list = await self.get_stat_vals(ctx, member)
reply = await ctx.author.send("What value do you want?")
await self.bot.wait_for('message')
if reply.content.lower() == "strength":
await ctx.author.send("Your strength is: {}".format(stat_list["strength"]))
Expected that when I [p]dmstats and trigger the command, the bot will DM me and prompt me, which it does, however its not catching my response

If you want to only accept messages from that user in a DM channel, you can record the channel that you sent the message to the user in, and then apss that as part of a check to wait_for
#commands.command(name="dmstats")
async def stat_dm(self, ctx):
stat_list = await self.get_stat_vals(ctx, member)
msg = await ctx.author.send("What value do you want?")
def check(message):
return message.author == ctx.author and message.channel == msg.channel
reply = await self.bot.wait_for('message', check=check)
if reply.content.lower() == "strength":
await ctx.author.send("Your strength is: {}".format(stat_list["strength"]))

Related

How can i fix this pycord code project i made?

I have a discord bot project. In the following code I made that if you reply a specific word the bot will give you a role. I already created the role but when I try it turn out to a error.
I'm using Pycord.
Code:
#bot.slash_command()
async def money(ctx):
await ctx.send("How much money you have?")
def check(m):
return m.content == "100,000" and m.author == ctx.author
role_input = await bot.wait_for('message', check=check)
role = discord.utils.get(ctx.guild.roles, name="Rich")
await role_input.author.add_roles(role)
await ctx.send(f"{role_input.author.mention}, you have been given the 'Rich' role.")
I was trying to make a slash command that the bot will reply "How much money you have?" and if you reply the specific word "100,000" then the bot will grant you a role.
The reason you're getting "the application did not respond" is because you're never responding to the application command. As your command could probably take a while waiting for the user to respond, we can use await ctx.defer() to defer our response and then use await ctx.followup.send to send the followup message and respond. If you didn't use defer, you could also use ctx.response.send_message or ctx.respond in cases where the command doesn't take too long to execute.
#bot.slash_command()
async def money(ctx):
# deferring as it might take us a while
await ctx.defer()
await ctx.send("How much money you have?")
def check(m):
return m.content == "100,000" and m.author == ctx.author
role_input = await bot.wait_for('message', check=check)
role = discord.utils.get(ctx.guild.roles, name="Rich")
await role_input.author.add_roles(role)
await ctx.followup.send(f"{role_input.author.mention}, you have been given the 'Rich' role.")

I'm trying to get my discord bot to wait for the user to send another message after they did the original command

Sorry if the title didn't make sense, I'm making a discord bot and I'm trying to make a little 8 ball command. What I'm trying to make the bot do is that after the user type "$8ball" the bot will say "What's your question?" Then wait for the user to type out their question and then respond with the array of responses I've made for it.
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith("$8Ball"):
await message.channel.send("What is your question?")
(that's all the code I have so far)
Try this. question will be what the user inputted. It waits for a message in the same channel as the orginal command and by the same user who did the command
#client.event
async def on_message(message, author):
if message.content.startswith('$8Ball'):
channel = message.channel
author = message.author
await channel.send('What is your question?')
def check(m):
return m.author == author and m.channel == channel
msg = await client.wait_for('message', check=check)
question = msg.content
Tell me how it goes :D
You can try to store the id of the user and react to the next message of this user.

Is there a way to make a confirmation in Discord.py?

I have a Discord bot and I'd like to know how I can create a confirmation for my purgeroles command. Here's the command currently:
#client.command(aliases = ['delroles', 'deleteroles', 'cleanseroles'])
async def purgeroles(ctx):
embed=discord.Embed(title="Purging (deleting) roles...")
embedcomplete=discord.Embed(title="All possible roles have been purged (deleted)!")
if (not ctx.author.guild_permissions.manage_roles):
await ctx.reply("Error: User is missing permission `Manage Roles`")
return
await ctx.reply(embed=embed)
for role in ctx.guild.roles:
try:
await role.delete()
except:
pass
await ctx.reply(embed=embedcomplete)
I don't want the bot to just delete all of the roles on command, in case someone runs the command by accident. Is there anyway I can make the bot wait until the author says a message to confirm whether or not the bot should continue?
You can use wait_for for this type of stuff.
#client.command(aliases = ['delroles', 'deleteroles', 'cleanseroles'])
async def purgeroles(ctx):
await ctx.send("Are you sure you want to run this command? (yes/no)")
def check(m): # checking if it's the same user and channel
return m.author == ctx.author and m.channel == ctx.channel
try: # waiting for message
response = await client.wait_for('message', check=check, timeout=30.0) # timeout - how long bot waits for message (in seconds)
except asyncio.TimeoutError: # returning after timeout
return
# if response is different than yes / y - return
if response.content.lower() not in ("yes", "y"): # lower() makes everything lowercase to also catch: YeS, YES etc.
return
# rest of your code
You could use client.wait_for.
#client.event
async def on_message(message):
if message.content.startswith('$greet'):
channel = message.channel
await channel.send('Say hello!')
def check(m):
return m.content == 'hello' and m.channel == channel
msg = await client.wait_for('message', check=check)
await channel.send('Hello {.author}!'.format(msg))
More info in the Discord docs.

Discord.py Bot deleting bot message too

I'm writing a simple script that exec if a simplified string is written in a channel, after that the user message gets deleted.
Or if the user send a message that is not one of the strings it to be deleted too.
However, even the bot message gets deleted too which are theses
await message.channel.send(badr.mention)
await message.channel.send(expired)
and
await message.channel.send(author.mention)
await message.channel.send(WL_message)
which is not what I'm aiming for I want only the member's message to get deleted not the bots.
if (message.channel.id == 897508930744381491):
author = message.author
content = message.content
expire = '||!WL xdxdxd||', '||!WL 432-234-4312-fas2||'
Valied= '||!WL Furball2244||', '||!WL 432-234-4www312-32242||', 'Furball2244', '!WL Furball2244'
if message.content.startswith(expire):
await message.delete()
badr = author
expired= "This code is expired, contact an admin in <#899289942897860659>, there is a chance they can add you manually"
await message.channel.send(badr.mention)
await message.channel.send(expired)
if message.content.startswith(Valied):
ROLE = "Role55555"
WL_message='Congratulations, now you have access to <#930074601436905522>, you enter your information there.'
await message.channel.send(author.mention)
await message.channel.send(WL_message)
role = get(message.guild.roles, name=ROLE)
await author.add_roles(role)
else: await message.delete()
Is there a trick around it?
To my understanding, you want to delete the message the user sends, in which you would use
await ctx.message.delete()
You need to wait for author to send message
def check(m):
return message.author == oldmsg.author #To make sure it is the only message author is getting
msg = await self.bot.wait_for('message', timeout=60.0, check=check)
if message.content == "your codes":
# do stuff
await message.delete()
This way you can delete the next message from the user right away. make sure you save the command author in a global dictionary or something!
elif message.author.id == 930374951935021096:
return
else:
await message.delete()
seems like just adding an elif solves the problem, regardless thank you for your reply.

discord.py Bot does not respond to input in DMs

What I'm trying to do: To receive a response from the message author in their DMs with the bot.
My problem: Bot does not respond when message is sent to it in the DMs as I am expecting. There are no error messages.
Code:
#client.command()
async def test(ctx):
await ctx.send("Sending a dm now")
def check(message):
return message.author == ctx.author and message.channel == discord.channel.DMChannel
try:
await ctx.author.send("Say test: ")
response = await client.wait_for('message', check=check)
if response.content.lower() == 'test':
await ctx.send("Test successful")
elif response.content.lower() == 'banana':
await ctx.author.send("That works too")
except:
# do things here
Images:
(Above image) No response is given despite the given conditions being met.
References/ Other Questions I have referred to:
Discord.py Check if Channel is a DM
discord.DMChannel API Reference
Discord.py - Reply to DM with a specific message
Discord.py bot: how would I make my discord bot send me responses to a command that users use in DMs e.g. for a survey?
There is a problem with your check, if you print message.channel you will get:
Direct Message with username#1234
And if you print discord.channel.DMChannel you will get:
<class 'discord.channel.DMChannel'>
You will notice they are two different things, changing your check to this should fix the problem:
def check(message):
return message.author == ctx.author and str(message.channel.type) == "private"

Categories

Resources