ساخت ربات تلگرام فارسی با API هوش مصنوعی در ۳۰ دقیقه (Python و استریم)
ربات تلگرام هنوز سریعترین راه رساندن هوش مصنوعی به دست کاربر ایرانی است: نه اپ میخواهد، نه سایت، نه آموزش. یک توکن از BotFather، یک کلید API و کمتر از صد خط Python کافی است تا رباتی داشته باشید که فارسی میفهمد، پاسخ را کلمهبهکلمه تایپ میکند و گفتگو را یادش میماند. مانع همیشگی، یعنی کلید API با کارت ارزی، با API هوش مصنوعی نِت اَرز برداشته شده؛ پس در این آموزش فقط روی ساختن تمرکز میکنیم. اگر سی دقیقه وقت بگذارید، آخر مقاله رباتتان روشن است.
چه چیزهایی لازم داریم
- Python نسخهٔ ۳٫۱۱ یا بالاتر
- کتابخانهٔ
python-telegram-botنسخهٔ ۲۱ به بالا (نسخههای async) و کتابخانهٔ رسمیopenai - توکن ربات از BotFather
- کلید API نِت اَرز با پیشوند
sk-ntz-v1-و کمی اعتبار (حداقل شارژ ۱۰۰ هزار تومان بهعلاوهٔ ۹ درصد مالیات) - یک سرور برای اجرای دائمی. نکتهٔ مهم: API نِت اَرز از داخل ایران بدون مشکل کار میکند، اما اتصال به API خود تلگرام از IP ایرانی محدود است؛ بنابراین ربات را یا روی سرور مجازی خارج از ایران اجرا کنید یا برای بخش تلگرام پروکسی تنظیم کنید.
قدم اول: توکن ربات
در تلگرام به BotFather پیام دهید، دستور /newbot را بزنید، نام و نام کاربری (که باید به bot ختم شود) را انتخاب کنید و توکنی شبیه 123456789:AAH... بگیرید. همانجا با /setdescription توضیح کوتاهی هم برای ربات بنویسید؛ کاربر قبل از اولین پیام آن را میبیند.
قدم دوم: پروژه و کلید در نِت اَرز
در پنل API یک پروژه با نام «telegram-bot» بسازید و داخل آن یک کلید. برای این کلید سقف هزینهٔ ماهانه بگذارید (مثلاً معادل بودجهای که برای ماه اول در نظر دارید) و اگر IP سرورتان ثابت است، آن را در فهرست IP مجاز قرار دهید. کلید فقط یک بار نمایش داده میشود؛ همان لحظه کپی کنید.
قدم سوم: نصب
python -m venv .venv && source .venv/bin/activate
pip install "python-telegram-bot>=21" openai
export TELEGRAM_TOKEN="123456789:AAH..."
export NETARZ_AI_KEY="sk-ntz-v1-..."
export AI_MODEL="gpt-5-mini"
قدم چهارم: کد کامل ربات
این کد سه کار میکند: برای هر گفتگو تاریخچهٔ کوتاهی نگه میدارد، پاسخ مدل را استریم میگیرد و پیام تلگرام را هر یک ثانیه با متن تازه ویرایش میکند تا کاربر حس تایپ زنده داشته باشد.
import os, time, asyncio
from collections import defaultdict, deque
from openai import AsyncOpenAI
from telegram import Update
from telegram.constants import ChatAction
from telegram.ext import Application, CommandHandler, MessageHandler, ContextTypes, filters
client = AsyncOpenAI(base_url="https://netarz.ir/api/ai/v1", api_key=os.environ["NETARZ_AI_KEY"])
MODEL = os.environ.get("AI_MODEL", "gpt-5-mini")
SYSTEM = (
"تو یک دستیار فارسیزبان مؤدب و دقیق هستی. کوتاه و روشن جواب بده و از Markdown استفاده نکن."
)
# per-chat short memory: last 10 messages (5 turns)
history = defaultdict(lambda: deque(maxlen=10))
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
history[update.effective_chat.id].clear()
await update.message.reply_text("سلام! هر سؤالی داری بپرس. برای شروع دوباره /reset را بزن.")
async def reset(update: Update, context: ContextTypes.DEFAULT_TYPE):
history[update.effective_chat.id].clear()
await update.message.reply_text("گفتگو پاک شد.")
async def chat(update: Update, context: ContextTypes.DEFAULT_TYPE):
chat_id = update.effective_chat.id
text = update.message.text.strip()
if not text:
return
history[chat_id].append({"role": "user", "content": text})
messages = [{"role": "system", "content": SYSTEM}] + list(history[chat_id])
await context.bot.send_chat_action(chat_id=chat_id, action=ChatAction.TYPING)
placeholder = await update.message.reply_text("…")
answer, last_edit = "", time.monotonic()
try:
stream = await client.chat.completions.create(
model=MODEL, messages=messages, max_tokens=600, stream=True,
)
async for chunk in stream:
piece = chunk.choices[0].delta.content or ""
if not piece:
continue
answer += piece
# Telegram allows roughly one edit per second per message
if time.monotonic() - last_edit > 1.0:
await placeholder.edit_text(answer)
last_edit = time.monotonic()
if answer:
await placeholder.edit_text(answer)
history[chat_id].append({"role": "assistant", "content": answer})
else:
await placeholder.edit_text("پاسخی دریافت نشد؛ دوباره تلاش کن.")
except Exception as e: # noqa: BLE001
history[chat_id].pop()
await placeholder.edit_text("فعلاً نمیتوانم پاسخ بدهم. چند لحظه بعد دوباره امتحان کن.")
print("AI error:", e)
def main():
app = Application.builder().token(os.environ["TELEGRAM_TOKEN"]).build()
app.add_handler(CommandHandler("start", start))
app.add_handler(CommandHandler("reset", reset))
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, chat))
app.run_polling()
if __name__ == "__main__":
main()
فایل را bot.py ذخیره کنید و با python bot.py اجرا کنید. به ربات پیام بدهید؛ باید ببینید پاسخ بهتدریج کامل میشود. برای عوض کردن مدل فقط متغیر AI_MODEL را عوض کنید؛ این چهار شناسه همین حالا روی درگاه فعالاند:
مقدار AI_MODEL | چه وقت |
|---|---|
gpt-5-mini | پیشفرض؛ فارسی روان با هزینهٔ کم |
deepseek-flash | کمهزینهترین گفتگوی روان برای حجم بالا |
openrouter/anthropic/claude-haiku-4.5 | وقتی پاسخها باید یکدستتر و دقیقتر باشند |
openrouter/google/gemini-2.5-flash | اسناد طولانی و خواندن تصویر |
چند نکته دربارهٔ استریم در تلگرام
تلگرام برای ویرایش پیام محدودیت نرخ دارد؛ اگر با هر تکهٔ متن پیام را ویرایش کنید، بعد از چند ثانیه خطای Flood میگیرید. برای همین در کد بالا فقط هر یک ثانیه ویرایش میکنیم و در انتها یک ویرایش نهایی داریم. نکتهٔ دوم، قالببندی است: اگر مدل Markdown تولید کند و شما parse_mode بگذارید، یک ستارهٔ بازمانده کل پیام را خراب میکند. سادهترین راه همان است که در پیام سیستم گفتیم: بدون Markdown. اگر قالببندی میخواهید، خروجی را در انتها به HTML تلگرام تبدیل و escape کنید. نکتهٔ سوم، طول پیام: تلگرام هر پیام را به حدود ۴ هزار کاراکتر محدود میکند؛ با max_tokens پاسخ را کوتاه نگه دارید یا متن بلند را در چند پیام بفرستید.
قدم پنجم: اجرای دائمی روی سرور
روی سرور لینوکسی، یک سرویس systemd بسازید تا ربات بعد از راهاندازی مجدد هم بالا بیاید:
[Unit]
Description=Persian AI Telegram bot
After=network-online.target
[Service]
WorkingDirectory=/opt/bot
EnvironmentFile=/opt/bot/.env
ExecStart=/opt/bot/.venv/bin/python bot.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
مقادیر توکن و کلید را در فایل .env بگذارید (نه در کد و نه در مخزن گیت)، سرویس را با systemctl enable --now فعال کنید و لاگ را با journalctl -u ببینید. اگر IP سرور ثابت است، همان IP را در فهرست مجاز کلید نِت اَرز قرار دهید تا کلید حتی در صورت لو رفتن، از جای دیگری کار نکند.
قدم ششم: سهمیهٔ روزانه برای هر کاربر
ربات عمومی بدون سهمیه، دعوتنامهٔ رسمی برای سوءاستفاده است؛ یک نفر با یک اسکریپت ساده میتواند در یک شب بودجهٔ ماه را مصرف کند. سادهترین محافظ، شمارندهٔ روزانه در حافظه است که پیش از فراخوانی مدل بررسی میشود:
from datetime import date
DAILY_LIMIT = 40
usage = defaultdict(int) # key: (user_id, date)
def allowed(user_id):
key = (user_id, date.today().isoformat())
if usage[key] >= DAILY_LIMIT:
return False
usage[key] += 1
return True
در ابتدای تابع chat اگر allowed(update.effective_user.id) نادرست بود، پیام کوتاهی بفرستید و برگردید. برای رباتهای بزرگتر، شمارنده را در Redis نگه دارید تا با راهاندازی مجدد صفر نشود. این سهمیه در کنار سقف هزینهٔ کلید در پنل نِت اَرز، دو لایهٔ دفاعی مستقل میسازد.
Polling یا Webhook؟
کد نمونه از polling استفاده میکند که برای شروع و رباتهای چند هزار کاربری کاملاً کافی است و به دامنه و گواهی SSL نیاز ندارد. اگر ترافیک به دهها پیام در ثانیه رسید یا میخواهید ربات را کنار وبسرور موجود اجرا کنید، به Webhook مهاجرت کنید؛ کتابخانه همین کار را با چند خط تنظیم پشتیبانی میکند و منطق پاسخدهی تغییری نمیکند.
هزینهاش چقدر میشود؟
هر پیام کاربر در این ربات حدود ۷۰۰ تا ۱٬۲۰۰ توکن ورودی (پیام سیستم بهعلاوهٔ تاریخچهٔ کوتاه) و ۱۵۰ تا ۳۰۰ توکن خروجی مصرف میکند. با نرخ رسمی gpt-5-mini (حدود ۰٫۲۵ و ۲ دلار برای هر میلیون توکن ورودی و خروجی) هر پیام حدود یکدهم سنت و ۵ هزار پیام در ماه حدود ۴ دلار تمام میشود؛ با deepseek-flash کمی کمتر و با مدلهای سبکتر باز هم کمتر. قیمت تومانی نِت اَرز برای هر مدل در صفحهٔ مدلها است و روش دقیق محاسبه را در راهنمای توکن و هزینه نوشتهایم. درخواست ناموفق هزینه ندارد و اگر ربات عمومی است، حتماً برای کلیدش سقف هزینه بگذارید.
ارتقاهای بعدی
- پیام صوتی: فایل صوتی کاربر را با مسیر
audio/transcriptionsو مدلی مثلgpt-4o-mini-transcribeبه متن تبدیل کنید و همان متن را به مدل چت بدهید. - عکس: تصویر را با قالب
image_urlبهopenrouter/google/gemini-2.5-flashبفرستید؛ خواندن فاکتور و توضیح تصویر همینطور ساخته میشود. نمونهاش در راهنمای API جمینای است. - دانش اختصاصی: با Embedding و بازیابی (RAG) ربات را روی اسناد خودتان متمرکز کنید؛ نمونهٔ کامل در راهنمای چتبات با دیپسیک آمده است.
- سهمیهٔ هر کاربر: تعداد پیام هر کاربر در روز را بشمارید تا یک نفر بودجهٔ همه را مصرف نکند.
- حافظهٔ ماندگار: تاریخچه را بهجای حافظهٔ فرایند در Redis یا SQLite ذخیره کنید تا با راهاندازی مجدد از بین نرود.
امنیت در یک نگاه
کلید API و توکن ربات هرگز در مخزن کد قرار نگیرد؛ کلید عملیاتی سقف هزینه و IP مجاز داشته باشد؛ ورودی کاربر مستقیم در دستور سیستم تزریق نشود؛ و برای کاربران ناشناس سهمیه بگذارید. با همین چند قاعده، رباتی که امروز ساختید فردا با هزار کاربر هم بیدردسر کار میکند. برای تصویر کاملتر از امکانات پنل، راهنمای API هوش مصنوعی با پرداخت ریالی و مستندات فنی را ببینید؛ و اگر اعضای تیم برای کار روزانه به رابط چت نیاز دارند، اشتراکهای دستهٔ اکانت هوش مصنوعی جدا از API در دسترس است.
نسخهٔ قابل اجرای ربات در گیتهاب
اگر ترجیح میدهید بهجای کپی از صفحه، از یک پروژهٔ آماده شروع کنید، ai-api-examples/telegram-bot یک ربات کوچک با long polling است که بدون وبسرور و چارچوب اضافه اجرا میشود و چند نوبت آخر هر گفتوگو را نگه میدارد. دو متغیر محیطی میخواهد، TELEGRAM_BOT_TOKEN و NETARZ_API_KEY، و با pip install -r requirements.txt آماده است. مدل را با NETARZ_MODEL عوض کنید. سقف روزانهٔ هر کاربر و استریمی که اینجا ساختیم را میتوانید روی همان فایل اضافه کنید. بقیهٔ مخزنهای ما در کدهای متنباز نِت اَرز فهرست شدهاند.
آموزشهای کاربردی در گیسو
گیسو برند هوش مصنوعی نِت اَرز است، با همین حساب و همین اعتبار. این راهنماها قدمبهقدم نشان میدهند همین کار را چطور با هوش مصنوعی انجام دهید.
پرسشهای پرتکرار
برای این ربات حتماً به سرور خارج از ایران نیاز دارم؟
API نِت اَرز از داخل ایران بدون مشکل کار میکند، اما اتصال به API خود تلگرام از IP ایرانی محدود است. یا ربات را روی سرور مجازی خارج از ایران اجرا کنید یا فقط برای بخش تلگرام پروکسی تنظیم کنید.
کدام مدل برای ربات تلگرام فارسی مناسبتر است؟
برای شروع gpt-5-mini یا deepseek-flash؛ هر دو فارسی روان و هزینهٔ پایین دارند. اگر پاسخها باید بسیار یکدست باشند openrouter/anthropic/claude-haiku-4.5 را امتحان کنید و برای کار با اسناد طولانی openrouter/google/gemini-2.5-flash. مدل را از متغیر محیطی بخوانید تا بدون تغییر کد عوض شود.
چرا هنگام استریم خطای Flood از تلگرام میگیرم؟
تلگرام ویرایش مکرر یک پیام را محدود میکند. پیام را حداکثر هر یک ثانیه ویرایش کنید (همان کاری که کد نمونه انجام میدهد) و در پایان یک ویرایش نهایی با متن کامل بفرستید.
هزینهٔ هر پیام ربات چقدر است؟
با مدلهای سبک، هر پیام حدود یکدهم سنت با نرخ رسمی؛ یعنی چند هزار پیام در ماه با چند دلار اعتبار. عدد دقیق به مدل و طول پیامها وابسته است؛ قیمت تومانی هر مدل در صفحهٔ مدلها و روش محاسبه در راهنمای توکن آمده است.
میتوانم پیام صوتی و عکس را هم پشتیبانی کنم؟
بله. صوت را با مسیر audio/transcriptions به متن تبدیل کنید و عکس را با قالب image_url به مدلی مثل openrouter/google/gemini-2.5-flash بدهید. هر دو با همان کلید و اعتبار کار میکنند و در مستندات فنی توضیح داده شدهاند.
نظر خوانندگان
هنوز نظری ثبت نشده. اگر این مقاله پرسشتان را جواب داد یا جای چیزی در آن خالی ماند، همینجا بنویسید.