Klaviaturalar va callback'lar
Ikki xil klaviatura bor: xabarga biriktiriladigan inline tugmalar va tizim klaviaturasi o'rnida chiqadigan reply klaviatura. Ikkalasi ham reply_markup parametri orqali yuboriladi.
Guruhlarda faqat inline klaviatura ishlaydi (reply klaviatura β 400 only inline keyboards are supported in groups); tugmani istalgan a'zo bosishi mumkin, javob esa faqat bosganga ko'rinadi. Kanal postlarida tugma bo'lmaydi. Batafsil.
Umumiy cheklovlar
| Cheklov | Qiymat |
|---|---|
| Qatorlar | β€12 |
| Bitta qatorda tugmalar | β€8 |
| Jami tugmalar | β€100 |
| Tugma matni | 1β64 belgi |
| callback_data | 1β64 bayt (UTF-8: kirill yoki emoji ko'proq bayt oladi) |
| URL | β€2048 belgi, faqat http/https |
| Bo'sh qator | Ruxsat yo'q |
JSON so'rovda reply_markup obyekt bo'ladi; query, form yoki multipart'da β JSON matn.
Inline klaviatura
Inline tugmalar xabar ostida turadi. Har bir tugmada text va quyidagilardan aynan bittasi: callback_data (botga signal), url (havola) yoki web_app (hozircha havola sifatida ochiladi).
import os
import requests
TOKEN = os.environ["ZAMIN_BOT_TOKEN"]
API = f"https://api.zamin.app/bot{TOKEN}"
CHAT_ID = int(os.environ["ZAMIN_CHAT_ID"])
keyboard = {
"inline_keyboard": [
[
{"text": "π Yoqdi", "callback_data": "like"},
{"text": "π Yoqmadi", "callback_data": "dislike"},
],
[{"text": "π Batafsil", "url": "https://example.com/maqola"}],
]
}
requests.post(
f"{API}/sendMessage",
json={"chat_id": CHAT_ID, "text": "Maqola sizga yoqdimi?", "reply_markup": keyboard},
timeout=15,
)Callback'larni qayta ishlash
callback_data'li tugma bosilganda bot callback_query yangilanishini oladi. Server faqat haqiqatan shu xabar klaviaturasida bor callback_data'ni qabul qiladi, lekin foydalanuvchi har qanday tugmani istalgan vaqtda bosishi mumkin β data'ni doim tekshiring.
- Darhol answerCallbackQuery chaqiring: bir marta, 60 soniya ichida. Ixtiyoriy
text(β€200) qisqa bildirishnoma bo'lib chiqadi,show_alert: trueβ oyna,urlβ havola. - Kerak bo'lsa, xabarni editMessageText yoki editMessageReplyMarkup bilan yangilang (48 soat ichida).
def on_callback(query):
chat_id = query["message"]["chat"]["id"]
message_id = query["message"]["message_id"]
data = query["data"]
text = {"like": "Rahmat! π", "dislike": "Fikringiz uchun rahmat."}.get(data, "Noma'lum tugma")
requests.post(
f"{API}/answerCallbackQuery",
json={"callback_query_id": query["id"], "text": text},
timeout=15,
)
# Ovoz berilgach, tugmalarni olib tashlaymiz (reply_markup yuborilmaydi)
requests.post(
f"{API}/editMessageText",
json={"chat_id": chat_id, "message_id": message_id, "text": f"Maqola sizga yoqdimi? β {text}"},
timeout=15,
)Reply klaviatura
Reply klaviatura chatning faol klaviaturasiga aylanadi va tizim klaviaturasi o'rnida (yoki u bilan almashinib) ko'rinadi. Oddiy tugma bosilsa, uning matni foydalanuvchining oddiy xabari bo'lib keladi. Klaviatura yangisi yuborilguncha yoki remove_keyboard bilan olib tashlanguncha turadi.
keyboard = {
"keyboard": [
["π Pitsa", "π Burger"], # oddiy matnli tugmalar
[{"text": "π Savat"}, {"text": "β Yordam"}],
],
"resize_keyboard": True,
"input_field_placeholder": "Taom tanlang",
}
requests.post(
f"{API}/sendMessage",
json={"chat_id": CHAT_ID, "text": "Nima buyurtma qilasiz?", "reply_markup": keyboard},
timeout=15,
)
# Keyinroq olib tashlash:
requests.post(
f"{API}/sendMessage",
json={"chat_id": CHAT_ID, "text": "Buyurtma qabul qilindi β
", "reply_markup": {"remove_keyboard": True}},
timeout=15,
)| Maydon | Ma'nosi |
|---|---|
keyboard | Tugmalar qatorlari. Tugma β {"text": β¦} obyekti yoki oddiy matn. |
resize_keyboard | Ixchamroq ko'rsatish uchun ishora. |
one_time_keyboard | true β foydalanuvchining keyingi xabaridan keyin klaviatura yo'qoladi. |
input_field_placeholder | Kiritish maydonidagi ishora matni (β€64). |
is_persistent | Saqlanadi va ilovaga uzatiladi. |
request_contact va request_location
Bot foydalanuvchining telefon raqamini yoki joylashuvini o'zi ko'ra olmaydi. Faqat so'rashi mumkin: reply klaviaturaga request_contact yoki request_location tugmasini qo'shing. Foydalanuvchi tugmani bosganda ilova tasdiq so'raydi ("Telefon raqamingizni @bot bilan ulashasizmi?"). Faqat tasdiqlangandan keyin bot contact yoki location'li xabar oladi.
keyboard = {
"keyboard": [
[{"text": "π± Raqamni yuborish", "request_contact": True}],
[{"text": "π Joylashuvni yuborish", "request_location": True}],
["Bekor qilish"],
],
"resize_keyboard": True,
"one_time_keyboard": True,
}
requests.post(
f"{API}/sendMessage",
json={"chat_id": CHAT_ID, "text": "Yetkazib berish uchun raqam va manzil kerak.", "reply_markup": keyboard},
timeout=15,
)
def on_message(message):
if "contact" in message:
phone = message["contact"]["phone_number"] # foydalanuvchining o'z raqami
print("Raqam:", phone)
elif "location" in message:
loc = message["location"]
print("Joylashuv:", loc["latitude"], loc["longitude"])- Kontakt β doim foydalanuvchining o'z raqami va ismi; boshqa odamning kontaktini yuborib bo'lmaydi.
- Joylashuv β bir martalik nuqta (jonli kuzatuv emas).
- Ilova bu ma'lumotni faqat chatning faol klaviaturasida shunday tugma bo'lsa yuboradi. Klaviaturani olib tashlasangiz, so'rov ham bekor bo'ladi.
- Bitta tugmada ikkalasi bo'lmaydi.
URL qoidalari
Inline tugmalardagi url, web_app.url va answerCallbackQuery'dagi url quyidagi qoidalar bilan tekshiriladi:
- Faqat
http://vahttps://(web_appuchun faqathttps://).zamin://,javascript:,data:,tel:va boshqa sxemalar rad etiladi. - URL ichida login/parol, bo'shliq yoki boshqaruv belgilari bo'lmasin; uzunligi β€2048.
- zamin.app havolalari faqat ochiq profil, bot yoki kanal sahifasiga:
https://zamin.app/<username>, ixtiyoriy?start=PARAMbilan (PARAM:A-Z a-z 0-9 _ -, β€64). Taklif havolalari (/+β¦) va boshqa yo'llar,#qism hamda zamin.app'ning boshqa subdomenlari ruxsat etilmagan.
| URL | Natija |
|---|---|
https://example.com/shop?id=5 | β |
https://zamin.app/ObHavoBot?start=promo | β |
https://zamin.app/+AbCdEf123 | β taklif havolasi |
https://api.zamin.app/v1/β¦ | β zamin.app subdomeni |
zamin://u/ali | β sxema |
javascript:alert(1) | β sxema |
Ilova bot bergan har qanday havolani ochishdan oldin domenni ko'rsatib, tasdiq so'raydi.