یک ویترین کوچک داخل تلگرام: لیست محصولات با دکمهٔ شیشهای، جزئیات هر محصول در همان پیام و ثبت سفارش با ارسال شماره تماس.
سوال یا راهنمایی لازم داری؟ از صفحهٔ تماس با ما بپرس.
با /start لیست محصولات بهصورت دکمههای شیشهای (Inline) زیر پیام نمایش داده میشود. با زدن هر محصول، همان پیام به صفحهٔ جزئیات تبدیل میشود و چت شلوغ نمیشود. دکمهٔ «سفارش» شمارهٔ تماس مشتری را با یک دکمه میگیرد و سفارش را برای مدیر ارسال میکند.
این مراحل را بهترتیب انجام بده تا ربات روی سیستم خودت یا سرور بالا بیاید. داخل فایل ZIP یک راهنمای README هم هست.
این همان کدی است که داخل فایل ZIP هم هست. فقط یادت باشد مقدار TOKEN را با توکن رباتت عوض کنی.
# -*- coding: utf-8 -*-
# ------------------------------------------------------------
# ربات کاتالوگ محصولات با دکمهٔ شیشهای (Inline) تلگرام
# طراحی و کدنویسی: سروش مقدمی — فیلتور (filtori.com)
# ------------------------------------------------------------
# یک ویترین کوچک داخل تلگرام:
# - لیست محصولات با دکمههای شیشهای (زیر پیام) نمایش داده میشه
# - با زدن هر محصول، همون پیام به صفحهٔ جزئیات تبدیل میشه
# (بدون ارسال پیامهای اضافه و شلوغشدن چت)
# - دکمهٔ «سفارش» شمارهٔ تماس مشتری رو با یک دکمه میگیره
# و سفارش رو برای مدیر میفرسته
#
# ⚠️ نکته: ربات تلگرام باید روی سروری اجرا بشه که به
# api.telegram.org دسترسی داره.
#
# آموزش کامل:
# https://filtori.com/telegram-bot-source/catalog-bot/
# سوال یا راهنمایی: https://filtori.com/contact/
# فروشگاه کامل با سبد خرید، پرداخت و Mini App؟ 09122874862
# ------------------------------------------------------------
import time
import requests
TOKEN = "توکن_ربات_خودت_را_اینجا_بگذار"
BASE = f"https://api.telegram.org/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"]
api("answerCallbackQuery", {"callback_query_id": callback["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,
"one_time_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 یک کد کوتاه (مثل p4) دارد؛ کد باید یکتا باشد چون در callback_data استفاده میشود.
برای نمایش عکس، بهجای editMessageText از متد sendPhoto با کپشن استفاده کن؛ در نسخهٔ اختصاصی گالری و دستهبندی هم اضافه میشود.
اگر میخواهی سفارشها در اکسل هم ذخیره شوند، تابع save_order از ربات ثبت سفارش را اضافه کن.
اگر ربات اجرا نشد، اول پیام خطای ترمینال را با این جدول مقایسه کن. اگر خطایت اینجا نبود، از صفحهٔ تماس با ما بپرس.
| پیام خطا | علت | راهحل |
|---|---|---|
401 Unauthorized | توکن اشتباه است یا فاصلهٔ اضافه دارد. | توکن را دوباره از BotFather کپی کن و بین دو علامت نقلقول بگذار. |
409 Conflict | یک نسخهٔ دیگر از ربات در حال اجراست یا روی ربات وبهوک تنظیم شده. | نسخهٔ دیگر را خاموش کن. اگر قبلاً وبهوک گذاشتهای، آدرس api.telegram.org/bot<TOKEN>/deleteWebhook را یک بار باز کن. |
| Timeout یا ConnectionError | سرور به api.telegram.org دسترسی ندارد. | ربات را روی سروری اجرا کن که به تلگرام دسترسی دارد؛ روی بیشتر هاستهای داخل ایران این آدرس باز نیست. |
ModuleNotFoundError: requests | کتابخانهٔ requests نصب نشده. | دستور pip install -r requirements.txt یا pip install requests را اجرا کن. |
429 Too Many Requests | در زمان کوتاه پیام زیادی ارسال شده. | بین ارسالها مکث بگذار؛ تلگرام حدود ۳۰ پیام در ثانیه اجازه میدهد. |
| ربات در گروه جواب نمیدهد | Privacy Mode ربات روشن است. | در BotFather دستور /setprivacy را بزن و آن را Disable کن، یا ربات را ادمین گروه کن. |
با python bot.py ربات تا وقتی ترمینال باز است کار میکند. برای اجرای دائمی روی سرور لینوکس (Ubuntu/Debian)، فایلها را در پوشهٔ /opt/mybot بگذار و یک سرویس systemd بساز تا ربات بعد از خطا یا ریاستارت سرور خودش دوباره روشن شود.
[Unit]
Description=Filtori Telegram Bot
After=network-online.target
[Service]
WorkingDirectory=/opt/mybot
ExecStart=/usr/bin/python3 /opt/mybot/bot.py
Environment=PYTHONUNBUFFERED=1
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
sudo nano /etc/systemd/system/mybot.service # متن بالا را اینجا بگذار
sudo systemctl daemon-reload
sudo systemctl enable --now mybot # روشنکردن + اجرای خودکار بعد از ریاستارت
journalctl -u mybot -f # دیدن لاگها
راهاندازی روی سرور برایت سخت است؟ نصب و راهاندازی را به ما بسپار.
درخواست راهاندازیاین سورس برای یادگیری و شروع کار عالی است. وقتی ربات قرار است هر روز با مشتری واقعی کار کند، معمولاً به دیتابیس، پنل مدیریت، امنیت بیشتر و پشتیبانی نیاز دارد. تیم فیلتور همین ربات کاتالوگ محصولات تلگرام را اختصاصی و متناسب با فرآیند کسبوکارت میسازد.
| امکان | سورس رایگان | نسخهٔ اختصاصی |
|---|---|---|
| ذخیرهسازی | فایل CSV/TXT | دیتابیس |
| پنل مدیریت | — | ✓ |
| پرداخت آنلاین | — | ✓ |
| اتصال به سایت / CRM | — | ✓ |
| نصب و پشتیبانی | خودت | تیم فیلتور |
دکمهٔ شیشهای زیر خود پیام نمایش داده میشود و با زدنش پیامی در چت ارسال نمیشود؛ ربات فقط یک callback_query میگیرد و میتواند همان پیام را ویرایش کند. برای ویترین و منو تجربهٔ تمیزتری است.
خیر، این سورس سفارش تکی را با شماره تماس ثبت میکند. سبد خرید، درگاه پرداخت و Mini App فروشگاهی در نسخهٔ اختصاصی ساخته میشود.
محدودیت خاصی ندارد، ولی برای بیش از ۱۵ تا ۲۰ محصول بهتر است دستهبندی و صفحهبندی اضافه شود.
از صفحهٔ تماس با ما در filtori.com/contact پیام بدهید یا با شمارهٔ ۰۹۱۲۲۸۷۴۸۶۲ تماس بگیرید؛ اگر نسخهٔ اختصاصی همین ربات را برای کسبوکارتان بخواهید هم همین مسیر را استفاده کنید.
اگر در راهاندازی گیر کردی، یا میخواهی همین ربات برای کسبوکارت نصب و شخصیسازی شود، از صفحهٔ تماس با ما پیام بده.