How do I make my bot reply with what the user sent? - discord.py

I'm making a giveaway bot and I cant get my bot to put what the user said into a field. For example, the bot says, "what do you want to giveaway?" then the user replies with something then the bot puts that "something" into its next reply.

take this simple bot
import discord
from bot import search_result, get_recent_query
class MyClient(discord.Client):
async def on_ready(self):
"""
showing message on console when the server start
:return:
"""
print('Logged on as {0}!'.format(self.user))
async def on_message(self, message):
# event listener, where sending message is a event
# we do not want the bot to reply to itself
if message.author == client.user:
return
print('Message from {0.author}: {0.content}'.format(message))
# checking the conditions, with which the user input starts
# if user input is hi, return hey
if message.content.startswith('hi'):
msg = 'hey {0.author.mention} '.format(message)
await message.channel.send(msg)
get the user reply from async def on_message(self, message) here message is what user reply and send the processed data to user as await message.channel.send(new_msg)

Related

How to have cog listener called before cog command

I have some code for a cog that looks something like this:
class Example(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.counter = 0
#commands.Cog.listener()
async def on_message(self, message):
print("Listener triggered")
self.counter += 1
#commands.group()
async def first(self, ctx):
if ctx.invoked_subcommand is None:
await ctx.send("Invalid subcommand")
#first.command()
async def second(self, ctx):
print("Command triggered")
await ctx.send(f"Current counter: {self.counter}")
When I run this code and send a message to my bot, second gets called before on_message. I have some code in second that expects on_message to be executed first, but I can't figure out a good way to make this happen. Suggestions?
check wait_for event.
and I think you are trying to make a bot count the number of valid uses of command. To do this, try:
def check(message):
#here put ur condition for message is a valide command
await client.wait_for('message', check=check)

Editing a bot's message just like when you swipe a page, discord.py

I wanted to make a command that edits the bot's old message trought another command, example:
user: !cmds
bot: *commands list*
user: !next
bot: *edits old message into a new one*
I have tried many times to make it myself, but I failed all the times, can anyone help me?
How I tried to make it:
#client.command
async def test():
embed=discord.Embed(title="Page1")
await ctx.send(embed=embed)
#client.event
async def on_command(message):
embed2=discord.Embed(title="Page2")
await client.process_commands(message)
if message.content == '$next':
await message.edit(content=embed2)
The on_command event is called whenever a command is called, you didn't register a next command, that's one, second of all on_command doesn't take message argument, it takes the Context(ctx).
An idea to make what you're asking for is having a cog with an instance variable that references to the previous message, then edit it when the next command is called.
class SomeCog(commands.Cog):
def __init__(self, client):
self.client = client
self._previous_message = None
#commands.command()
async def test(self, ctx):
message = await ctx.send("I'll edit this message when you type `$next`")
self._previous_message = message
#commands.command()
async def next(self, ctx):
if self._previous_message is None: # Exiting if the `test` command wasn't called before, i.e the message is a NoneType
return await ctx.send("You need to invoke first `$test`")
await self._previous_message.edit(content="Edited the message")
client.add_cog(SomeCog(client))
I'm guessing you could do it with global or bot vars but this is the best way to do it, in my opinion.

Store the contents of a message which triggers a function

I don't know where to start like most things, but for example.
A user says "foo", the bot stores the message, and then says "bar". The closest I could get was this:
message = await channel.send('hmm…')
message_id = message.id
Though this stores the message sent by the bot, and not the user which triggered the function. It also doesn't store the message, just the ID. Please help.
Thanks in advance!
Edit: My goal is kinda like Sx4's suggest feature.
Hi :) not sure exactly what you want but seems like you are looking for the on message event? Here is an example. You should replace client with whatever you named your bot instance.
#client.event
async def on_message(message):
if message.author != client.user: # Avoids loops by checking that the message author is not the bot itself
# Code in here will run when a message is sent
await client.process_commands(message) # Runs all commands contained in the message
If you want to store every message, use something like this to set a variable that you can then do something with:
#client.event
async def on_message(message):
if message.author != client.user:
STORED_MESSAGE = message.content
# Do something with the variable here
await client.process_commands(message)
Or to respond to a message "foo" with "bar":
#client.event
async def on_message(message):
if message.author != client.user:
if message.content == "foo":
await message.channel.send("bar")
await client.process_commands(message)

on_message stops all of my bot.commands from working

I have a flip command that returns either heads or tails and it was working fine until I added the on_message function. I did some research on SO and read the documentation and here it says to include await bot.process_commands(message) in the on_message function but that did not solve the issue and the flip command still doesn't work. If I remove the on_message function everything works as expected.
bot.py
import discord
from discord.ext import commands
import random
# from app bot user
# click to reveal
TOKEN = 'token_here'
client = commands.Bot(command_prefix = '!')
#client.event
async def on_ready():
print('Bot ready')
#client.command()
async def flip():
flip = random.choice(['heads', 'tails'])
await client.say(flip)
#client.event
async def on_message(message):
if message.content.upper().startswith('N****'):
await client.send_message(message.channel, "Please do not use that word here.")
client.process_commands(message)
#client.event
async def on_member_join(member):
await client.change_presence(game=discord.Game(name='Hi %s' % (member)))
await client.send_message(member, "Hi %s, Welcome to Carson's Discord Server! This server is fairly NSFW at times; you've been warned! Enjoy your stay :)" % (member))
#client.event
async def on_member_remove(member):
await client.change_presence(game=discord.Game(name='Bye %s' % (member)))
client.run(TOKEN)
When I run the script, everything else works normally with no errors. It's just the commands that don't work. Any insight would be greatly appreciated.
You need to await the last line in on_message as process_commands is a coroutine.
await client.process_commands(message)
If you send !flip in discord, you should be able to receive the appropriate response (heads or tails).

How to make bot respond to a certain msg?

So, I've been trying to make my bot respond to a specific keyword however when I do this the bot either doesn't respond or gives me a bunch of errors. I've tried a few methods of doing this but I didn't have much luck. If anybody can make it work would be glad here are one of the methods I tried using.
if message.content == "keyword":
await client.send_message(message.channel, "Response {0.author.mention}")
You can do this one of two ways, either with the commands extension, or within the on_message event.
Below is an example of how you can do this. With this example, when a user types "!ping" the bot will respond with "Pong". If a message contains the word "foo", then the bot will respond with "bar".
from discord.ext import commands
client = commands.Bot(command_prefix='!')
#client.event
async def on_ready():
print('client ready')
#client.command()
async def ping():
await client.say('Pong')
#client.event
async def on_message(message):
if client.user.id != message.author.id:
if 'foo' in message.content:
await client.send_message(message.channel, 'bar')
await client.process_commands(message)
client.run('TOKEN')

Resources