Inline tugmali menyu bot
Bitta xabar ichida ishlaydigan menyu: tugma bosilganda bot yangi xabar yubormaydi, balki o'sha xabarni editMessageText bilan yangilaydi. Har bir callback'ga answerCallbackQuery bilan javob beriladi.
Kod
menu_bot.py
import os
import time
import requests
TOKEN = os.environ["ZAMIN_BOT_TOKEN"]
API = f"https://api.zamin.app/bot{TOKEN}"
PRODUCTS = {
"olma": ("π Olma", "12 000 so'm/kg"),
"anor": ("π
Anor", "25 000 so'm/kg"),
"uzum": ("π Uzum", "18 000 so'm/kg"),
}
def call(method, params=None, http_timeout=15):
r = requests.post(f"{API}/{method}", json=params or {}, timeout=http_timeout)
body = r.json()
if not body.get("ok"):
raise RuntimeError(f"{method}: {body.get('error_code')} {body.get('description')}")
return body["result"]
def main_menu():
return {
"inline_keyboard": [
[{"text": "π Mahsulotlar", "callback_data": "products"}],
[
{"text": "βΉοΈ Biz haqimizda", "callback_data": "about"},
{"text": "π Sayt", "url": "https://example.com"},
],
]
}
def products_menu():
rows = [[{"text": name, "callback_data": f"p:{key}"}] for key, (name, _) in PRODUCTS.items()]
rows.append([{"text": "Β« Orqaga", "callback_data": "home"}])
return {"inline_keyboard": rows}
def back_menu(target="home"):
return {"inline_keyboard": [[{"text": "Β« Orqaga", "callback_data": target}]]}
def show(chat_id, message_id, text, markup):
"""Xabarni joyida yangilaydi (yangi xabar yubormasdan)."""
try:
call("editMessageText", {"chat_id": chat_id, "message_id": message_id, "text": text, "reply_markup": markup})
except RuntimeError as e:
if "message is not modified" not in str(e):
raise
def on_message(message):
text = message.get("text", "")
if text.startswith("/start") or text.startswith("/menu"):
call("sendMessage", {"chat_id": message["chat"]["id"], "text": "Meva do'koniga xush kelibsiz! π", "reply_markup": main_menu()})
def on_callback(query):
data = query.get("data", "")
chat_id = query["message"]["chat"]["id"]
message_id = query["message"]["message_id"]
notice = None
if data == "home":
show(chat_id, message_id, "Meva do'koniga xush kelibsiz! π", main_menu())
elif data == "products":
show(chat_id, message_id, "Mahsulotni tanlang:", products_menu())
elif data == "about":
show(chat_id, message_id, "Biz 2026-yildan beri yangi meva yetkazamiz.", back_menu())
elif data.startswith("p:") and data[2:] in PRODUCTS:
name, price = PRODUCTS[data[2:]]
show(chat_id, message_id, f"{name}\nNarxi: {price}", back_menu("products"))
notice = f"{name} tanlandi"
else:
notice = "Bu tugma eskirgan"
# Har bir callback'ga bir marta, 60 soniya ichida javob beriladi
params = {"callback_query_id": query["id"]}
if notice:
params["text"] = notice
call("answerCallbackQuery", params)
def main():
call("deleteWebhook")
call("setMyCommands", {"commands": [{"command": "start", "description": "Boshlash"}, {"command": "menu", "description": "Menyu"}]})
offset = None
while True:
params = {"timeout": 30, "allowed_updates": ["message", "callback_query"]}
if offset is not None:
params["offset"] = offset
try:
updates = call("getUpdates", params, http_timeout=40)
except (requests.RequestException, RuntimeError, ValueError) as e:
print("getUpdates xatosi:", e)
time.sleep(3)
continue
for update in updates:
offset = update["update_id"] + 1
try:
if "message" in update:
on_message(update["message"])
elif "callback_query" in update:
on_callback(update["callback_query"])
except (requests.RequestException, RuntimeError, ValueError) as e:
print("Xato:", e)
if __name__ == "__main__":
main()Ishga tushirish
Terminal
pip3 install requests
export ZAMIN_BOT_TOKEN="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
python3 menu_bot.pyMuhim nuqtalar
callback_dataβ 64 baytgacha. Qisqa kodlar ishlating (p:olma), katta ma'lumotni serveringizda saqlang.- Foydalanuvchi eski xabardagi tugmani ham bosishi mumkin β noma'lum
datauchun ham javob bering. - editMessageText'da
reply_markupberilmasa, tugmalar o'chadi. Shu sabab har safar menyu qayta yuboriladi. - Bot xabarlarini faqat 48 soat ichida tahrirlash mumkin; undan keyin
/menuyangi xabar yuboradi. - URL tugma (
π Sayt) callback yubormaydi β ilova havolani tasdiq bilan ochadi.