آموزش ساخت سورس ربات روبیکا؛ پیشنیازها و نقشه راه
ساخت سورس ربات روبیکا فقط نوشتن چند دستور برای پاسخ دادن به پیام نیست. یک ربات قابل تحویل باید بتواند پیام ورودی را دریافت کند، کاربر را تشخیص دهد، وضعیت هر گفتگو را نگه دارد، دکمه یا منو نمایش دهد، اطلاعات را در دیتابیس ذخیره کند و در صورت نیاز به سایت، درگاه پرداخت، CRM یا پنل مدیریت متصل شود. در این آموزش یک اسکلت مهندسی برای ربات روبیکا میسازیم تا بتوانید آن را به ربات پشتیبانی، ثبت سفارش، فروش فایل، استعلام موجودی یا ربات موزیکال توسعه دهید.
پیش از شروع، وضعیت دسترسی توسعهدهندگان و مستندات رسمی روبیکا را بررسی کنید. روش اتصال، نام پارامترها، نشانی API و شیوه احراز هویت ممکن است تغییر کند. بنابراین در سورس واقعی، مقادیر حساس را در فایل محیطی نگه دارید و هرگز توکن یا کلید دسترسی را داخل کد، مخزن عمومی یا فایل فشرده قابل انتشار قرار ندهید. اگر هدف شما ساخت سریع یک جریان فروش یا پشتیبانی پایدار است، صفحه ربات روبیکا و ایتا مسیر طراحی و تحویل ربات اختصاصی را نیز توضیح میدهد.
خروجی نهایی این آموزش چیست؟
- ساختار پوشه استاندارد و قابل نگهداری برای سورس ربات روبیکا با پایتون
- دریافت و پردازش امن پیامهای ورودی با وبهوک
- مدیریت فرمانها، منوها و وضعیت مکالمه کاربر
- ذخیره کاربران و سفارشها در SQLite با قابلیت مهاجرت به PostgreSQL
- استقرار سرویس روی هاست یا سرور لینوکسی و اجرای دائمی
- چکلیست تست، لاگگیری و رفع خطاهای رایج
مرحله اول: انتخاب سناریو قبل از کدنویسی
بزرگترین اشتباه در شروع ساخت ربات، شروع مستقیم با API است. ابتدا جریان کاربر را روی کاغذ یا یک فایل متنی مشخص کنید. برای مثال، در ربات فروش کانفیگ یا فروش محصول دیجیتال، کاربر باید بتواند وارد منو شود، دسته را انتخاب کند، اطلاعات محصول را ببیند، سفارش بسازد، پرداخت را انجام دهد و نتیجه را دریافت کند. در ربات پشتیبانی نیز کاربر باید درخواست ثبت کند، کد پیگیری بگیرد و اپراتور بتواند وضعیت را تغییر دهد.
- هدف اصلی ربات را مشخص کنید: فروش، پشتیبانی، عضویت، اطلاعرسانی یا دریافت فرم.
- ورودیهای لازم از کاربر را بنویسید: نام، شماره سفارش، نوع درخواست یا فایل.
- خروجی هر مرحله را تعیین کنید: پیام، دکمه، لینک پرداخت، کد پیگیری یا اعلان مدیر.
- خطاها را طراحی کنید: پیام نامعتبر، پرداخت ناموفق، دسترسی نداشتن و درخواست تکراری.
- نقطه مدیریت را تعیین کنید: پنل ادمین، فایل تنظیمات یا اتصال به CRM.
اگر تجربه ساخت بات در پیامرسانهای دیگر دارید، بسیاری از اصول مشترک هستند. برای درک منطق هندلرها، وبهوک و ساختار پروژه میتوانید آموزش ساخت ربات تلگرام با Python را نیز بخوانید. تفاوت اصلی در لایه اتصال به API هر پلتفرم است، نه در معماری کسبوکار.
مرحله دوم: ساخت محیط پروژه پایتون
در این مثال از Python، Flask و SQLite استفاده میکنیم. Flask فقط وظیفه دریافت وبهوک را دارد و کد ارسال پیام در یک ماژول جدا قرار میگیرد. این جداسازی مهم است؛ چون بعدها میتوانید بدون تغییر منطق سفارش، روش اتصال روبیکا را اصلاح یا جایگزین کنید.
mkdir rubika-bot
cd rubika-bot
python -m venv .venv
source .venv/bin/activate
pip install flask requests python-dotenvدر ویندوز، فعالسازی محیط مجازی معمولاً با دستور زیر انجام میشود:
.venv\Scripts\activateپوشهها را به شکل زیر بسازید:
rubika-bot/
├── app.py
├── config.py
├── database.py
├── rubika_client.py
├── handlers.py
├── requirements.txt
├── .env
└── logs/فایل .env نباید در گیت ثبت شود. یک فایل .gitignore نیز ایجاد کنید:
.venv/
.env
__pycache__/
logs/
*.dbمرحله سوم: تنظیم متغیرهای حساس و پیکربندی
در فایل .env، نشانی وبهوک، کلید مخفی و اطلاعات اتصال را نگه دارید. نام متغیرها نمونه هستند؛ آنها را بر اساس مستندات اتصال مورد استفاده خود تنظیم کنید.
BOT_TOKEN=YOUR_BOT_TOKEN
WEBHOOK_SECRET=CHANGE_THIS_TO_A_LONG_RANDOM_VALUE
DATABASE_PATH=bot.db
ADMIN_USER_ID=123456
RUBIKA_API_BASE=https://api.example.comاکنون فایل config.py را بسازید:
import os
from dotenv import load_dotenv
load_dotenv()
class Config:
BOT_TOKEN = os.getenv("BOT_TOKEN", "")
WEBHOOK_SECRET = os.getenv("WEBHOOK_SECRET", "")
DATABASE_PATH = os.getenv("DATABASE_PATH", "bot.db")
ADMIN_USER_ID = os.getenv("ADMIN_USER_ID", "")
RUBIKA_API_BASE = os.getenv("RUBIKA_API_BASE", "")قبل از اجرا بررسی کنید که BOT_TOKEN و WEBHOOK_SECRET خالی نباشند. در پروژه عملی، برنامه باید هنگام نبودن تنظیمات ضروری متوقف شود، نه اینکه با تنظیمات ناقص اجرا شود.
مرحله چهارم: ایجاد دیتابیس کاربران و سفارشها
برای نمونه اولیه، SQLite انتخاب مناسبی است؛ فایل دیتابیس کنار پروژه قرار میگیرد و راهاندازی پیچیدهای ندارد. اگر تعداد تراکنشها یا اپراتورها زیاد شد، PostgreSQL انتخاب مناسبتری خواهد بود. در اینجا شناسه کاربر، نام نمایشی، وضعیت مکالمه و سفارشها را ذخیره میکنیم.
import sqlite3
from config import Config
def get_connection():
connection = sqlite3.connect(Config.DATABASE_PATH)
connection.row_factory = sqlite3.Row
return connection
def init_db():
connection = get_connection()
cursor = connection.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
user_id TEXT PRIMARY KEY,
first_name TEXT,
state TEXT DEFAULT 'idle',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
''')
cursor.execute('''
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT NOT NULL,
product_code TEXT NOT NULL,
status TEXT DEFAULT 'pending',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
''')
connection.commit()
connection.close()
def save_user(user_id, first_name=""):
connection = get_connection()
connection.execute('''
INSERT INTO users (user_id, first_name)
VALUES (?, ?)
ON CONFLICT(user_id) DO UPDATE SET first_name=excluded.first_name
''', (str(user_id), first_name))
connection.commit()
connection.close()برای ربات فروش، فقط ساخت سفارش کافی نیست. وضعیتهایی مانند pending، paid، delivered و failed را مشخص کنید تا بتوانید گزارش دقیق و قابل پیگیری داشته باشید. تحویل خودکار محصول باید تنها بعد از تأیید معتبر پرداخت یا تأیید اپراتور انجام شود.
مرحله پنجم: ساخت لایه ارسال پیام
کلاس زیر یک الگوی عمومی است. نام endpoint و بدنه درخواست را باید دقیقاً با مستندات اتصال روبیکا یا سرویس واسط مجاز خود هماهنگ کنید. نکته مهم این است که هیچ بخش دیگری از پروژه مستقیماً درخواست HTTP ارسال نکند؛ همه پیامها از این لایه عبور کنند.
import requests
from config import Config
class RubikaClient:
def send_text(self, chat_id, text):
url = f"{Config.RUBIKA_API_BASE}/sendMessage"
payload = {
"token": Config.BOT_TOKEN,
"chat_id": str(chat_id),
"text": text
}
response = requests.post(url, json=payload, timeout=15)
response.raise_for_status()
return response.json()
def send_menu(self, chat_id):
text = "به ربات خوش آمدید. یکی از گزینهها را ارسال کنید:\n1) ثبت سفارش\n2) پشتیبانی\n3) پیگیری سفارش"
return self.send_text(chat_id, text)در نسخههای دارای دکمه تعاملی، به جای شمارهگذاری متن، ساختار دکمه را طبق API رسمی ارسال کنید. راهنمای آموزش ساخت ربات روبیکا با پایتون و پیام شیشهای (دکمه تعاملی) برای طراحی تجربه کاربری منویی و پیامهای دکمهدار مفید است.
مرحله ششم: پردازش پیام و مدیریت وضعیت مکالمه
هندلر باید پیام را پاکسازی کند، فرمانها را تشخیص دهد و در حالتهای مختلف واکنش مناسب نشان دهد. هرگز به داده دریافتی اعتماد کامل نکنید؛ ممکن است برخی فیلدها وجود نداشته باشند یا متن پیام خالی باشد.
from database import save_user
from rubika_client import RubikaClient
client = RubikaClient()
def handle_message(chat_id, user_id, first_name, text):
text = (text or "").strip()
save_user(user_id, first_name)
if text in ["/start", "شروع", "بازگشت به منو"]:
client.send_menu(chat_id)
return
if text in ["1", "ثبت سفارش"]:
client.send_text(chat_id, "کد محصول موردنظر را ارسال کنید.")
return
if text in ["2", "پشتیبانی"]:
client.send_text(chat_id, "شرح درخواست خود را در یک پیام ارسال کنید.")
return
if text in ["3", "پیگیری سفارش"]:
client.send_text(chat_id, "کد پیگیری سفارش را ارسال کنید.")
return
client.send_text(chat_id, "دستور را متوجه نشدم. عبارت «شروع» را ارسال کنید.")در نمونه بالا برای کوتاهی، وضعیت در دیتابیس خوانده نشده است. در پروژه واقعی، پس از انتخاب «ثبت سفارش»، وضعیت کاربر را مثلاً به waiting_product_code تغییر دهید. سپس فقط وقتی وضعیت همین مقدار است، متن بعدی را بهعنوان کد محصول پردازش کنید. این روش باعث میشود متنهای عادی کاربر به اشتباه سفارش تلقی نشوند.
مرحله هفتم: راهاندازی وبهوک با Flask
وبهوک یک URL عمومی است که پلتفرم پیامرسان رویدادهای جدید را به آن ارسال میکند. برای امنیت، یک مسیر غیرقابل حدس انتخاب نکنید؛ به جای تکیه بر مخفی بودن URL، امضای درخواست یا هدر امنیتی را اعتبارسنجی کنید. همچنین وبهوک باید با HTTPS در دسترس باشد.
from flask import Flask, request, jsonify, abort
from config import Config
from database import init_db
from handlers import handle_message
app = Flask(__name__)
init_db()
@app.post("/webhook/rubika")
def rubika_webhook():
secret = request.headers.get("X-Webhook-Secret", "")
if secret != Config.WEBHOOK_SECRET:
abort(403)
payload = request.get_json(silent=True) or {}
message = payload.get("message", {})
chat_id = message.get("chat_id")
user_id = message.get("from", {}).get("id")
first_name = message.get("from", {}).get("first_name", "")
text = message.get("text", "")
if not chat_id or not user_id:
return jsonify({"ok": True, "ignored": True})
handle_message(chat_id, user_id, first_name, text)
return jsonify({"ok": True})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)ساختار دقیق payload در هر API متفاوت است. ابتدا یک نمونه رویداد واقعی را در محیط آزمایشی لاگ کنید، فیلدهای شناسه گفتگو و فرستنده را استخراج کنید و سپس هندلر را با همان ساختار تطبیق دهید. بدنه کامل پیامها را در لاگ عمومی ذخیره نکنید؛ ممکن است شامل داده شخصی کاربران باشد.
مرحله هشتم: نصب سورس ربات روی هاست یا سرور
برای اجرای دائمی، هاست باید امکان اجرای Python و وبسرور را داشته باشد. در سرور لینوکسی، استفاده از Gunicorn پشت Nginx رایج است. ابتدا وابستگیها را ثبت کنید:
pip freeze > requirements.txt
pip install gunicorn
python -m gunicorn --bind 127.0.0.1:8000 app:appبرای اجرای پایدار پس از ریاستارت سرور، یک سرویس systemd بسازید:
[Unit]
Description=Rubika Bot Service
After=network.target
[Service]
User=www-data
WorkingDirectory=/var/www/rubika-bot
Environment="PATH=/var/www/rubika-bot/.venv/bin"
ExecStart=/var/www/rubika-bot/.venv/bin/gunicorn --workers 2 --bind 127.0.0.1:8000 app:app
Restart=always
[Install]
WantedBy=multi-user.targetسپس سرویس را فعال کنید:
sudo systemctl daemon-reload
sudo systemctl enable rubika-bot
sudo systemctl start rubika-bot
sudo systemctl status rubika-botاگر قبلاً سورس بات دیگری نصب کردهاید، اصول استقرار مشابه است. برای معماری بدون سرور نیز میتوانید آموزش ساخت ربات تلگرام با Cloudflare Workers بدون نیاز به هاست (راهنمای کامل ۲۰۲۶) را بهعنوان مرجع مفهومی بررسی کنید؛ البته سازگاری نهایی با وبهوک و محدودیتهای API روبیکا باید جداگانه تست شود.
چکلیست تست پیش از تحویل
- ارسال فرمان شروع از حساب جدید و حساب قبلی
- تست منو، دکمهها و متنهای فارسی در موبایل
- ارسال متن خالی، متن طولانی و داده نامعتبر
- تست همزمان چند کاربر و مستقل بودن وضعیت مکالمه
- بررسی ثبت کاربر و سفارش در دیتابیس
- تست قطع موقت API و نمایش پیام خطای مناسب
- تست ریاستارت سرویس و ادامه دریافت وبهوک
- بررسی عدم نمایش توکن، کلیدها و خطاهای حساس به کاربر
خطاهای رایج در سورس ربات روبیکا
ربات پیام دریافت نمیکند
اول URL وبهوک، گواهی SSL، تنظیم endpoint و لاگ وبسرور را بررسی کنید. سپس با یک درخواست آزمایشی بررسی کنید که Flask پاسخ 200 میدهد. اگر پاسخ 403 است، هدر یا مقدار کلید مخفی با تنظیمات سرویس ارسالکننده یکسان نیست.
پیام تکراری پردازش میشود
برخی سرویسها در صورت تأخیر پاسخ، رویداد را دوباره ارسال میکنند. برای جلوگیری از ثبت سفارش تکراری، شناسه یکتای پیام یا رویداد را در دیتابیس ذخیره کنید و قبل از پردازش، وجود آن را بررسی کنید. این موضوع برای پرداخت و تحویل محصول حیاتی است.
ربات در سرور کار میکند اما روی دامنه نه
تنظیمات reverse proxy، پورت داخلی، DNS و گواهی SSL را بررسی کنید. Nginx باید درخواست مسیر وبهوک را به Gunicorn منتقل کند و فایروال نیز اتصال HTTPS را مسدود نکرده باشد.
توسعههای بعدی برای یک ربات قابل فروش
پس از راه افتادن نسخه پایه، قابلیتها را مرحلهای اضافه کنید: پنل مدیریت سفارشها، نقش اپراتور، پیام گروهی با رضایت کاربران، اتصال درگاه پرداخت، وبسرویس استعلام، گزارش فروش، تیکتینگ و اتصال CRM. برای پروژههایی که قرار است در چند پیامرسان فعالیت کنند، منطق کسبوکار را از کلاینت روبیکا جدا نگه دارید تا بتوانید همان سفارش، کاربران و پنل را برای ایتا یا بله نیز استفاده کنید. راهنمای آموزش ساخت ربات ایتا و ارسال خودکار پیام به کانال یا گروه و صفحه ساخت ربات پیامرسان و شبکههای اجتماعی نیز برای طراحی مسیر چندکاناله کاربرد دارند.
جمعبندی
یک سورس ربات روبیکا حرفهای از چهار بخش تشکیل میشود: اتصال امن به API، هندلرهای قابل توسعه، دیتابیس برای نگهداری وضعیت و استقرار پایدار روی سرور. ابتدا نسخه کوچک با یک منوی مشخص بسازید، سپس سفارش، پرداخت و پنل مدیریت را اضافه کنید. با این رویکرد، سورس شما به جای یک اسکریپت کوتاه و شکننده، به یک راهکار قابل تست، قابل پشتیبانی و آماده توسعه تبدیل میشود.
نظرات کاربران
فقط نظرات تاییدشده مدیر نمایش داده میشود.