Tugmalar bilan ishlash (2-dars)

Ushbu bo’limda biz siz bilan Telegram Botdagi tugmalar bilan ishlashni o’rganamiz. Telegram bot ikki xil tugmani jo’nata oladi: oddiy va inline(inlayn). Oddiy tugma deb ekranning past qismida chiqadigan tugmaga aytiladi, inline deb esa xabarning tagida chiqadigan tugmaga, quyidagi rasmda farqlarini ko’rishingiz mumkin:

Oddiy tugmalar

Oddiy tugma bosilganida unda yozilgan matn hudda foydalanuvchi jo’natgan matndek chatga jo’natiladi. Ushbu tugma bosilganida foydalanuvchiga javob berish uchun biz matnni qabul qiladigan handler yozishimiz kerak. Keling foydalanuvchi /start buyrug’ini yuborsa matnli xabar bilan oddiy tugma jo’natamiz:

# from aiogram import types

@dp.message_handler(commands='start')
async def start_cmd(message: types.Message):
    keyboard = types.ReplyKeyboardMarkup() # keyboard obyekti
    keyboard.add(types.KeyboardButton(text="Yaxshi")) # keyboardga KeyboardButton() orqali tugma qo'shish
    keyboard.add("Yomon") # KeyboardButton()'siz keyboardga tugma qo'shish
    await message.answer("Kayfiyatingiz qanday?", reply_markup=keyboard)
Python

E’tibor bergan bo’lsangiz “Yomon” tugmasini biz KeyboardButton()siz qo’shdik, chunki yangi tugma qo’shish uchun add() funksiyasiga shunchaki tugma uchun matnni bersa ham bo’ladi.

Keling endi kodimizni ishga tushirib, natijani ko’ramiz:

Ko’rib turganingizdek ikkita tugma chiqdi, biroq tugmalarimiz kattaroq. Tugmalarni kichraytirish uchun keyboard obyektiga resize_keyboard=True parametrini berish kerak. Keling bira to’lasi ikkita tugmani bitta qatorda chiqarishni ham ko’ramiz. Keling endi kodimizni biroz o’zgartirib, yuqoridagilarni kodimizda qo’llaymiz:

@dp.message_handler(commands='start')
async def start_cmd(message: types.Message):
    keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True) # keyboard obyekti
    buttons = ['Yaxshi','Yomon']
    keyboard.add(*buttons) # yoki .add('Yaxshi','Yomon')
    await message.answer("Kayfiyatingiz qanday?", reply_markup=keyboard)

Endi kodni qayta ishga tushirib, natijani ko’ramiz:

Ko’rib turganingizdek tugmalar kichyardi va bir qatorda bo’ldi.

Ushbu tugmalarni foydalanuvchi bosganda unga javob beradigan qilish qoldi. Yoqorida aytib o’tganimizdek foydalanuvchi oddiy tugmani bosganida ushbu tugma botga matndek keladi, shuning uchun biz Yaxshi va Yomon matnlarini handlerda “ushlab” olishimiz kerak. Ma’lum bir matnni “ushlab” olish uchun handlerda aiogram’da Text filteri mavjud:

from aiogram.dispatcher.filters import Text

@dp.message_handler(Text("Yaxshi")) # yoki shunchaki text="Yaxshi"
async def good(message: types.Message):
    await message.reply("Kayfiyatingiz yaxshi ekanligidan xursandman :)")

@dp.message_handler(Text("Yomon")) # yoki shunchaki text="Yomon"
async def bad(message: types.Message):
    await message.reply("Kayfiyatingiz yomonligidan afsusdaman :(\nSizga yaxshi kayfiyat tilab qo'laman!")

Kodimizni qayta ishga tushirib, natijasini ko’ramiz:

E’tibor bergan bo’lsangiz biz tugmani bosganimizdan so’ng ham tugmalar o’chmayapti. Ushbu tugmalarni o’chirish uchun ReplyKeyboardRemove mavjud. Qo’llash uchun misol:

await message.reply("Kayfiyatingiz yaxshi ekanligidan xursandman :)",reply_markup=types.ReplyKeyboardRemove())

Siz bilan to’liq bo’lmasa ham oddiy tugmalar bilan ishlashni o’rgandik. Agar to’liqroq o’rganmoqchi bo’lsangiz manbalar: (Telegram Bot API: ReplyKeyboardMarkup, KeyboardButton), (Aiogram Docs: ReplyKeyboardMarkup, KeyboardButton).

Maxsus oddiy tugmalar

Oddiy tugmalarning vazifasi faqatgina foydalanuvchi biror bir tugmani bossa, usha tugma matnini chatga jo’natishdan iborat emas. Balki oddiy tugmalar orqali foydalanuvchining joylashuvini,telefon raqamini qabul qilish mumkin. Keling ushbu tugmalarni kodda qanday bo’lishini ko’ramiz:

@dp.message_handler(commands="buttons")
async def buttons(message: types.Message):
    keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
    keyboard.add(types.KeyboardButton(text="Lokatsiyani yuborish", request_location=True))
    keyboard.add(types.KeyboardButton(text="Telefon raqamni yuborish", request_contact=True))
    await message.answer("Quyidagi maxsus tugmalardan birini tanlang: ", reply_markup=keyboard)

Oddiy tugmalar bilan ishlashda yozilgan to’liq kod: havola

Inline(inlayn) tugmalar

Inline(inlayn) tugmalar yuborilgan xabarning tagida chiqadi, oddiy tugmalar kabi ekranning pastgi qismida emas. Biz siz bilan ikki xil turdagi inline tugmalar bilan ishlashni o’rganamiz,bular: url va callback.

URL(havolali) tugmalar

Ushbu turdagi tugmalar orqali foydalanuvchini biror http(s) yoki tg:// bilan boshlangan havolalarga yo’naltirsa bo’ladi.

@dp.message_handler(commands='url_tugma')
async def url_tugma(message: types.Message):
    keyboard = types.InlineKeyboardMarkup(row_width=1)
    buttons = [
        types.InlineKeyboardButton(text="Instagram",url="https://www.instagram.com/texnokun_uz/"),
        types.InlineKeyboardButton(text="Telegram kanal",url="tg://resolve?domain=texnokun_uz"),
    ]
    keyboard.add(*buttons)
    await message.answer("TexnoKun.uz'ning ijtimoiy tarmoqlardagi sahifasi: ",reply_markup=keyboard)

Natija esa:

Agar ikkita tugmani bir qatorda qilmoqchi bo’lsangiz InlineKeyboardMarkupdan row_width=1ni olib tashlang(shunda standart(default) qiymat 3 ishlatiladi). row_width parametri orqali bir qatorda nechta tugma bo’lishi kerakligini sozlash mumkin.

Callback tugmalar

Callback tugmalarda foydalanuvchi qaysi tugmani bosganini bilish uchun o’zida maxsus qiymatni(data) saqlaydi. Ushbu qiymat bizga foydalanuvchi qaysi tugma bosganini va unga javoban nima deyish kerakligini bilish uchun kerak bo’ladi. Sodda qilib aytganda foydalanuvchi qaysi tugmani bosganini bilish va shunga qarab javob qaytarish uchun callback tugmalarda qiymat saqlanadi.

Keling endi praktikaga o’tsak, foydalanuvchi botga /random buyrug’ini jo’natsa, unga callback tugma jo’natamiz:

@dp.message_handler(commands='random')
async def random_cmd(message: types.Message):
    keyboard = types.InlineKeyboardMarkup()
    keyboard.add(types.InlineKeyboardButton(text="Tugmani bosing",callback_data='random_value'))
    await message.answer("1dan 10gacha bo'lgan tasodifiy sonlarni jo'natishim uchun quyidagi tugmani bosing: ", reply_markup=keyboard)

Endi ushbu tugmani bosganda foydalanuvchiga javob berish qoldi. Biror bir yangi xabarni “ushlab” olish uchun avval biz message_handlerdan foydalangan bo’lsak, callbackni “ushlab” olish uchun callback_query_handlerdan foydalanamiz. Foydalanuvchi tugmani bosganida uni “ushlab” olish uchun biz tugmamizga bergan callback_datani,yani maxsus qiymatni ushlab oladigan handler qilamiz:

from random import randint

@dp.callback_query_handler(text="random_value")
async def send_random_value(call: types.CallbackQuery):
    await call.message.answer(str(randint(1,10)))

callback_query_handlerda ham message_handler kabi text filter qo’llaniladi.

Keling yuqoridagi kodimizga biroz o’zgartirish kiritib, tasodifiy sonni jo’natmasdan, bot jo’natgan xabarini tahrirlab foydalanuvchiga tasodifiy sonni taqdir etamiz:

@dp.callback_query_handler(text="random_value")
async def send_random_value(call: types.CallbackQuery):
    await call.message.edit_text(str(randint(1,10)))

Endi callback tugmani bosganingizda xabarni tahrirlab, tasodifiy sonni taqdim etadi. Sinab ko’rishingiz mumkin.

Callback tugmalar bilan ishlashdagi barcha kodlar: link

Kengi qism: Ketma-ketlik bo’yicha foydalanuvchidan ma’lumotlarni qabul qilish(FSM)(3-qism).

Mavzuga oid maqolalar