رفتن به محتوای اصلی
🗂️ سطح: متوسط · رایگان · جدید

سورس ربات کاتالوگ محصولات با دکمهٔ شیشه‌ای بله

یک ویترین کوچک داخل بله: لیست محصولات با دکمهٔ شیشه‌ای، جزئیات هر محصول در همان پیام (بدون شلوغ‌شدن چت) و ثبت سفارش با ارسال شماره تماس.

طراحی و کدنویسی: به‌روزرسانی: زبان: Python 3حجم کد: حدود ۱۸۰ خطمجوز: آزاد (CC0)

پاسخ کوتاه

ربات کاتالوگ بله محصولات را با inline keyboard زیر پیام نشان می‌دهد. با زدن هر دکمه، به‌جای پیام جدید یک callback_query می‌رسد و ربات با editMessageText همان پیام را به صفحهٔ جزئیات تبدیل می‌کند. دکمهٔ سفارش شماره تماس را با request_contact می‌گیرد و سفارش را برای مدیر می‌فرستد.

ربات کاتالوگ محصولات بله چه کاری انجام می‌دهد؟

اگر محصولاتت را با عکس و متن در کانال می‌گذاری و مشتری‌ها مدام «قیمتش چنده؟» می‌پرسند، این ربات یک ویترین مرتب می‌سازد. دکمه‌های شیشه‌ای زیر پیام نمایش داده می‌شوند و با زدن هر محصول، همان پیام به صفحهٔ جزئیات با قیمت و توضیح تبدیل می‌شود. دکمهٔ «سفارش» شمارهٔ تماس مشتری را با یک دکمه می‌گیرد و سفارش را همراه نام و یوزرنیم برای مدیر می‌فرستد.

زبان: پایتون ۳
وابستگی: فقط requests
دکمهٔ شیشه‌ای: inline keyboard
ویرایش پیام: editMessageText
هزینه: رایگان

آموزش راه‌اندازی ربات کاتالوگ محصولات بله در ۵ قدم

این مراحل را به‌ترتیب انجام بده تا ربات روی سیستم خودت یا سرور بالا بیاید. زمان تقریبی: ۲۰ دقیقه. داخل فایل ZIP راهنمای README هم هست.

از BotFather در بله توکن ربات را بگیر.
پایتون ۳ را نصب کن و pip install requests را اجرا کن.
در فایل bot.py مقدار TOKEN و ADMIN_CHAT_ID را بگذار.
دیکشنری PRODUCTS را با نام، قیمت و توضیح محصولات خودت پر کن.
python bot.py را اجرا کن، /start بزن، یک محصول را باز کن و سفارش آزمایشی ثبت کن.

کل سورس ربات کاتالوگ محصولات بله (کپی یا دانلود کن)

این همان کدی است که داخل فایل ZIP هم هست. می‌توانی مستقیم از اینجا کپی کنی. فقط یادت باشد مقدار TOKEN را با توکن رباتت عوض کنی.

bot.py
# -*- coding: utf-8 -*-
# ------------------------------------------------------------
#  ربات کاتالوگ محصولات با دکمهٔ شیشه‌ای (Inline) بله
#  طراحی و کدنویسی: سروش مقدمی — فیلتور (filtori.com)
# ------------------------------------------------------------
#  یک ویترین کوچک داخل بله:
#   - لیست محصولات با دکمه‌های شیشه‌ای (زیر پیام) نمایش داده می‌شه
#   - با زدن هر محصول، همون پیام به صفحهٔ جزئیات تبدیل می‌شه
#     (بدون ارسال پیام‌های اضافه و شلوغ‌شدن چت)
#   - دکمهٔ «سفارش» شمارهٔ تماس مشتری رو با یک دکمه می‌گیره
#     و سفارش رو برای مدیر می‌فرسته
#
#  آموزش کامل:
#     https://filtori.com/bale-bot-source/catalog-bot/
#  سوال یا راهنمایی:  https://filtori.com/contact/
#  فروشگاه کامل با سبد خرید و پرداخت درون‌بله؟  09122874862
# ------------------------------------------------------------

import time

import requests

TOKEN = "توکن_ربات_خودت_را_اینجا_بگذار"
BASE = f"https://tapi.bale.ai/bot{TOKEN}"

ADMIN_CHAT_ID = 123456789  # <-- chat_id مدیر برای دریافت سفارش‌ها

# ------------------------- محصولات -------------------------
PRODUCTS = {
    "p1": {"name": "هدفون بی‌سیم", "price": "۱٬۸۵۰٬۰۰۰ تومان",
           "desc": "باتری ۳۰ ساعته، حذف نویز، گارانتی ۱۸ ماهه."},
    "p2": {"name": "ساعت هوشمند", "price": "۲٬۹۰۰٬۰۰۰ تومان",
           "desc": "ضدآب، سنجش ضربان قلب، اتصال به اندروید و iOS."},
    "p3": {"name": "پاوربانک ۲۰ هزار", "price": "۹۵۰٬۰۰۰ تومان",
           "desc": "شارژ سریع ۲۲.۵ وات، دو خروجی USB و یک Type-C."},
}
# -----------------------------------------------------------

pending_orders = {}  # chat_id -> کد محصولی که منتظر شمارهٔ تماسش هستیم


def api(method, data):
    try:
        return requests.post(f"{BASE}/{method}", json=data, timeout=15).json()
    except (requests.RequestException, ValueError) as error:
        print(f"خطا در {method}:", error)
        return {"ok": False}


def get_updates(offset):
    params = {"offset": offset, "timeout": 30}
    try:
        return requests.get(f"{BASE}/getUpdates", params=params, timeout=40).json()
    except (requests.RequestException, ValueError) as error:
        print("خطا در دریافت پیام‌ها:", error)
        return {"ok": False, "result": []}


def catalog_keyboard():
    buttons = [[{"text": f"{p['name']} — {p['price']}", "callback_data": f"show:{code}"}]
               for code, p in PRODUCTS.items()]
    return {"inline_keyboard": buttons}


def product_keyboard(code):
    return {
        "inline_keyboard": [
            [{"text": "🛒 سفارش این محصول", "callback_data": f"order:{code}"}],
            [{"text": "↩️ بازگشت به لیست", "callback_data": "back"}],
        ]
    }


def send_catalog(chat_id):
    api("sendMessage", {"chat_id": chat_id, "text": "🛍 محصولات ما؛ روی هر کدوم بزن:",
                        "reply_markup": catalog_keyboard()})


def edit(chat_id, message_id, text, keyboard):
    """ویرایش همان پیام قبلی به‌جای ارسال پیام جدید."""
    api("editMessageText", {"chat_id": chat_id, "message_id": message_id,
                            "text": text, "reply_markup": keyboard})


def handle_callback(callback):
    data = callback.get("data", "")
    chat_id = callback["message"]["chat"]["id"]
    message_id = callback["message"]["message_id"]

    if data == "back":
        edit(chat_id, message_id, "🛍 محصولات ما؛ روی هر کدوم بزن:", catalog_keyboard())

    elif data.startswith("show:"):
        code = data.split(":", 1)[1]
        product = PRODUCTS.get(code)
        if product:
            text = f"📦 {product['name']}\n\n{product['desc']}\n\n💰 قیمت: {product['price']}"
            edit(chat_id, message_id, text, product_keyboard(code))

    elif data.startswith("order:"):
        code = data.split(":", 1)[1]
        if code in PRODUCTS:
            pending_orders[chat_id] = code
            api("sendMessage", {
                "chat_id": chat_id,
                "text": f"برای سفارش «{PRODUCTS[code]['name']}» شمارهٔ تماست رو با دکمهٔ زیر بفرست:",
                "reply_markup": {
                    "keyboard": [[{"text": "📱 ارسال شماره تماس", "request_contact": True}],
                                 [{"text": "انصراف"}]],
                    "resize_keyboard": True,
                },
            })


def handle_message(message):
    chat_id = message["chat"]["id"]
    text = message.get("text", "")
    contact = message.get("contact")

    if text in ("/start", "/products"):
        pending_orders.pop(chat_id, None)
        send_catalog(chat_id)
        return

    if text == "انصراف":
        pending_orders.pop(chat_id, None)
        api("sendMessage", {"chat_id": chat_id, "text": "سفارش لغو شد.",
                            "reply_markup": {"remove_keyboard": True}})
        return

    if chat_id in pending_orders and contact:
        code = pending_orders.pop(chat_id)
        product = PRODUCTS[code]
        user = message.get("from", {})
        username = f"@{user['username']}" if user.get("username") else "—"
        api("sendMessage", {
            "chat_id": chat_id,
            "text": f"سفارش «{product['name']}» ثبت شد ✅\nبه‌زودی برای هماهنگی باهات تماس می‌گیریم.",
            "reply_markup": {"remove_keyboard": True},
        })
        api("sendMessage", {
            "chat_id": ADMIN_CHAT_ID,
            "text": (f"🛒 سفارش جدید\n📦 {product['name']} ({product['price']})\n"
                     f"👤 {contact.get('first_name', '')}  {username}\n📞 {contact['phone_number']}"),
        })
        return

    if chat_id in pending_orders:
        api("sendMessage", {"chat_id": chat_id,
                            "text": "لطفاً شماره را با دکمهٔ «📱 ارسال شماره تماس» بفرست."})
        return

    send_catalog(chat_id)


def main():
    print("ربات کاتالوگ فیلتور روشن شد... (Ctrl+C برای خاموش‌کردن)")
    offset = 0
    while True:
        updates = get_updates(offset)
        if not updates.get("ok"):
            time.sleep(2)
            continue

        for update in updates.get("result", []):
            offset = update["update_id"] + 1
            if "callback_query" in update:
                handle_callback(update["callback_query"])
            elif "message" in update:
                handle_message(update["message"])

        time.sleep(0.5)


if __name__ == "__main__":
    main()
کل سورس این ربات ↑ — همین حالا کپی یا دانلود کن

کد را خط‌به‌خط بفهم

کپی‌کردن کافی نیست؛ اگر بدانی هر بخش چرا آن‌جاست، می‌توانی ربات را برای کسب‌وکار خودت تغییر بدهی. مهم‌ترین قطعه‌های ربات کاتالوگ محصولات بله:

۱محصولات در یک دیکشنری

PRODUCTS = {
    "p1": {"name": "هدفون بی‌سیم", "price": "۱٬۸۵۰٬۰۰۰ تومان", "desc": "..."},
}

هر محصول یک کد کوتاه دارد (p1، p2 …). این کد داخل callback_data دکمه قرار می‌گیرد، پس باید یکتا و کوتاه باشد؛ نام و قیمت فقط برای نمایش است.

۲دکمهٔ شیشه‌ای با callback_data

{"text": f"{p['name']} — {p['price']}", "callback_data": f"show:{code}"}

دکمهٔ شیشه‌ای برخلاف کیبورد معمولی، پیامی در چت نمی‌فرستد؛ فقط یک callback_query با همین داده به ربات می‌رسد. پیشوند show: و order: نوع درخواست را مشخص می‌کند.

۳ویرایش همان پیام

api("editMessageText", {"chat_id": chat_id, "message_id": message_id,
                        "text": text, "reply_markup": keyboard})

به‌جای ارسال پیام تازه، همان پیام لیست به صفحهٔ جزئیات تبدیل می‌شود و دکمهٔ «بازگشت» دوباره لیست را برمی‌گرداند. نتیجه یک چت تمیز و تجربه‌ای شبیه اپلیکیشن است.

۴منتظر شمارهٔ تماس

pending_orders[chat_id] = code
...
if chat_id in pending_orders and contact:

بعد از زدن «سفارش» کد محصول را برای آن کاربر نگه می‌داریم و منتظر پیام contact می‌مانیم. اگر کاربر شماره را تایپ کند، ربات دوباره دکمهٔ ارسال شماره را یادآوری می‌کند.

🔁 همین کد روی تلگرام هم اجرا می‌شود: فقط BASE را به https://api.telegram.org/bot{TOKEN} تغییر بده. نسخهٔ تلگرامی آماده را در سورس رایگان ربات تلگرام ببین.

سوال‌های پرتکرار دربارهٔ ربات کاتالوگ محصولات بله

دکمهٔ شیشه‌ای چه فرقی با کیبورد معمولی دارد؟

دکمهٔ شیشه‌ای زیر خود پیام نمایش داده می‌شود و با زدنش پیامی در چت ارسال نمی‌شود؛ ربات یک callback_query می‌گیرد و می‌تواند همان پیام را ویرایش کند. برای ویترین و منو تجربهٔ تمیزتری است.

عکس محصول هم نمایش داده می‌شود؟

این سورس برای سادگی فقط متن نشان می‌دهد. برای عکس می‌توان از متد sendPhoto بله با کپشن استفاده کرد؛ در نسخهٔ اختصاصی گالری، دسته‌بندی و جست‌وجو هم اضافه می‌شود.

پرداخت آنلاین دارد؟

خیر، سفارش با شماره تماس ثبت می‌شود. بله پرداخت درون‌ربات با متد sendInvoice را پشتیبانی می‌کند؛ سبد خرید و پرداخت ریالی در نسخهٔ اختصاصی پیاده‌سازی می‌شود.

چند محصول می‌شود اضافه کرد؟

محدودیت خاصی ندارد، ولی برای بیش از ۱۵ تا ۲۰ محصول بهتر است دسته‌بندی و صفحه‌بندی اضافه شود تا لیست طولانی نشود.

سوال یا مشکلی داشتم از کجا راهنمایی بگیرم؟

از صفحهٔ تماس با ما پیام بدهید یا با ۰۹۱۲۲۸۷۴۸۶۲ تماس بگیرید؛ برای نسخهٔ اختصاصی همین ربات هم همین مسیر را استفاده کنید.

طراح و برنامه‌نویس این سورس‌ها · بنیان‌گذار فیلتور

مدیر بخش دیتابیس همراه اول و فعال در توسعهٔ نرم‌افزار از سال ۱۳۹۱؛ با سابقهٔ کار روی سامانه‌های بانکی و پرتراکنش. این سورس‌ها را طوری نوشته که ساده، خوانا و قابل توسعه باشند و مستقیم در کسب‌وکار واقعی استفاده شوند.

سوالی داری یا راهنمایی می‌خواهی؟

اگر در راه‌اندازی گیر کردی، یا می‌خواهی همین ربات برای کسب‌وکارت نصب، شخصی‌سازی و به سیستم‌هایت وصل شود، از صفحهٔ تماس با ما پیام بده.