My code:
#client.command()
async def suggest(ctx, suggestion):
embed = discord.Embed(
title = "New suggestion.",
description = f"{suggestion}",
color = 0,
timestamp = ctx.message.created_at
)
embed.set_footer(text='Requested by {} | ID-{}' .format(ctx.message.author, ctx.message.author.id))
await ctx.guild.owner.send(embed=embed)
await ctx.send("Suggestion sent to server owner.")
Problem with this command is that bot does not read the whole message, it reads only first word of it.
For example I send this message: =suggest this is suggestion And bot sends embed to a owner only with the first word in this case it will send embed with only this and not whole sentence. If it is possible, how?
You can pass the keyword-only argument
async def suggest(ctx, *, suggestion):
Take a look at the introduction
Related
I'm trying to have a single embed that is going to be used as a list of some sort. I would like for an add_field to be added when a command is pushed to the bot. For example, I want to add to this current embed a new line with embed.add_field(name, value) that is given by a user when activated. How would I go about this? I've tried using message ID and message content but I don't think this is the best method. Thanks in advance.
#bot.command()
async def mangaEmbed(ctx):
embed = discord.Embed(
title = "Completed Self Prints",
#description ="test",
color = discord.Color.blue()
)
#embed.set_footer(text="Footer")
#embed.set_image(url="https://media.discordapp.net/attachments/138231921925816320/902586759773306900/unknown.png?width=810&height=375")
#embed.set_thumbnail(url="https://media.discordapp.net/attachments/138231921925816320/902586759773306900/unknown.png?width=810&height=375")
#embed.set_author(name= "Kyle G", icon_url="https://media.discordapp.net/attachments/138231921925816320/902586759773306900/unknown.png?width=810&height=375")
embed.add_field(name="Kokou no Hito by NggKGG", value="Volumes 1-17", inline=False)
embed.add_field(name="DrangonBall Z\nby NggKGG", value="Kokoue no 222o", inline=False)
embed.add_field(name="Homoculus", value="Volumes 1-24\nManmangaboy", inline=False)
await ctx.send(embed=embed)
The new problem is not being able to pass the discord.Message using the message id
#bot.command()
async def editembed(ctx, vols, *, title):
#just assuming you only want to get the first embed in the message
message = discord.Message(903060490035556383)
print(message)
embed = message.embeds[0]
embed.add_field(name=title, value=vols, inline=False)
await message.edit(embed=embed)
If I understood your question correctly, you want to edit an already sent embed from a different command right?
message has the attribute embeds, which will return a list of embeds the message has. You can use that to get the embed you want and edit it in a separate command.
Something like this should work:
#bot.command()
async def editembed(ctx, message: discord.Message):
#just assuming you only want to get the first embed in the message
embed = message.embeds[0]
embed.add_field(name="test", value="test")
await message.edit(embed=embed)
https://discordpy.readthedocs.io/en/master/api.html?highlight=message#discord.Message.embeds
Edit:
Regarding your second question:
You would have to get your message from somewhere, if it is always the same embed that you want to edit you can just define it inside your command using fetch_message. There are 2 ways to do this, either you would have to also get the channel the message you wanna edit is in, or just use ctx but then you can only use this command in the same channel as the embed that you want to edit.
Option 1 (recommended):
#bot.command()
async def editembed(ctx):
channel = bot.get_channel(1234567890)
message = await channel.fetch_message(1234567890)
Option 2:
#bot.command()
async def editembed(ctx):
message = await ctx.fetch_message(1234567890)
Please keep in mind that embeds can only have 25 fields in them though.
I'm quite new to discord.py so I'm posting this here. How do I make a command so that when the user says !embed (message here) #channelhere it turns the users message into an embed and then posts it into the specified channel? An explanation would be nice to so I can try to understand it.
Based on the 2 answers I see, you can send an embed to a specific channel whatever you want by converting the channel into the channel id.
Here's the code :
#client.command()
async def echoembed(ctx, channel : discord.TextChannel, *, Text : str): # full command (!echoembed #channelhere Title here | Description here)
Title, Description = Text.split(' | ') # You need to split the arguments using |, change to other symbols whatever you want
channel_id = channel.id # this will convert the channel name into the channel id
channel_send = client.get_channel(channel_id) # we will get the channel using the channel id
embed = discord.Embed(title = Title, description = Description, color = 0x2F3136)
embed.timestamp = datetime.datetime.utcnow() # this will tell the time today
embed.set_footer(text = "\u200b", icon_url = ctx.author.avatar_url) # the \u200b is an empty character
await channel_send.send(embed = embed) # and finally, we can send the embed
If you're fairly new to discord.py, I suggest you need to read the docs before going into complicated stuff.
The docs will be linked Here
Thank me later :D
Sample code I have:
Eg: I enter !embed hello / wow
#bot.command() #used before a command
async def embed(ctx, *, content: str): #when the person uses !embed it will do what is under. Ctx is needed to store the channel of the message, author of message and other properties. content is the argument, or what you put after the !embed (in this case hello / wow)- we state that it is a string(str) or plain text if that is more clear
title, description= content.split('/') #the title and description of the embed are separated by "/" In this cas, title is "hello",description is "wow"
embed = discord.Embed(title=title, description=description, color=0x00ff40) #making the embed (MUST HAVE TITLE AND DESCRIPTION)
await ctx.send(embed=embed) #sending the embed in THE SAME CHANNEL YOU SENT THE COMMAND IN (as shown via ctx)
await ctx.message.delete() #deleting the original message by you to clean the channel up(as shown by ctx.message)
In terms of specific channel that might be a bit more complicated: however this should work perfectly
Basiclly you have to create a variable called channel that contains the channel ID, for example: channel = bot.get_channel(636399538650742795). Then you create a command that takes an argument, this argument is the message to be embeded, you store the argument in a variable, make a variable called embed, this variable will be embed = discord.Embed(value=argument), wich we will send with await channel.send(embed=embed). The actual code looks like this:
#bot.command()
async def embed(ctx, argument: str):
channel = bot.get_channel(636399538650742795)
embed = discord.Embed()
embed.add_field(name="Message", value=argument)
await channel.send(embed=embed)
To get the channel ID, just right click the channel you want to get the ID of and click Copy ID. And considering that you're very new to discord.py, I am using #bot.command() because I am defining it with bot = commands.Bot(command_prefix="$")
The way im programming the bot im not sure how to make the messages send as embed via messages from discord. i can make it send normal messages but embeds wont work idk what im doing wrong. im kinda new so!
#szn.event
async def on_message(message):
if message.content == 'info':
general_channel = szn.get_channel()
myEmbed = discord.Embed(tiitle="test", description="", color="")
myEmbed.add_field()
myEmbed.set_footer()
await general_channel.send(embed=myEmbed)
this is my code
Things to Note:
get_channel() requires an ID as the argument
add_field() requires name and value
set_footer() requires atleast text
Revised code:
# CHANNEL_ID is the id of the channel you want to send message to
#szn.event
async def on_message(message):
if message.content == 'info':
general_channel = szn.get_channel(CHANNEL_ID)
myEmbed = discord.Embed(title="test")
myEmbed.add_field(name="Field 1", value="Value 1")
myEmbed.set_footer(text="Footer")
await general_channel.send(embed=myEmbed)
Something to note is that if you're getting the channel that the message was sent in you can do 'message.channel'
async def on_message(message):
if message.content == 'info':
myEmbed.title = "[insert the title of the embed]"
myEmbed.description = '[insert the description of the embed]'
myEmbed.color = 0xfc0303 [hex color, you can search up hex colors and then put '0x' in front of it] #this is optional
myEmbed.set_footer(text = "[text]") #also optional
myEmbed.set_image(url = "[image URL]") #again, optional
await message.channel.send(embed=myEmbed)
There's probably more stuff to the embed that you can do that I don't know, but those should be easy to look up
So I'm in discord.py right now, and whenever I directly edit bot.py (my main file) I can implement a version of my suggest command.
#bot.command(name = 'suggest', help = 'Use this command to give a suggestion to the server')
async def suggest(ctx, content):
channel = discord.utils.get(bot.guilds[0].channels, name = 'suggestions')
print('Suggest command triggered, content is {}'.format(content))
await channel.send(content)
^ bot is just my version of client
This works perfectly fine (except the fact that I only get the 1st word of content, so if someone could solve that, that would also be nice
But when I copy paste into my cog
#commands.command(name = 'suggest', help = 'Use this command to give a suggestion to the server')
async def suggest(self, bot, ctx, content):
print('Suggest command triggered')
channel = discord.utils.get(bot.guilds[0].channels, name = 'suggestions')
print('Content is {}'.format(content))
await channel.send(content)
It doesn't work, can someone help me?
For a cog, that bot parameter is unnecessary, so you just put
#commands.command(name = 'suggest', help = 'Use this command to give a suggestion to the server')
async def suggest(self, ctx, content):
print('Suggest command triggered')
channel = discord.utils.get(bot.guilds[0].channels, name = 'suggestions')
print('Content is {}'.format(content))
await channel.send(content)
As for the only having the first word, discord.py separates arguments by words, so you can just group them all with a * like so:
async def suggest(self, ctx, *content): # gets all the words in a tuple
I've been trying to send the same message to all the guilds where my bot is, but nothing has worked and I haven't been able to find something similar in the docs. Is this posible? How can I do It?
Edit: ok, lets's imagine that what my bot does is checking a news webpage like BBC or any other. The bot would be checking the web every five minutes and sending links of the news to those guilds where .start (for example) was executed. The way I've implemented this, was by a command that generates a single loop for each guild, the idea was to have just one loop for every guild.
for guild in bot.guilds:
await guild.text_channels[0].send(<message>)
This will get the first text channel found in the guild and send a message to it.
You can get the bot from a context variable by typing ctx.bot.
class send_all(commands.Cog):
def __init__(self,bot):
self.bot = bot
#commands.command()
async def send(self,ctx,*message_to_send):
guild = ctx.message.guild
output = ' '
author = ctx.message.author
for word in message_to_send:
output += word
output += ' '
for member in self.bot.get_all_members():
try:
embed = discord.Embed(title="",colour = discord.Colour.green())
embed.add_field(name="**From server:**",value= guild.name)
embed.add_field(name = "**From Mod/Admin:**",value = author.name)
embed.add_field(name="**Message:**",value = output)
# await ctx.send(embed=embed)
await member.send(embed=embed)
except (discord.HTTPException, discord.Forbidden,AttributeError):
continue