Add reactions to embeds py-cord - python

Im making a discord bot and i decided to change from prefixed commands to slash command using pycord and my poll command it won't add the reaction it will just send the embed without the reactions
Here is my code:
import discord
import datetime
from discord.ext import commands
class Poll(commands.Cog):
def __init__(self, client):
self.client = client
#discord.slash_command(description = "Create a poll in the current channel")
#commands.has_permissions(manage_channels = True)
#commands.bot_has_permissions(manage_messages = True)
async def poll(self, ctx, *, question):
poll = discord.Embed(
title = "Poll",
description = f"{question}",
timestamp = datetime.datetime.utcnow(),
colour = 0xeeffee)
poll.add_field(name = "Usage:", value = "`✅ Yes | ❎ No`")
message = await ctx.respond(embed = poll)
await message.add_reaction("✅")
await message.add_reaction("❎")
def setup(client):
client.add_cog(Poll(client))
Before i decided to change to slash commands it worked perfectly fine
I don't know what is the problem and i can't find a solutions if it's something simple pls tell because i can't make it work

message = await ctx.respond(embed=poll)
msg = await message.original_response()
await msg.add_reaction("✅")
await msg.add_reaction("❎")
https://docs.pycord.dev/en/stable/api.html#discord.Interaction.original_response

Related

AttributeError: 'NoneType' object has no attribute 'edit'

I made a simple slash command for my discord bot using python, to show bot latency. However, it does not appear to be working. can you help me out? thanks a lot :D.
My code:
import time
import discord
from discord import app_commands
from discord.ext import commands
intents = discord.Intents.default()
client = discord.Client(intents=intents)
tree = app_commands.CommandTree(client)
prefix = "-"
bot = commands.Bot(command_prefix=prefix,intents=intents)
#client.event
async def on_ready():
await tree.sync(guild=discord.Object(id=ID))
print("Ready!")
#tree.command(name = "ping", description = "test command", guild=discord.Object(id=ID))
async def ping(Interaction):
before = time.monotonic()
message = await Interaction.response.send_message("pong")
ping = (time.monotonic() - before) * 1000
await message.edit(content=f"pong `{int(ping)}ms`") <-- here's the line that's causing the problem..
client.run('TOKEN')
I've been trying to find the issue on the Internet, and I haven't been able to find it. D:
I tried to fix it myself somehow, but I am new to coding with python and was not successful.
U cannot store the interaction like message = await Interaction.response.send_message("pong") and update it.
You can edit the interaction by using edit_original_message()
#tree.command(name = "ping", description = "test command", guild=discord.Object(id=ID))
async def ping(Interaction):
before = time.monotonic()
await Interaction.response.send_message("pong")
ping = (time.monotonic() - before) * 1000
await Interaction.edit_original_message(content=f"pong `{int(ping)}ms`")

How to make an argument on discord.py to be the last words

I am making a discord bot that one of the features is that you can use a command to make the bot embed thing into chat. This is the code:
import discord
from datetime import datetime
from discord.ext.commands import Bot
from discord.ext import commands
from discord.ext.commands import has_permissions
client = commands.Bot(command_prefix='=')
#client.command(pass_context=True)
async def embed(ctx, args):
await ctx.channel.purge(limit=1)
embed = discord.Embed(color=discord.Colour.red())
embed.set_author(name=args)
await ctx.send(embed=embed)
client.run('YOUR-TOKEN-GOES-HERE')
But when I try to embed more than one words it only embeds the last one. Why does it do that?
You need to add a * before the final argument to take in the full string like this:
async def embed(ctx, *, args):
So your function will look like this:
#client.command(pass_context = True)
async def embed(ctx, *, args):
await ctx.channel.purge(limit = 1)
embed = discord.Embed(color = discord.Colour.red())
embed.set_author(name = args)
await ctx.send(embed = embed)

How to make my custom discord bot sends message

Im trying to make my custom bot sends a custom message using python
Me: ~repeat Hi
My Message deleted
custom-Bot: Hi
whenever I try using this I get error problems with this code specifically "client"
await client.delete_message(ctx.message)
return await client.say(mesg)
from discord.ext import commands
client = commands.Bot(command_prefix = '~') #sets prefix
#client.command(pass_context = True)
async def repeat(ctx, *args):
mesg = ' '.join(args)
await client.delete_message(ctx.message)
return await client.say(mesg)
client.run('Token')
client does not have an attribute called delete_message, to delete the author's message use ctx.message.delete. To send a message in the rewrite branch of discord.py, you use await ctx.send()
#client.command()
async def repeat(ctx, *args):
await ctx.message.delete()
await ctx.send(' '.join(args))

use function name as a command

I have this function here that uses the folder name as a command. Right now the only folders are "hug" and "headpat". So when I send .hug or .headpat to Discord it will go into that folder, grab a random image and post it.
#client.event
async def on_message(message):
async def random_image(dir): #picks a random image from local directory
if message.content.lower() ==f".{dir}":
image = random.choice(os.listdir(dir))
embed = discord.Embed(color = 0xff9e00)
chosen_one = discord.File(f"{dir}\\{image}", filename = image)
embed.set_image(url = f"attachment://{image}")
await message.channel.send (embed = embed, file = chosen_one)
print(f"{image} sent in response to {(message.author)}.")
print(f"----------")
However, I would like to be able to do something like as follows, but I am not sure where to start.
#bot.command()
async def folder_name(ctx):
#code that does the same as the function above
By default with the commands extension, the function's name is the command name. However, the #commands.command decorator have a aliases argument that you can use along with Context.invoked_with:
#bot.command(aliases=['hug', 'headpat'])
async def folder_name(ctx):
image = random.choice(os.listdir(ctx.invoked_with))
embed = discord.Embed(color = 0xff9e00)
chosen_one = discord.File(f"{dir}\\{image}", filename=image)
embed.set_image(url = f"attachment://{image}")
await ctx.send (embed = embed, file=chosen_one)
print(f"{image} sent in response to {ctx.author}.")
print(f"----------")
Note that if someone types !folder_name, the command will execute so you'll have to add a check like this:
if ctx.invoked_with == ctx.command.name:
#Do stuff
Here is a simple bot that implements your code as a command.
import discord
from discord.ext import commands
TOKEN = "your token"
PREFIXES = ['.']
bot = commands.Bot(command_prefix=PREFIXES)
#bot.command(name='image')
async def random_image(ctx, dir):
image = random.choice(os.listdir(dir))
embed = discord.Embed(color = 0xff9e00)
chosen_one = discord.File(f"{dir}\\{image}", filename = image)
embed.set_image(url = f"attachment://{image}")
await ctx.send (embed = embed, file = chosen_one)
print(f"{image} sent in response to {(message.author)}.")
print(f"----------")
#bot.event
async def on_ready():
print(f"Logged in as {bot.user.name} in {len(bot.guilds)} guilds!")
#bot.event
async def on_message(message):
if message.author.bot: # I always do this to make sure it isn't a bot
return
await bot.process_commands(message)
if __name__ == '__main__':
try:
bot.run(TOKEN)
finally:
print("Logging Out")
I'd actually recommend using links instead of files/folders for their unreliable and often produce problems and bugs in your code and they just don't work very well with discord.py.
Here's an example of your desired command.
import discord
from discord.ext import commands
from discord import Embed
import random
client = commands.Bot(command_prefix=".")
headpat_image_links = ['https://media.tenor.com/images/ad8357e58d35c1d63b570ab7e587f212/tenor.gif', 'https://image.myanimelist.net/ui/xUjg9eFRCjwANWb4t4P8QbyfbVhnxa2QGYxoE7Brq1sHDVak6YxhLP3ZbNkkHm6GX9x8FWB1tWCapNyEqSltXa8wxAdwIERdrHGhYPilHJ8']
secret_headpat = random.choice(headpat_image_links)
#client.command()
async def headpat(ctx):
e=Embed(title="Headpats!", description="whatever description you want")
e.set_image(url=secret_headpat)
await ctx.send(embed=e, content=None)
client.run('TOKEN')
I've checked it and it works like a charm ;)
It's the same concept for the hug command. Just choose a random link to embed :)
PS:
Make sure you don't use any imgur links, imgur's API and links has been on the fritz and no longer works with discord.py. Well, it no longer works with embedded messages. Just don't use it. :>

How do I set a required role for a command?

I'm trying to make my Discord bot require a rank to execute the Say command but I cannot find a way to make it work. I would like to ask you guys if you could help me setup a role required to execute the command.
import asyncio
import discord
from discord.ext.commands import Bot
bot = Bot('>') # the <#4> is essential so people cannot share it via DMs.
#bot.command(pass_context = True)
async def Say(ctx, *args):
mesg = ' '.join(args)
await bot.delete_message(ctx.message)
return await bot.say(mesg)
bot.run('Token')
Discord.py provides a simple decorator commands.has_role that is used for verifying roles by name. The has_role utilise the check function and both functions are part of the undocumented commands extension.
from discord.ext import commands
bot = commands.Bot('>')
#bot.command(pass_context = True)
#commands.has_role('admin')
async def Say(ctx, *args):
mesg = ' '.join(args)
await bot.delete_message(ctx.message)
return await bot.say(mesg)
bot.run('Token')

Categories

Resources