discord.py command that create embed - python

im trying to code a discord.py bot where you can create embeds through a command, something like the embed creation function in mimu bot. i tried to code it but it dont work, any ways to make it work?
async def embed_create(ctx):
def check(message):
return message.author == ctx.author and message.channel == ctx.channel
await ctx.send('Enter your title.\nPut `none` if you do not want anything in this section.')
await client.wait_for("message", timeout = 300.0, check=check)
if message.content == "none":
title = ""
else:
title = ("message")
await ctx.send('Enter your title.\nPut `none` if you do not want anything in this section.')
await client.wait_for("message", timeout = 300.0, check=check)
if message.content == "none":
desc = ""
else:
desc = ("message")
embed = discord.Embed(title=title.content, description=desc.content, color=0xa9e9e9```

I figured out the problem and fixed it, here:
async def embed_create(ctx):
def check(message):
return message.author == ctx.author and message.channel == ctx.channel
await ctx.send('Enter your title.\nPut `none` if you do not want anything in this section.')
title = await client.wait_for("message", timeout = 300.0, check=check)
title = title.content
if title == "none":
title = "** **" # it will still be empty but not give an empty error message
else:
title = title
await ctx.send('Enter your title.\nPut `none` if you do not want anything in this section.')
desc = await client.wait_for("message", timeout = 300.0, check=check)
desc = desc.content
if desc == "none":
desc = "** **"
else:
desc = desc
embed = discord.Embed(title=title, description=desc, color=0xa9e9e9)
await ctx.send(embed=embed)

Related

bot executes next command without waiting for message

Hello I have been trying to create a application bot for my server the bot sends you a questions then the person answers then its noted down ect but my problem is that sometimes the next question would send without waiting for the answer to the previous question. this only happens most of the time. try i might i have not been able to fix the problem. I’m pretty new to python and at the end of my wits.
my code for reference:
import os
from discord.ext import commands
from discord.utils import get
BOT_PREFIX = ("!")
client = commands.Bot(command_prefix=BOT_PREFIX)
a_list = []
#client.event
async def on_ready():
print ("------------------------------------")
print ("Bot Name: " + client.user.name)
print ("------------------------------------")
submit_wait = False
a_list = []
b_list = []
c_list = []
d_list = []
#client.command(aliases=['application'])
async def app(ctx):
a_list = []
b_list = []
c_list = []
d_list = []
submit_wait = False
submit_channel = client.get_channel(806404345830047744)
channel = await ctx.author.create_dm()
await channel.send("starting applaction!")
await ctx.send(ctx.author.mention + "check your dms!")
time.sleep(2)
def check(m):
return m.content is not None and m.channel == channel
await channel.send("Do you have any prior milli sim experiance?")
msg = await client.wait_for('message', check=check)
a_list.append(msg.content)
await channel.send("What time zone are you in?")
msg2 = await client.wait_for('message', check=check)
b_list.append(msg2.content)
await channel.send("If a officer ordered you to break the genva convention would you do it?")
msg3 = await client.wait_for('message', check=check)
c_list.append(msg3.content)
await channel.send("Is there any particular dvision you want to be in?")
msg4 = await client.wait_for('message', check=check)
d_list.append(msg4.content)
await channel.send('thank you for applying! a officer will do your application as soon as they can - respound with "submit" to submit your application')
msg = await client.wait_for('message', check=check)
if "submit" in msg.content.lower():
submit_wait = False
answers = "\n".join(f'{a}. {b}' for a, b in enumerate(a_list, 1))
answer = "\n".join(f'{a}. {b}' for a, b in enumerate(b_list, 2))
answerr = "\n".join(f'{a}. {b}' for a, b in enumerate(c_list, 3))
answerss = "\n".join(f'{a}. {b}' for a, b in enumerate(d_list, 4))
submit_msg = f'Application from {msg.author} \nThe answers are:\n{answers}'
submit_msg2 = f'{answer}'
submit_msg3 = f'{answerr}'
submit_msg4 = f'{answerss}'
await submit_channel.send(submit_msg)
await submit_channel.send(submit_msg2)
await submit_channel.send(submit_msg3)
await submit_channel.send(submit_msg4)
client.run(os.getenv('TOKEN'))
I tested code using print() and I think problem is because check() sometimes gets bot's question and it treats it as user's answer.
You have to check m.author in check() - something like this
#client.command(aliases=['application'])
async def app(ctx):
submit_channel = client.get_channel(806404345830047744)
#print('submit_channel:', submit_channel)
channel = await ctx.author.create_dm()
author = ctx.author
def check(m):
#print('m.author:', m.author)
#print('m.content:', m.content)
#print('m.channel:', m.channel, m.channel == channel)
return m.author == author and m.content and m.channel == channel
Minimal working code with other changes
import os
import time
from discord.ext import commands
client = commands.Bot(command_prefix="!")
#client.event
async def on_ready():
print ("------------------------------------")
print ("Bot Name:", client.user.name)
print ("------------------------------------")
#client.command(aliases=['application'])
async def app(ctx):
submit_channel = client.get_channel(806404345830047744)
print('submit_channel:', submit_channel)
channel = await ctx.author.create_dm()
author = ctx.author
def check(m):
print('m.author:', m.author)
print('m.content:', m.content)
print('m.channel:', m.channel, m.channel == channel)
return m.author == author and m.content and m.channel == channel
await channel.send("starting applaction!")
await ctx.send(ctx.author.mention + " check your dms!")
time.sleep(2)
await channel.send("Do you have any prior milli sim experiance?")
answer_a = await client.wait_for('message', check=check)
answer_a = answer_a.content
await channel.send("What time zone are you in?")
answer_b = await client.wait_for('message', check=check)
answer_b = answer_b.content
await channel.send("If a officer ordered you to break the genva convention would you do it?")
answer_c = await client.wait_for('message', check=check)
answer_c = answer_c.content
await channel.send("Is there any particular dvision you want to be in?")
answer_d = await client.wait_for('message', check=check)
answer_d = answer_d.content
await channel.send('thank you for applying! a officer will do your application as soon as they can - respound with "submit" to submit your application')
msg = await client.wait_for('message', check=check)
if "submit" in msg.content.lower():
submit_msg = f'''Application from {msg.author}
The answers are:
1. {answer_a}
2. {answer_b}
3. {answer_c}
4. {answer_d}'''
await submit_channel.send(submit_msg)
client.run(os.getenv('TOKEN'))
Ok so at first glance I'm picking up a few errors
Firstly, minor issue, but using time.sleep(2) will pause your entire bot, so if you want to let other people to run this command at the same time you may want to change this
import asyncio # instead of import time
await asyncio.sleep(2) # instead of time.sleep(2)
Also you needn't repeat so much code, this should make it work exactly how you want it to
import os
from discord.ext import commands
from discord.utils import get
import asyncio
client = commands.Bot(command_prefix="!")
#client.event
async def on_ready():
print ("------------------------------------")
print ("Bot Name: " + client.user.name)
print ("------------------------------------")
submit_wait = False
questions = ["Do you have any prior milli sim experiance?",
"What time zone are you in?",
"If a officer ordered you to break the genva convention would you do it?",
"Is there any particular dvision you want to be in?"]
#client.command(aliases=['application'])
async def app(ctx):
submit_channel = client.get_channel(810118639234973719)
channel = await ctx.author.create_dm()
await channel.send("starting applaction!")
await ctx.send(ctx.author.mention + "check your dms!")
await asyncio.sleep(2)
def check(m):
return m.content != "" and m.channel == channel
answers = []
for question in questions:
await channel.send(question)
msg = await client.wait_for("message", check=check)
answers.append(msg.content)
await channel.send('thank you for applying! a officer will do your application as soon as they can - respound with "submit" to submit your application')
msg = await client.wait_for("message", check=check)
if "submit" in msg.content.lower():
submit_wait = False
answers = [f"{no+1}. {ans}" for no, ans in enumerate(answers)]
submit_msg = [f"Application from {msg.author}",
"The answers are:", *answers]
await submit_channel.send("\n".join(submit_msg))
client.run(os.getenv('TOKEN'))

Cannot Check Reaction In Discord.py

So basically i was making a modmail system and the problem was we wanted the person who dmed the bot has to react to ✅ if he reacts then the bot has to reply him "OK"
but the code was not working so what is the problem how to fix it?
import discord
import asyncio
client = discord.Client()
#client.event
async def on_message(message):
# empty_array = []
# modmail_channel = discord.utils.get(client.get_all_channels(), name="mod-mail")
if message.author == client.user:
return
if str(message.channel.type) == "private":
embed = discord.Embed(title='Confirmation',
color=0x03d692)
embed.add_field(name="You're sending this message to **The Dynamic Legends**", value="React with :white_check_mark: to confirm." + "\nTo cancel this request, react with :x:.", inline=False)
confirmation_msg = await message.author.send(embed=embed)
await confirmation_msg.add_reaction('✅')
await confirmation_msg.add_reaction('❌')
sent_users = []
sent_users.append(message.author.name)
try:
print('Working')
def check1(reaction, user):
return user == client.user and user!='Mod Mail Humara#5439' and str(reaction.emoji) == '✅'
reaction, user = await client.wait_for("reaction_add", timeout=30.0, check=check1)
# print(reaction, user)
if str(reaction.emoji) == '✅':
message.author.send('yes)
client.run('TOKEN')
There's a logic problem in the check func
return user == client.user
It simply doesn't make sense, instead of == use != and don't put the user!='Mod Mail Humara#5439' part
Your check func fixed:
def check1(reaction, user):
return user != client.user and str(reaction.emoji) == '✅'
Also message.author.send is a coroutine, so you need to await it
await message.author.send("whatever")
Your code:
#client.event
async def on_message(message):
if message.author == client.user:
return
if isinstance(message.channel, discord.DMChannel):
embed = discord.Embed(title='Confirmation', color=0x03d692)
embed.add_field(name="You're sending this message to **The Dynamic Legends**", value="React with :white_check_mark: to confirm." + "\nTo cancel this request, react with :x:.", inline=False)
confirmation_msg = await message.author.send(embed=embed)
await confirmation_msg.add_reaction('✅')
await confirmation_msg.add_reaction('❌')
sent_users = []
sent_users.append(message.author.name)
try:
def check1(reaction, user):
return user != client.user and str(reaction.emoji) == '✅'
reaction, user = await client.wait_for("reaction_add", timeout=30.0, check=check1)
if str(reaction.emoji) == '✅':
await message.author.send('yes')
except Exception as e:
pass

Discord py - if emoji in new created channel - delete the channel

Hey guys!
I am trying to make a litte ticket-bot for my server - the problem is that the emoji in the reaction deletes a channel!
So if a member uses the emoji outside the new created channel it will delete the channel :(
What does my code look like now:
#commands.Cog.listener()
async def on_raw_reaction_add(self, payload):
guild_id = payload.guild_id
guild = self.client.get_guild(guild_id)
user_id = payload.user_id
user = self.client.get_user(payload.user_id)
message_id = payload.message_id
emoji = payload.emoji.name
if message_id == 768765161301213185 and emoji == "📩":
member = discord.utils.find(lambda m : m.id == payload.user_id, guild.members)
support_role = guild.get_role(760792953718308915)
category = guild.get_channel(768764177736400906)
overwrites = {
guild.default_role: discord.PermissionOverwrite(read_messages=False),
member: discord.PermissionOverwrite(read_messages=True, send_messages=True),
support_role: discord.PermissionOverwrite(read_messages=True, send_messages=True)
}
ticket_nr = random.randint(100,999)
channel = await category.create_text_channel(f'ticket-{ticket_nr}', overwrites=overwrites)
embed = discord.Embed(
title="How can I help you?",
description="Please wait for a supporter.")
embed.set_author(name="TiLiKas Ticket Bot")
for channel_all in guild.text_channels:
if str(channel_all) == str(channel):
if user_id != 739740219544305714 and emoji == "🔒":
await channel.delete(reason=None)
else:
print("ERROR")
What do I want?
I want the bot only to responde on the emoji if its used in the new created channel!
https://discordpy.readthedocs.io/en/latest/ext/commands/api.html?highlight=check#discord.ext.commands.Bot.wait_for
#client.event
async def on_message(message):
if message.content.startswith('$thumb'):
channel = message.channel
await channel.send('Send me that 👍 reaction, mate')
def check(reaction, user):
return user == message.author and str(reaction.emoji) == '👍'
try:
reaction, user = await client.wait_for('reaction_add', timeout=60.0, check=check)
except asyncio.TimeoutError:
await channel.send('👎')
else:
await channel.send('👍')
Your check method should look something like:
def check(reaction, user):
return user == message.author and str(reaction.emoji) == '👍' and reaction.message.channel == message.channel
This check here, checks:
the user who is reacting to the message is the same user who started the command.
the reaction is a thumbs up emoji.
the reaction is done in the same channel the command was started in.

How to fetch and edit embeds in discord.py?

I want the bot to fetch embeds and scroll between them . Here is what I tried doing:
#commands.command()
async def test(self,ctx):
chan = self.bot.get_channel(746339276983238677)
message1 = await chan.fetch_message(761267709438328904)
message2 = await chan.fetch_message(761267744721076265)
message3 = await chan.fetch_message(761267778639495168)
page1= message1.embeds[0]
page2= message2.embeds[0]
page3= message3.embeds[0]
contents = [page1,page2,page3]
pages = 3
cur_page = 1
message = await ctx.send(f"Page {cur_page}/{pages}:\n{contents[cur_page-1]}")
await message.add_reaction("◀️")
await message.add_reaction("▶️")
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) in ["◀️", "▶️"]
while True:
try:
reaction, user = await self.bot.wait_for("reaction_add", timeout=60, check=check)
if str(reaction.emoji) == "▶️" and cur_page != pages:
cur_page += 1
await message.edit(content=f"Page {cur_page}/{pages}:\n{contents[cur_page-1]}")
await message.remove_reaction(reaction, user)
elif str(reaction.emoji) == "◀️" and cur_page > 1:
cur_page -= 1
await message.edit(content=f"Page {cur_page}/{pages}:\n{contents[cur_page-1]}")
await message.remove_reaction(reaction, user)
else:
await message.remove_reaction(reaction, user)
except asyncio.TimeoutError:
await message.delete()
break
It doesn't send the embeds. it sends this:
How do I fetch embeds and send them and then how to I edit them?
In order to send an embed, you're supposed to use
await ctx.send(embed=embed_variable)
attaching it to the message. You're sending the actual embed instance where it expects a string. So in your case, you should use
await ctx.send(embed=contents[cur_page-1])
Afterwards, you can edit them like you want to, using the usual embed methods & attributes (add_field, set_footer, ...).

How to take input of a mentioned channel and send message in that channel?

I have the following code to generate embed from a message , it works fine now what I want is after creating embed the bot should ask the user to mention a channel and after the user mentions a channel , the bot should send that embed there. How do I do it?
#bot.command()
async def embed(ctx):
await ctx.send("Enter title for embed:")
e = await get_input_of_type(str, ctx)
await ctx.send("Enter the content for embed:")
c = await get_input_of_type(str, ctx)
embed = discord.Embed(
title = e,
description = c,
color = 0x03f8fc,
timestamp= ctx.message.created_at
)
embed.set_thumbnail(url = ctx.guild.icon_url)
await ctx.channel.send(embed=embed)
Using wait_for() and TextChannelConverter
#bot.command()
async def embed(ctx):
def check(m):
return m.author == ctx.author and m.channel == ctx.channel
await ctx.send("Enter title for embed:")
e = await get_input_of_type(str, ctx)
await ctx.send("Enter the content for embed:")
c = await get_input_of_type(str, ctx)
embed = discord.Embed(
title = e,
description = c,
color = 0x03f8fc,
timestamp= ctx.message.created_at
)
embed.set_thumbnail(url = ctx.guild.icon_url)
channel = await bot.wait_for("message", check=check)
channel = await commands.TextChannelConverter().convert(ctx, channel.content)
await channel.send(embed=embed)
I used the Client.wait_for() coroutine to wait for a message from the user. Then I formatted the message.content string to get just the ID of the channel. Then I used the discord.utils.get method to get the channel using just the ID.
# at the top of the file
from discord.utils import get
#client.command()
async def embed(ctx):
# embed stuff here
def check(msg):
# make sure the author of the message we're waiting for is the same user that invoked the command
return ctx.author == msg.author
await ctx.send("mention a channel to send to")
msg = await client.wait_for('message', timeout=60.0, check=check)
msg = msg.content.split("#")[1].split('>')[0]
"""
over here we are spliting the '#' from the message content first and index just the ID with the '>'
(if the message is just a channel mention it shoud be something like this: <#000000000000000000>)
then we split the '>' from the string and index just the ID part and now we have the ID of the channel
"""
channel = get(ctx.guild.channels, id=int(msg))
await channel.send(f'{words}')

Categories

Resources