telegram bot reply message for buttons - python

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)

Related

How to make "back" button in aiogram? - python

I need to make working "back" button in aiogram that returns to /start menu.
I know what's my mistake is, but I have no idea how to fix it. Can someone help?
back_button = InlineKeyboardButton(text = "back", callback_data="bk")
keyboard_back = InlineKeyboardMarkup().add(back_button)
#dp.message_handler(commands=['start', 'help'])
async def send_welcome(message: types.Message):
return await bot.send_message(message.from_user.id, text="Hello!\nI'm WriteEssayBot!\nI will write any essay for you!", reply_markup = keyboard_inline)
#dp.callback_query_handler()
async def generate_text(call: types.CallbackQuery):
await bot.answer_callback_query(call.id)
if call.data == "bk":
await send_welcome() ```

how do i remove buttons off a message?

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.

How do i keep my class variable exclusive for every user?

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.

Telegram-bot on AIOgram. Pass message from message.handler to callback.handler

I am making a telegram bot on aiogram. Can't pass variables from message.handler to callback.handler. I use FSM, in message.handler state = "waiting_for_address".
The algorithm is => in message.handler, the bot sends inline_keyboard with the "Take" button to the GROUP. When the button is clicked, a callback is sent and the bot visits callback.handler. The state (state = "waiting_for_address") is saved, but only for the user who used the bot. But when we click the button, another user appears and has no state set. If I manually set the state in callback.handler, then the bot stops working.
Tell me, please, how to do it right?
#dp.message_handler(state=Form.waiting_for_address)
async def address_enter(message: types.Message, state: FSMContext):
inline_button = InlineKeyboardButton(text = 'Take order', callback_data='take')
inline_keyboard = types.InlineKeyboardMarkup(resize_keyboard = True, one_time_keyboard=True).add(inline_button)
address = message.text
await state.update_data(myTelephone=await getPhone(mydb,message))
await state.update_data(myAddress=address)
await state.update_data(myId=message.from_user.id)
user_data = await state.get_data()
chatId = '-###'
await bot.send_message(chatId, text=emoji.emojize(f"❗️ <b>New order</b> ❗️\nAddress : <b>{user_data['myAddress']}</b>\nCustomers telephone number : <b>{user_data['myTelephone']}</b>"),parse_mode='html',reply_markup = inline_keyboard)
await message.answer('Your order is sent',parse_mode='html')
#dp.callback_query_handler(lambda call: call.data == 'take' )
async def agree_ref_start(query: types.CallbackQuery, state: FSMContext):
if query.data == 'take':
await query.answer("I am callback!")
await bot.edit_message_text(chat_id=query.message.chat.id, message_id=query.message.message_id, text=emoji.emojize(f"✅ <b>Order is accepted</b> ✅\nАдрес : <b>{user_data['myAddress']}</b>\nCustomer telephone : <b>{user_data['myTelephone']}</b>\nOrder is accepted by #{query.from_user.username}"),parse_mode='html', reply_markup=None)
await bot.send_message(user_data['myId'],f"✅Your order is accepted\nYour telephone number <b>{user_data['myTelephone']}</b>\ndriver id - {query.from_user.id} ",parse_mode='html')
await state.finish()

Discord.py: This interaction failed

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")
...

Categories