رفتن به محتوا

ساخت چت‌بات برای سایت و بازوی بله با API هیبانا

راهنمای ساخت چت‌بات پشتیبانی برای سایت و بازوی پیام‌رسان بله با API هیبانا و پایتون؛ از پیام سیستمی و حافظهٔ گفت‌وگو تا کنترل هزینه و امنیت کلید.

تیم هیبانا۴ دقیقه مطالعه
یک پنجرهٔ مرورگر و یک گوشی همراه که حباب‌های گفت‌وگو از هر دو به یک هستهٔ نورانی مشترک وصل شده‌اند

یک چت‌بات خوب می‌تواند به پرسش‌های تکراری مشتری‌ها، مثل ساعت کاری، هزینهٔ ارسال یا وضعیت سفارش، شبانه‌روز پاسخ بدهد. در این راهنما یک چت‌بات پشتیبانی می‌سازیم که هم روی سایت کار می‌کند و هم به‌عنوان بازو (ربات) در پیام‌رسان بله فعالیت می‌کند. هر دو از یک «مغز» مشترک استفاده می‌کنند که با API هیبانا به مدل زبانی وصل است.

معماری: یک مغز، دو کانال

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

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

یک قانون امنیتی مهم: کلید API هیبانا هرگز نباید در کد مرورگر باشد. هر کسی می‌تواند کد جاوااسکریپت سایت را ببیند و با کلید شما درخواست بفرستد. مرورگر فقط با سرور شما حرف می‌زند و کلید روی سرور می‌ماند.

مغز چت‌بات

کتابخانه‌های لازم را نصب کنید:

pip install openai flask requests

این تابع را در فایلی به نام bot.py بگذارید. به‌جای YOUR_API_KEY کلید هیبانای خودتان را بگذارید، یا بهتر، آن را از متغیر محیطی بخوانید:

from openai import OpenAI client = OpenAI(base_url="https://api-ai.hibanacloud.ir/v1", api_key="YOUR_API_KEY") SYSTEM = (    "تو دستیار پشتیبانی فروشگاه اینترنتی «نمونه» هستی. کوتاه، مؤدب و به فارسی پاسخ بده. "    "ساعت کاری: شنبه تا چهارشنبه ۹ تا ۱۸ و پنجشنبه ۹ تا ۱۳. ارسال رایگان برای خرید بالای ۲ میلیون تومان. "    "اگر پاسخ را نمی‌دانی، کاربر را به پشتیبانی تلفنی ارجاع بده.")MAX_MESSAGES = 10  # فقط ۱۰ پیام آخر هر گفت‌وگو فرستاده می‌شود تا هزینه بالا نرودhistories = {}  # شناسهٔ گفت‌وگو ← پیام‌ها (در محیط واقعی: Redis یا پایگاه داده)  def answer(conversation_id, text):    history = histories.setdefault(conversation_id, [])    history.append({"role": "user", "content": text})    del history[:-MAX_MESSAGES]     r = client.chat.completions.create(        model="openai/gpt-5-nano",        reasoning_effort="low",        messages=[{"role": "system", "content": SYSTEM}, *history],    )    reply = r.choices[0].message.content    history.append({"role": "assistant", "content": reply})    return reply

سه تصمیم در این کد مهم است:

  • اطلاعات کسب‌وکار در پیام سیستمی: مدل از ساعت کاری یا شرایط ارسال شما خبر ندارد. در آزمایش ما، وقتی ساعت کاری را از پیام سیستمی حذف کردیم، مدل با اطمینان ساعت‌هایی را گفت که وجود نداشتند. اطلاعاتی را که ربات باید بداند، صریح بنویسید و از آن بخواهید در موارد نامعلوم به پشتیبانی ارجاع بدهد.
  • حافظهٔ محدود: در هر درخواست، برای تاریخچهٔ فرستاده‌شده دوباره هزینه می‌پردازید، پس فقط چند پیام آخر را نگه دارید. دلیلش را در مطلب توکن و هزینه توضیح داده‌ایم.
  • مدل ارزان و سریع: برای پاسخ به پرسش‌های پشتیبانی، مدل‌های کوچک مثل gpt-5-nano کافی و چند برابر ارزان‌ترند. مدل‌های دیگر را در لیست مدل‌ها مقایسه کنید.

چت‌بات سایت

یک سرور کوچک Flask که پیام را از مرورگر می‌گیرد و پاسخ تابع answer را برمی‌گرداند (فایل site.py):

from flask import Flask, jsonify, requestfrom bot import answer app = Flask(__name__)  @app.post("/chat")def chat():    data = request.get_json()    return jsonify(reply=answer(data["session_id"], data["message"]))  if __name__ == "__main__":    app.run(port=8000)

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

const sessionId = crypto.randomUUID(); async function sendMessage(text) {  const res = await fetch("/chat", {    method: "POST",    headers: { "Content-Type": "application/json" },    body: JSON.stringify({ session_id: sessionId, message: text }),  });  return (await res.json()).reply;}

یک گفت‌وگوی واقعی با همین کد، روی API هیبانا:

کاربر: سلام، پنجشنبه‌ها باز هستید؟ربات: بله. پنجشنبه‌ها از ساعت ۹ تا ۱۳ بازیم. همچنان می‌تونید سفارش بدید و از ارسال رایگان برای خریدهای بالای ۲ میلیون استفاده کنید. هر سوالی داشتید بفرمایید. کاربر: تا چه ساعتی؟ و ارسال رایگان دارید؟ربات: - ساعات کاری: شنبه تا چهارشنبه ۹:۰۰ تا ۱۸:۰۰، پنجشنبه‌ها ۹:۰۰ تا ۱۳:۰۰.- ارسال رایگان: دارد برای خریدهای بالای ۲٬۰۰۰٬۰۰۰ تومان. در خریدهای پایین‌تر هزینه ارسال ممکن است اعمال شود. سوالی دیگه‌ای دارید؟

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

بازوی بله

API بازوی بله بر پایهٔ API بات تلگرام طراحی شده و ساده است. ابتدا در بله با @botfather گفت‌وگو کنید، یک بازوی تازه بسازید و توکن آن را بگیرید. آدرس همهٔ متدها به این شکل است:

https://tapi.bale.ai/bot<token>/METHOD_NAME

کد زیر (فایل bale.py) با روش long polling پیام‌های تازه را با متد getUpdates می‌گیرد، پاسخ را از همان تابع answer می‌گیرد و با sendMessage در همان گفت‌وگو می‌فرستد. به‌جای YOUR_BALE_TOKEN توکن بازوی خودتان را بگذارید:

import requestsfrom bot import answer BALE = "https://tapi.bale.ai/botYOUR_BALE_TOKEN" offset = 0while True:    # long polling: تا ۳۰ ثانیه منتظر پیام تازه می‌ماند    resp = requests.get(f"{BALE}/getUpdates", params={"offset": offset, "timeout": 30}, timeout=40).json()    for update in resp.get("result", []):        offset = update["update_id"] + 1        msg = update.get("message")        if not msg or "text" not in msg:            continue  # فعلاً فقط پیام متنی        reply = answer(msg["chat"]["id"], msg["text"])        requests.post(            f"{BALE}/sendMessage",            json={"chat_id": msg["chat"]["id"], "text": reply[:4096], "reply_to_message_id": msg["message_id"]},            timeout=30,        )

چند نکته دربارهٔ این بخش:

  • offset باید یکی بیشتر از شناسهٔ آخرین به‌روزرسانیِ دریافت‌شده باشد؛ وگرنه همان پیام‌ها دوباره می‌آیند.
  • متن هر پیام در بله حداکثر ۴۰۹۶ نویسه است؛ پاسخ‌های بلندتر را کوتاه کنید یا در چند پیام بفرستید.
  • برای بازوی پرکاربرد، به‌جای long polling می‌توانید با متد setWebhook یک آدرس HTTPS معرفی کنید تا بله پیام‌ها را خودش به سرور شما بفرستد.
  • چون API بله بر پایهٔ API بات تلگرام است، کتابخانه‌ها و نمونه‌کدهای بات تلگرام معمولاً با تغییرات کمی برای بله هم کار می‌کنند.

پیش از انتشار

  • کلید را در کد ننویسید: کلید هیبانا و توکن بازو را در متغیرهای محیطی نگه دارید و در مخزن کد ثبت نکنید.
  • سقف خرج بگذارید: برای کلید ربات یک کلید جداگانه در پنل بسازید تا مصرفش را جدا ببینید و در صورت نیاز محدودش کنید.
  • جلوی سوءاستفاده را بگیرید: برای هر کاربر یا هر آی‌پی محدودیت تعداد پیام در دقیقه بگذارید تا کسی نتواند با فرستادن هزاران پیام کیف پولتان را خالی کند.
  • تاریخچه را ماندگار کنید: دیکشنری histories با راه‌اندازی دوبارهٔ سرور پاک می‌شود؛ در محیط واقعی آن را در Redis یا پایگاه داده نگه دارید.

جمع‌بندی

با یک تابع مشترک و چند ده خط پایتون، یک چت‌بات پشتیبانی دارید که هم روی سایت کار می‌کند و هم در بله. درخواست‌های مدل با همان کلید و پرداخت ریالی هیبانا انجام می‌شوند و اگر بخواهید مدل را عوض کنید، فقط نام مدل تغییر می‌کند. برای شروع، کلید API بگیرید و اگر ربات باید از روی اسناد شما پاسخ بدهد، آموزش RAG فارسی را هم ببینید.

مطالب مرتبط

پروتکل MCP چیست؛ اتصال ابزارها و داده‌ها به مدل‌های هوش مصنوعی

پروتکل MCP به زبان ساده؛ میزبان، کلاینت و سرور چه می‌کنند، کدام ابزارها از آن پشتیبانی می‌کنند و چطور با مدل‌های هیبانا یک سرور MCP را به کار بگیرید.

کدام ایجنت کدنویسی با API ایرانی کار می‌کند؟ Kilo Code و Cline و Cursor

مقایسهٔ عملی Kilo Code و Cline و Cursor برای اتصال به API هوش مصنوعی از ایران؛ کدام کار می‌کند، چرا Cline توکن زیادی مصرف می‌کند و کدام مدل را انتخاب کنیم.

با یک کلید به همه مدل‌ها وصل شوید

GPT، Claude، Gemini و ده‌ها مدل دیگر، با پرداخت ریالی و یک API سازگار با OpenAI.