المساعد
البادئة: /v1/assistant على الواجهة العامة.
المساعد دردشة متدفقة. يجب أن يعرض العميل الكتل (blocks) من البث ومن الرسائل المحفوظة. لا تخترع أسعاراً أو مخزوناً أو أسماء منتجات.
المصادقة
| العميل | كيف تُرسل الهوية |
|---|---|
| عميل مسجّل | Authorization: Bearer <accessToken> |
| ضيف | فقط إذا كان GET /v1/init → store.assistant.allowGuests يساوي true |
يحتاج الضيوف مفتاحاً ثابتاً من 32 حرفاً hex: ولّده مرة، احفظه، وأرسل X-Assistant-Guest: <32-hex> مع كل استدعاء للمساعد. بعد دخول OTP تُدمج محادثات الضيف في الحساب؛ يمكن حذف الترويسة.
إن كان الإعدادات ← المساعد enabled: false تفشل كل مسارات المساعد. إن مُنع الضيوف يحصل غير المسجّلين على AUTHENTICATION_REQUIRED.
حدود المعدل: قائمة المحادثات 60/دقيقة، إرسال الرسالة 20/دقيقة.
النقاط
| الطريقة | المسار | المصادقة | الاستجابة | الغرض |
|---|---|---|---|---|
GET | /v1/assistant/conversations | عميل أو ضيف | غلاف JSON | قائمة محادثات بصفحات |
GET | /v1/assistant/conversations/:conversationId | المالك | غلاف JSON | المحادثة + الرسائل مع blocks محلولة |
POST | /v1/assistant/messages | عميل أو ضيف | SSE (text/event-stream) | إرسال دور |
POST | /v1/assistant/actions/:actionId/confirm | المالك | غلاف JSON | تطبيق تغيير مقترح على السلة / التوصيل |
POST | /v1/assistant/conversations/:conversationId/handoff | المالك | غلاف JSON | إنشاء تذكرة دعم من المحادثة |
POST | /v1/assistant/messages/:messageId/feedback | المالك | غلاف JSON | { "feedback": "up" | "down" | null } |
حالة المحادثة status: active | handed_off | closed. تُغلق المحادثة عند سقف الرسائل/الرموز؛ الإرسال التالي يبدأ محادثة جديدة.
إرسال رسالة (SSE)
POST /v1/assistant/messages
Content-Type: application/json
Accept: text/event-stream
Authorization: Bearer <accessToken>
X-Assistant-Guest: <32-hex> # الضيوف على الجوال
{
"conversationId": "665f0c0c0c0c0c0c0c0c0c0f",
"message": "أضف زجاجتين حليب"
}| حقل الجسم | مطلوب | ملاحظات |
|---|---|---|
message | نعم | 1–2000 حرف |
conversationId | لا | احذفه في الرسالة الأولى؛ البث يعيد معرّفاً جديداً |
هذه النقطة ليست غلاف JSON. كل إطار SSE يبدو هكذا:
event: <name>
data: { ...json... }أحداث البث (بالترتيب)
event | data | ماذا يفعل العميل |
|---|---|---|
message_start | { "conversationId": "<id>" } | احفظ معرّف المحادثة |
user_message | { "conversationId", "message" } | اعرض دور المستخدم (message فيه _id وrole: "user" وcontent وblocks وfeedback) |
text_delta | { "delta": "..." } | ألحق بالنص الحي للمساعد |
tool_start | { "name", "callId" } | اختياري: حالة «يجري البحث…» |
tool_end | { "name", "callId", "ok" } | أزل مؤشر الأداة |
block | { "block": { "kind": "...", ... } } | ألحق بطاقة واجهة (انظر الأنواع أدناه) |
error | { "code", "message" } | اعرض الخطأ؛ code هو statusMessage أو رمز شبيه بـ HTTP |
message_end | { "conversationId", "message" } | استبدل الدور الحي برسالة المساعد الكاملة (blocks محلولة) |
التسلسل المعتاد:
message_startuser_message- صفر أو أكثر من
text_delta/tool_start/tool_end/block message_endأوerror
أبقِ الاتصال مفتوحاً حتى message_end أو error نهائي ثم أغلق.
كائن الرسالة
يُعاد في GET .../conversations/:id وفي user_message وفي message_end:
| الحقل | المعنى |
|---|---|
_id | معرّف الرسالة (للتقييم) |
conversationId | المحادثة الأم |
role | user | assistant | system |
content | النص الصريح للدور |
blocks | بطاقات الواجهة بالترتيب (انظر kind) |
feedback | up | down | null |
createdAt, updatedAt | طوابع ISO |
قيم kind للكتل
كل كتلة كائن فيه سلسلة kind. تفرّع على kind واعرض الحقول المطابقة. تجاهل الأنواع المجهولة حتى لا تكسر البطاقات الجديدة التطبيقات القديمة.
kind | الحقول | العرض |
|---|---|---|
text | text | نص المساعد |
products | products[] | بطاقات منتجات (name محلّى، الأسعار بالفلس، صور) |
product_detail | product | بطاقة منتج واحد |
cart_action | actionId، items[]، status، واختياري estimatedTotal | تغيير مقترح على السلة — تأكيد مربوط بـ actionId طالما status هو pending |
cart_summary | cart | السلة الحالية (نفس شكل GET /v1/cart) |
order | order | ملخص طلب (_id، orderNumber، status، total، itemCount، thumbnails) |
order_status | order | نفس الملخص كتحديث حالة |
offers | offers[]، اختياري couponCode | بطاقات عروض |
recipe | recipe، servings، ingredientCount | بطاقة وصفة |
faq | items[] | أسئلة وأجوبة من محتوى المتجر |
categories | categories[] | بطاقات الممرات |
brands | brands[] | بطاقات العلامات |
delivery_slots | days[] | اختيار الفترة (YYYY-MM-DD كويتي) |
delivery_info | اختياري areaName، zoneName، fee، etaMinutes | سياق التوصيل الحالي (fee بالفلس) |
locations | items[] من { label, address?, phone?, lat, lng } | دبابيس الخريطة / الفروع |
handoff | ticketId، ticketNumber | رابط تذكرة الدعم المُنشأة |
actions | suggestions[] من { label, prompt } | أزرار شرائح: إرسال prompt كالرسالة التالية |
error | code، اختياري message | بطاقة خطأ داخل المحادثة |
حالة cart_action
status | المعنى |
|---|---|
pending | اعرض تأكيد. السلة لا تتغيّر حتى ينجح التأكيد |
confirmed | طُبّق مسبقاً |
cancelled | أُلغي |
expired | انتهت نافذة التأكيد |
items[] على cart_action: { productId, variantId, quantity, product? }.
لا تستدعِ مسارات تعديل السلة بنفسك لاقتراحات المساعد. دائماً POST /v1/assistant/actions/:actionId/confirm.
تأكيد إجراء مقترح
POST /v1/assistant/actions/{actionId}/confirm
Authorization: Bearer <accessToken>results:
| الحقل | المعنى |
|---|---|
message | إقرار مترجم |
blocks | بطاقات محدّثة (عادة cart_summary وcart_action بحالة confirmed) |
حتى ينجح هذا الاستدعاء تبقى السلة كما هي. التأكيد للمالك فقط (نفس العميل أو مفتاح الضيف).
أنواع الإجراءات التي قد يقترحها النموذج (الحمولة على الخادم؛ العميل يؤكد فقط):
add_to_cart، update_cart_item، remove_cart_item، apply_coupon، apply_loyalty، add_recipe_to_cart، reorder، select_delivery_area، select_address، clear_cart، clear_coupon، clear_loyalty، set_express.
التحويل إلى الدعم
POST /v1/assistant/conversations/{conversationId}/handoff
Content-Type: application/json
{ "subject": "صنف ناقص", "category": "order", "subcategory": "missing_items" }كل حقول الجسم اختيارية. يشمل results الحقول ticketId وticketNumber وmessage. تصبح status المحادثة handed_off. قد تظهر كتلة handoff في المحادثة.
التقييم
POST /v1/assistant/messages/{messageId}/feedback
Content-Type: application/json
{ "feedback": "up" }feedback هو up أو down أو null (مسح).
قائمة فحص العميل
- استدعِ
GET /v1/initوأخفِ الدردشة إن كانstore.assistant.enabledخاطئاً. - حلّل SSE حسب اسم
event؛ حوّل كل سطرdataمن JSON. - تفرّع بطاقات الواجهة على
block.kind. - لـ
kind: "cart_action"معstatus: "pending"أكّد عبر مسار الإجراءات — لا تعدّل/v1/cartلذلك الاقتراح. - بعد
message_endفضّلmessage.blocksالمحلولة على الدلتا الحية إن اختلفا. - لا تخترع بيانات الكتالوج؛ اعرض فقط ما أرسلته الواجهة.