How to copy an embed in discord.py? - python

I want the bot fetch a message(embed) and send it to channel where command is invoked.
Following code works fine for normal text message:
#bot.command()
async def fetch(ctx):
channel = bot.get_channel(736984092368830468)
msg = await channel.fetch_message(752779298439430164)
await ctx.send(msg.content)
For sending embeds I tried:
#bot.command()
async def fetch(ctx):
channel = bot.get_channel(736984092368830468)
msg = await channel.fetch_message(752779298439430164)
await ctx.send(msg.embeds.copy())
It sends this instead of sending embed:
How do I make the bot copy and send embed?

The problem is that you are trying to send a list of discord.Embed objects as a string in your await ctx.send(msg.embeds.copy())
The ctx.send() method has a parameter called embed to send embeds in a message.
await ctx.send(embed=msg.embeds[0])
Should do the trick. This way you are sending an actual discord.Embed object, instead of a list of discord.Embeds
You should not need the .copy() method in
await ctx.send(embed=msg.embeds[0].copy())
although you can use it
The only downside of using the index operator [0] is that you can only access one embed contained in your message. The discord API does not provide a way to send multiple embeds in a single message. (see this question).
A workaround could be iterating over every embed in the msg.embeds list and send a message for every embed.
for embed in msg.embeds:
await ctx.send(embed=embed)
This unfortunately results in multiple messages being sent by the bot, but you don't really notice.

You have to select the first embed like this and use [copy] if you want to change into it before sending again.(https://discordpy.readthedocs.io/en/latest/api.html?highlight=embed#discord.Embed.copy)
#bot.command()
async def fetch(ctx):
channel = bot.get_channel(736984092368830468)
msg = await channel.fetch_message(752779298439430164)
await ctx.send(embed=msg.embeds[0])

Related

Get message from RawReactionActionEvent (discord.py)

How can I get the message a reaction is used on? I know you can get the message with context, but how can I use the attributes
channel_id guild_id and message_id
to get the original message? This seems like enough information
I have tried using client.http.edit_message and client.http.delete_message which seems to work until using an embed. Whenever used, TypeError: Object of type Embed is not JSON serializable is raised
There are multiple ways of doing this:
Independent of the bot's cache, requires more API calls:
async def fetch_message(payload):
channel = await bot.fetch_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
return message
Depends on bot's cache, requires less API calls:
async def get_message(payload):
channel = bot.get_channel(payload.channel_id)
message = await bot.fetch_message(payload.message_id)
return message

how to send albums as new messages in telethon

I want to send every new message from one channel to another.
But when there are albums in the message, they are sent separately to the destination channel.
How can I send them as an album (as one message)?
#client.on(events.NewMessage('your_channel'))
async def my_event_handler(event):
await client.send_message('my_channel', event.message)
And I used events.album instead of events.NewMessage, but it didn't work!
I find a simple way, maybe someone will use it
#client.on(events.Album(chats="your_channel"))
async def handler(event):
await client.send_message(
"my_channel", #output channel
file=event.messages, #list of messages
message=event.original_update.message.message, #caption
)

Make bot output embeded (discord.py)

So i am making a discord bot and i wrote a SAY command that outputs whatever you say,
import discord
from discord.ext import commands
#client.command()
async def say(ctx, *, message):
await ctx.message.delete() # Deletes last command
await ctx.send(f"{message}" .format(message)) # Send text from command
command .say TEXT
This will output that text as a message from the bot, instead of doing it as a normal message i need this to be a embed
You need to explicitly tell your bot to use an embed, per default it will always send a regular message. Something like the below will output an embed instead of a text message
#client.command()
async def say(ctx, *, message):
await ctx.message.delete() # Deletes last command
await ctx.send(embed=discord.Embed(description=message))
Check the documentation for more information on styling options for the embed (e.g. color, author info etc)
You should create a discord.Embed instance and pass it as embed param in the send function. And f-strings already format the string. If you add an f in front of the quotes, you won't need .format() Like that:
#client.command()
async def say(ctx, *, message):
await ctx.message.delete() # Deletes last command
myEmbed = discord.Embed(description=f"{message}")
await ctx.send(embed=myEmbed)
Embeds are not limited to descriptions, you can also add titles, fields, footers, images, thumbnails, etc.
If you want to learn about the embeds' potentials, you can look at discord.py docs about embeds.

discord.py - Send messages though console

ok, I wanted so I could send messages in an specific server and channel form the console. I seen on other post how to send messages on specific servers and channels but theyr from the discord app and not console. Can someone help me?
I wanted so I type msg [server-id-here] [channel-name] [message] for example
msg 493121776402825219 general hello
Code I have but it has errors
#bot.event
async def on_ready(ch, *, msg):
while msg:
channel = bot.get_channel(ch)
msg=input("Mensagem: ")
if channel:
await bot.send_message(channel, msg)
else:
await bot.say("I can't find that channel")
Error that outputs
TypeError: on_message() missing 1 required positional argument: 'ch'
I don't this this is actually possible, however you can implement a new command to do it, heres the one I used for welcomer
#bot.command(description="Echos, developers only", pass_context=True)
async def echo(ctx, echowords:str):
if ctx.message.author.id in []: #put in id's in a list or replace it with one string
await bot.say(echowords)
else:
await bot.say("Bot developers only :<")
This makes the bot repeat what you said where you said it, but if you want to send messages to a specific channel by ID you can do this
#bot.command(description="Echos, developers only", pass_context=True)
async def echo(ctx, id, echowords:str):
if ctx.message.author.id in []: #put in id's in a list or replace it with one string
sendchannel = bot.get_channel(id)
await bot.send_message(sendchannel, echowords)
else:
await bot.say("Bot developers only :<")
Use the say command.
#bot.command()
async def say(ctx, *,message):
if not ctx.author.bot:
else:
pass

How do I make my discord.py bot use custom emoji?

How can I make my bot use my custom emoji in any discord server?
#bot.command(pass_context=True)
async def ping(ctx):
msg = "Pong :CustomEmoji: {0.author.mention}".format(ctx.message)
await bot.say(msg)
Example:
If I upload some custom emojis on Server 1 and when we use the !ping command (mentioned above) in Server 2 or Server 3 or any server where the bot has access to, it should use the custom emoji.
Result: Pong with :CustomEmoji:
From https://github.com/Rapptz/discord.py/issues/390:
It's <:emoji_name:emoji_id> for custom emojis.
You can also find the discord.Emoji instance through Server.emojis and
then cast it to str.
Also for animated ones you do <a:emoji_name:emoji_id>
As we know, every discord bot has nitro privileges when it comes to using emotes. So a bot can access any emoji for all servers it has been added to. What I do is make an API converter for myself with a global emote dictionary.
emojis=None
#bot.command(pass_context=True)
async def ping(ctx):
global emojis
if not emojis:
emojis = {e.name:str(e) for e in ctx.bot.emojis}
msg = "Pong :CustomEmoji: {0.author.mention}".format(ctx.message).replace(':CustomEmoji:',emojis['CustomEmoji'])
await ctx.send(msg)
#bot.event
async def on_reaction_add(reaction, user):
if reaction.emoji.id == emoji_id:
await reaction.message.delete()
IMPORTANT: Change the emoji_id, It deletes the message

Categories

Resources