Skip to Content
مرجع APIگفتگو (Chat)

گفتگو

POST /v1/assistants/:assistantCode/chat

:assistantCode همان مقدار id از GET /v1/assistants است.

بدنه‌ی درخواست

فیلدنوعالزامیمحدودیت‌ها
principalstringبله۱ تا ۲۵۵ کاراکتر
messagestringبله، مگر اینکه attachment باشد۰ تا ۲۰٬۰۰۰ نویسه. برای پیامِ فقط-صدا خالی بگذارید
conversationIdstringخیر۳۲ کاراکتر Hex با حروف کوچک — همان conversationId از یک پاسخ قبلی، برای ادامه‌ی همان مکالمه
newConversationbooleanخیرtrue یک مکالمه‌ی کاملاً تازه برای همین principal شروع می‌کند (روی conversationId غلبه می‌کند)
attachmentobjectخیر{ filename, contentBase64 }. صدا (webm، m4a، mp3، wav، ogg و مانند آن) فقط وقتی روی دستیار acceptVoice روشن است

principal: این مکالمه برای چه کسی است؟

یک کلید API متعلق به کل حساب شماست، اما تقریباً همیشه از طریق آن به بسیاری از کاربران نهاییِ مستقل خودتان خدمت می‌دهید (کاربران اپلیکیشن خودتان، هر کدام یک مکالمه‌ی پلکسیت جداگانه). principal روشی است که با آن به پلکسیت می‌گویید این تماس مشخص برای کدام‌یک از کاربران شماست — رشته‌ای است که خودتان انتخاب می‌کنید (شناسه‌ی کاربر، ایمیل، هر چیز پایدار و یکتا برای آن کاربر در سمت شما).

پیش از رسیدن به موتور گفتگو، به‌صورت داخلی با پیشوند api:<principal> فضانام‌گذاری می‌شود، تا هرگز با شناسه‌های سایر کانال‌ها تداخل نکند (ویجت جاسازی‌شونده از فضانام خودش، u:<endUserId>، استفاده می‌کند) — نیازی نیست خودتان هیچ پیشوندی اضافه کنید، فقط مقداری پایدار و یکتا برای هر کاربر نهایی ارسال کنید.

{ "principal": "user_9f21", "message": "How do I reset my password?" }

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

attachment

برخلاف Endpointهای بارگذاری انبوه اسناد (که multipart/form-data هستند)، بدنه‌ی این مسیر JSON است، پس یک پیوست تکی به‌صورت base64 و درون همان بدنه ارسال می‌شود:

{ "principal": "user_9f21", "message": "What does this error mean?", "attachment": { "filename": "screenshot.png", "contentBase64": "iVBORw0KGgoAAAANSUhEUgAA..." } }

این برای پیوست‌های کوچک و اتفاقیِ درون یک مکالمه (یک اسکرین‌شات، یک قطعه‌ی کوتاه) در نظر گرفته شده — base64 حدود ۳۳٪ سربار اضافه می‌کند، که برای پیوست‌های اندازه‌ی گفتگو قابل قبول است. contentBase64 حداکثر ۷,۰۰۰,۰۰۰ کاراکتر (حدود ۵ مگابایت پس از دیکد) و filename حداکثر ۲۵۵ کاراکتر مجاز است. برای اسناد انبوهِ پایگاه دانش، از Endpointهای بارگذاری اسناد استفاده کنید که همچنان multipart هستند (حداکثر ۱۰ فایل در هر درخواست، هر فایل تا ۲۵ مگابایت).

conversationId: ادامه‌ی یک مکالمه

conversationId یک پاسخ قبلی را بفرستید تا دقیقاً همان مکالمه، همراه با کل زمینه‌ی قبلی، ادامه یابد. اگر نفرستید، آخرین مکالمه‌ی بازِ همان principal ادامه پیدا می‌کند (یا اگر نداشته باشد یکی ساخته می‌شود) و پاسخ همیشه در conversationId می‌گوید کدام بوده است. برای شروع اجباریِ یک مکالمه‌ی تازه و بی‌ربط، "newConversation": true بفرستید. برای الگوی کامل به راهنمای اختصاصی مراجعه کنید.

پاسخ

OutboundReplyResponse:

{ "data": { "conversationId": "9c1e3f5a7b9d2c4e6f8a0b2d4f6a8c0e", "text": "You can reset your password from Settings → Security.", "sources": [ { "fileId": "a1b2c3d4e5f60718293a4b5c6d7e8f90", "path": "/help/password-reset.md", "chunk": 1 } ], "model": "sol", "reasoning": "low", "degraded": false, "quota": { "...": "مبهم، توضیح در ادامه" }, "ui": [], "voice": null }, "response": { "status": "success", "message": "..." } }
فیلدنوعتوضیح
conversationIdstringبرای ادامه‌ی این مکالمه، همین مقدار را به‌عنوان conversationId ارسال کنید.
textstringپاسخ دستیار.
sources{ fileId, path, chunk }[]قطعات سندی که پاسخ بر اساس آن‌ها ساخته شده، در صورت وجود (استنادهای RAG). اگر پاسخ از هیچ سند بارگذاری‌شده‌ای استفاده نکرده باشد، آرایه‌ای خالی است.
modelstringیک key از GET /v1/models — مدلی که واقعاً این پاسخ را سرو کرده.
reasoningstringیکی از none، low، medium، high.
degradedbooleanاگر true باشد، این پاسخ از یک مسیر تنزل‌یافته/جایگزین سرو شده است. ارزش لاگ‌کردن دارد؛ هنوز enum مستند و پایداری برای چرایی آن وجود ندارد.
quotaobjectعیناً از دفتر هزینه‌ی retrieval عبور داده می‌شود. آن را یک شیء مبهم در نظر بگیرید — شکل داخلی آن بخشی از قرارداد این API نیست.
uiobject[]کارت‌هایی که ابزارهای دستیار خواسته‌اند کنار text نشان داده شوند (یک محصول با عکس و قیمت، یک فهرست، یک وضعیت). معمولاً []. بخش اجزای ui را ببینید.
voice{ audioFileId, transcript } | nullفقط وقتی نوبتِ بازدیدکننده صدا بوده. transcript متنی است که از صدا خوانده و در پایگاه ذخیره شده (اگر سکوت بوده null). audioFileId شناسهٔ فایل ضبط‌شده است؛ بایت‌هایش را از GET /assistants/:assistantCode/customer-files/:audioFileId بگیرید (همان کلید API). در غیر این صورت null.

اجزای ui

وقتی دستیار از یک ابزار استفاده می‌کند — مثلاً جستجوی محصول — ابزار می‌تواند علاوه بر چیزی که گفته می‌شود، چیزی هم برای نمایش برگرداند. هر عضو v: 1، یک type و یک fallback متنی ساده دارد:

typeفیلدها
cardtitle، و اختیاری subtitle، body، imageUrl (نشانی http(s)) و fields: { label, value }[]
listاختیاری title، و items: { title, subtitle? }[]
choicesاختیاری prompt، و options: { label, value }[]
statustone (success، error، info) و text
form، confirmاجزای تعاملی ویجت.
{ "v": 1, "type": "card", "title": "گوشی سامسونگ Galaxy A15", "subtitle": "12,000,000 تومان", "body": "موبایل", "imageUrl": "https://cdn.example.com/a15.png", "fields": [{ "label": "رنگ", "value": "آبی" }], "fallback": "گوشی سامسونگ Galaxy A15 — 12,000,000 تومان" }

نوع‌های جدید ممکن است در طول زمان اضافه شوند. نوع‌هایی را که می‌شناسید نمایش دهید و برای هر نوع دیگر fallback را نشان دهید — همیشه هست، پس یک جزء ناشناخته هرگز رابط شما را خراب نمی‌کند.

اجزای form و confirm به جریان تعاملی ویجت نیاز دارند (کسی که یک اقدام را تأیید می‌کند). این API مسیری برای پاسخ دادن به آن‌ها ندارد؛ پس متن fallback را نشان دهید و بگذارید کاربر نهایی با یک پیام معمولی ادامه دهد. ضمناً این Endpoint استریم نمی‌شود: کل پاسخ یک‌جا می‌رسد.

مثال کامل

curl -X POST "https://api.plexit.ir/v1/assistants/<assistantCode>/chat" \ -H "Authorization: Bearer $PLEXIT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "principal": "user_9f21", "message": "How do I reset my password?" }'