button = Button(style = discord.ButtonStyle.green, emoji = ":arrow_backward:", custom_id = "button1")
button2 = Button(style = discord.ButtonStyle.green, emoji = ":arrow_up_small:", custom_id = "button2")
button3 = Button(style = discord.ButtonStyle.green, emoji = ":arrow_forward:", custom_id = "button3")
view = View()
view.add_item(button)
view.add_item(button2)
view.add_item(button3)
async def button_callback(interaction):
if number != ("⠀⠀1"):
await message.edit(content="**response 1**")
else:
await message.edit(content="**response 2**")
async def button_callback2(interaction):
if number != ("⠀⠀⠀⠀⠀⠀⠀⠀⠀2"):
await message.edit(content="**response 1**")
else:
await message.edit(content="**response 2**")
async def button_callback3(interaction):
if number != ("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀3"):
await message.edit(content="**response 1**")
else:
await message.edit(content= "**response 2**")
button.callback = button_callback
button2.callback = button_callback2
button3.callback = button_callback3
await message.edit(content= f"⠀⠀:watermelon:⠀⠀⠀⠀⠀:watermelon:⠀⠀⠀⠀⠀:watermelon:\n{number}", view=view)
In the code it creates and sends a message with buttons on it, once you press the button itll either edit the message to say "response1" or "response2" depending if the button had the 1, 2 ,3 over it (if it didnt have the number over it, it prints "response1" if it did have the number over it, it prints "response2") i would like it so when it edits it to either of the responses it also removes the buttons, as it currently doesnt.
Set view=None in your message.edit function call to remove all of the buttons.
Related
I'm trying to write a telegram bot, that selects a group of photos in 3 steps, using Inline Keyboards. During each of steps I call an Inline Keyboard with 2 buttons. First button selects a criteria, changes variable "selected_criteria" and calls next Inline Keyboard, 2nd button sends photos based on the variable "selected_criteria".
from aiogram import Bot, Dispatcher, executor, types
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
import os
button1 = InlineKeyboardButton(text="Criteria1", callback_data="Never")
button2 = InlineKeyboardButton(text="Criteria2", callback_data="Gonna")
button3 = InlineKeyboardButton(text="Criteria3", callback_data="Give")
button4 = InlineKeyboardButton(text="Selected Criteria", callback_data="You")
keyboard_inline = InlineKeyboardMarkup().add(button1, button4)
keyboard_inline2 = InlineKeyboardMarkup().add(button2, button4)
keyboard_inline3 = InlineKeyboardMarkup().add(button3, button4)
keyboard_inline4 = InlineKeyboardMarkup().add(button4)
class Handler:
def __init__(self, dp: Dispatcher, chat_id):
self.selected_criteria = ""
self.chat_id = chat_id
self.source_dir = ""
dp.callback_query_handler(
text=["Never", "Gonna", "Give", "You"]
)(self.criteria_selection)
async def criteria_selection(self, call: types.CallbackQuery):
if call.data == "Never":
self.selected_criteria = "1"
await call.message.reply("Choose 2nd Criteria", reply_markup=keyboard_inline2)
if call.data == "Gonna":
self.selected_criteria = self.selected_criteria + "2"
await call.message.reply("Choose 3rd Criteria", reply_markup=keyboard_inline3)
if call.data == "Give":
self.selected_criteria = self.selected_criteria + "3"
await call.message.reply("End Selection", reply_markup=keyboard_inline4)
if call.data == "You":
await call.message.reply(self.selected_criteria)
with os.scandir(self.source_dir) as entries:
for entry in entries:
if entry.name.startswith(self.selected_criteria):
await call.message.answer_photo(photo=open(entry, "rb"))
await call.answer()
bot = Bot(token="")
dp = Dispatcher(bot)
#dp.message_handler(commands=['start', 'help'])
async def welcome(message: types.Message):
handler = Handler(dp, message.chat.id)
await message.reply("Welcome chat_id= " + str(handler.chat_id), reply_markup=keyboard_inline)
await handler.criteria_selection()
executor.start_polling(dp)
Variable source_dir is the folder where I keep all of the photos that I will be sending
The problem is that once there is more than 1 user of the bot, it stops working as intended, because the variable "selected_criteria" is shared between all users.
So if User1 chose all 3 criteria, but before he pushed the button to send photos, someone else chose 1st criteria, User1 is going to receive incorrect photos.
It's my first time doing a telegram bot, so i'm probably doing something wrong, if so please tell me how I can do better.
recently i created a telegram bot using python and i added keyboard button features to the bot. However, i am having difficulties in getting replies from bot to the buttons users choose.
button7 = KeyboardButton('About Us',request_contact= False)
keyboard2 = ReplyKeyboardMarkup(resize_keyboard = True, one_time_keyboard = True).row(button7)
#dp.message_handler(commands=['info'])
async def mood(message: types.Message):
await message.reply('Do you wish to know about us??', reply_markup=keyboard2)
In this case, i created a button named "About Us" and i want the bot to open a url using webbrowser.open if the user click on that button. Can anyone help me solving this problem?
Try it:
markup = types.InlineKeyboardMarkup()
button1 = types.InlineKeyboardButton(text='Ukraine', url="https://en.wikipedia.org/wiki/Ukraine", callback_data='1')
markup.add(button1)
bot.send_message(message.from_user.id, 'Do you know?, parse_mode='Markdown', reply_markup=markup)
Text (inline button)
from aiogram import Bot, Dispatcher, executor, types
bot = Bot(token='token')
dp = Dispatcher(bot)
#dp.message_handler(commands=['start'])
async def welcome(message: types.Message):
markup = types.InlineKeyboardMarkup()
button1 = types.InlineKeyboardButton(text='Ukraine', url="https://en.wikipedia.org/wiki/Ukraine", callback_data='1')
button2 = types.InlineKeyboardButton(text='Hi bot!', callback_data="1")
markup.add(button1, button2)
await bot.send_message(message.from_user.id, "Do you know?", parse_mode="Markdown", reply_markup=markup)
#dp.callback_query_handler(lambda call: True)
async def sendText(call: types.CallbackQuery):
msg = ""
if call.data == "1":
msg = "Hi, programmer!"
await call.message.edit_text(msg)
if __name__ == '__main__':
executor.start_polling(dp, skip_updates=True)
I am trying to disable the "Next" button after it has been clicked once. When a user clicks on "Next", the bot replies to itself with the next page of the weekly tasks.
global WEEK_NUM
next_button = interactions.Button(
style=interactions.ButtonStyle.PRIMARY,
label="Next",
custom_id="next",
disabled = False
)
async def week_choose(ctx: interactions.CommandContext, week_number: int):
global WEEK_NUM
WEEK_NUM = week_number
embeds = interactions.Embed(
title=f"Deadlines for Week {week_number}",
description=Dates[week_number],
color=0x00ff00
)
embeds.add_field(name="Summatives:", value=Summatives[week_number], inline=False)
if (week_number == 1):
await ctx.send(embeds = embeds, components = next_button)
#bot.component("next")
async def button_response(ctx):
global WEEK_NUM
forward = WEEK_NUM
WEEK_NUM += 1
forward = forward + 1
embeds1 = interactions.Embed(
title=f"Deadlines for Week {forward}",
description=Dates[forward],
color=0x00ff00
)
embeds1.add_field(name="Summatives:", value=Summatives[forward], inline=False)
await ctx.send(embeds = embeds1, ephemeral=False)
If I add next_button.disabled = True after await ctx.send(embeds = embeds, components = next_button) it disables the button after it has been called once which seems logical. Is there a way to do this around? I am using interactions.py
You could try this one:
I've used this with the discord.py but I am not sure if it's the same as in interactions.py
next_button.disabled = True
await ctx.send(embeds = embeds1, ephermeral=False, components=next_button)
I recommend using interactions.py's official wait_for extension. Wait for a button press, it will give you the ComponentContext of the component that was pressed. You can disable the buttons after receiving the button press using:
disable_all_components() or component_context.disabled = True.
I'm trying to create a ticket bot using discord buttons. However, whenever I click on the button- which should create a ticket just responds with a prompt saying: "This interaction failed".
#commands.command(pass_context = True)
#commands.has_permissions(administrator=True)
async def ticket(self, ctx):
if self.channelId == 0:
embed_var = discord.Embed(title="", description="No channel set up [.ticketSet]", color=0xffffff)
await ctx.send(embed=embed_var)
else:
await self.bot.wait_until_ready()
embed_var = discord.Embed(title="Tickets", description=self.ticketDesc, color=0xffffff)
channel = self.bot.get_channel(int(self.channelId))
await channel.send(embed=embed_var,components = [Button(label = "📩 Create Ticket", custom_id = "button1")])
while True:
event = await self.bot.wait_for('button_click')
await self.on_button_click()
#commands.Cog.listener()
async def on_button_click(self, interaction):
admin = discord.utils.get(interaction.guild.roles, name=self.manageRole)
category = discord.utils.get(interaction.guild.categories, name="INFO / HELP")
print("Button 'ticket' clicked")
...
I have 3 embeds. 2 of them show the correct embeds, but one of them just shows a blank embed. the codes are nearly the same, so I don't know whats wrong. Here is my code for my function:
My code:
#client.command()
async def slots(ctx, amount = None):
await open_account(ctx.author)
if amount == None:
await ctx.send("How ya gonna slots 0 coins, dum dum")
return
bal = await update_bank(ctx.author)
amount = int(amount)
if amount>(bal[0]+1):
await ctx.send("You don't even have that many coins, idiot")
return
if amount<0:
await ctx.send("You wanna lose money by gambling negative coins?")
return
final = []
for i in range(3):
a = random.choice([":egg:", ":baby_chick:", ":hatching_chick:",":hatched_chick:",':poultry_leg:',':chicken:'])
final.append(a)
em = Embed(title = f"{ctx.author}s Slots Game", color = discord.Color.lighter_grey())
em.add_field(name = final, value = f"\n{ctx.author}s Slots Game", inline = False)
msg = await ctx.send(embed = em)
if final[0] == final[1] or final[0] == final[2] or final[1] == final[2]:
await update_bank(ctx.author, 2*amount)
em_new = Embed(title = f"{ctx.author}s Slots Game", color = discord.Color.green())
em_new.add_field(name = final, value = f"\n{ctx.author}s Slots Game", inline = False)
em_new.add_field(name = "Win!", value = f"You won {2*amount} coins!")
sleep(1)
await msg.edit(embed=em_new)
if final[0] == final[1] == final[2]:
await update_bank(ctx.author, 3*amount)
em_new = Embed(title = f"{ctx.author}s Slots Game", color = discord.Color.green())
em_new.add_field(name = final, value = f"\n{ctx.author}s Slots Game", inline = False)
em_new.add_field(name = "Win!", value = f"You won {3*amount} coins!")
sleep(1)
await msg.edit(embed=em_new)
else:
await update_bank(ctx.author, -1*amount)
em_new = Embed(title = f"{ctx.author}s Slots Game", color = discord.Color.red())
em_new.add_field(name = final, value = f"\n{ctx.author}s Slots Game", inline = False)
em_new = discord.Embed(name = "Loss!", value = f"You lost {-1*amount} coins.")
sleep(1)
await msg.edit(embed=em_new)
the first 2 if statement embed things are working, they edit and show what they're supposed to show. But the else statement embed just shows a blank embed. can someone pls help me
In this line of code
em_new = discord.Embed(name = "Loss!", value = f"You lost {-1*amount} coins.")
You are calling an embed via discord.Embed while in all other cases you are using Embed by itself.
Considering that all embeds except for this work I assume your imports look similar to the following:
from discord import Embed
With this import structure you do not need to specify discord.Embed
So change the line of code to the following:
em_new = Embed(name = "Loss!", value = f"You lost {-1*amount} coins.")
Additionally I should remark that you should probably replace time.sleep with its asyncio equivalent. You can find more info about that here.