Skip to content

المساعد

البادئة: /v1/assistant على الواجهة العامة.

المساعد دردشة متدفقة. يجب أن يعرض العميل الكتل (blocks) من البث ومن الرسائل المحفوظة. لا تخترع أسعاراً أو مخزوناً أو أسماء منتجات.

المصادقة

العميلكيف تُرسل الهوية
عميل مسجّلAuthorization: Bearer <accessToken>
ضيففقط إذا كان GET /v1/initstore.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)

http
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... }

أحداث البث (بالترتيب)

eventdataماذا يفعل العميل
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 محلولة)

التسلسل المعتاد:

  1. message_start
  2. user_message
  3. صفر أو أكثر من text_delta / tool_start / tool_end / block
  4. message_end أو error

أبقِ الاتصال مفتوحاً حتى message_end أو error نهائي ثم أغلق.

كائن الرسالة

يُعاد في GET .../conversations/:id وفي user_message وفي message_end:

الحقلالمعنى
_idمعرّف الرسالة (للتقييم)
conversationIdالمحادثة الأم
roleuser | assistant | system
contentالنص الصريح للدور
blocksبطاقات الواجهة بالترتيب (انظر kind)
feedbackup | down | null
createdAt, updatedAtطوابع ISO

قيم kind للكتل

كل كتلة كائن فيه سلسلة kind. تفرّع على kind واعرض الحقول المطابقة. تجاهل الأنواع المجهولة حتى لا تكسر البطاقات الجديدة التطبيقات القديمة.

kindالحقولالعرض
texttextنص المساعد
productsproducts[]بطاقات منتجات (name محلّى، الأسعار بالفلس، صور)
product_detailproductبطاقة منتج واحد
cart_actionactionId، items[]، status، واختياري estimatedTotalتغيير مقترح على السلة — تأكيد مربوط بـ actionId طالما status هو pending
cart_summarycartالسلة الحالية (نفس شكل GET /v1/cart)
orderorderملخص طلب (_id، orderNumber، status، total، itemCount، thumbnails)
order_statusorderنفس الملخص كتحديث حالة
offersoffers[]، اختياري couponCodeبطاقات عروض
reciperecipe، servings، ingredientCountبطاقة وصفة
faqitems[]أسئلة وأجوبة من محتوى المتجر
categoriescategories[]بطاقات الممرات
brandsbrands[]بطاقات العلامات
delivery_slotsdays[]اختيار الفترة (YYYY-MM-DD كويتي)
delivery_infoاختياري areaName، zoneName، fee، etaMinutesسياق التوصيل الحالي (fee بالفلس)
locationsitems[] من { label, address?, phone?, lat, lng }دبابيس الخريطة / الفروع
handoffticketId، ticketNumberرابط تذكرة الدعم المُنشأة
actionssuggestions[] من { label, prompt }أزرار شرائح: إرسال prompt كالرسالة التالية
errorcode، اختياري messageبطاقة خطأ داخل المحادثة

حالة cart_action

statusالمعنى
pendingاعرض تأكيد. السلة لا تتغيّر حتى ينجح التأكيد
confirmedطُبّق مسبقاً
cancelledأُلغي
expiredانتهت نافذة التأكيد

items[] على cart_action: { productId, variantId, quantity, product? }.

لا تستدعِ مسارات تعديل السلة بنفسك لاقتراحات المساعد. دائماً POST /v1/assistant/actions/:actionId/confirm.

تأكيد إجراء مقترح

http
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.

التحويل إلى الدعم

http
POST /v1/assistant/conversations/{conversationId}/handoff
Content-Type: application/json

{ "subject": "صنف ناقص", "category": "order", "subcategory": "missing_items" }

كل حقول الجسم اختيارية. يشمل results الحقول ticketId وticketNumber وmessage. تصبح status المحادثة handed_off. قد تظهر كتلة handoff في المحادثة.

التقييم

http
POST /v1/assistant/messages/{messageId}/feedback
Content-Type: application/json

{ "feedback": "up" }

feedback هو up أو down أو null (مسح).

قائمة فحص العميل

  1. استدعِ GET /v1/init وأخفِ الدردشة إن كان store.assistant.enabled خاطئاً.
  2. حلّل SSE حسب اسم event؛ حوّل كل سطر data من JSON.
  3. تفرّع بطاقات الواجهة على block.kind.
  4. لـ kind: "cart_action" مع status: "pending" أكّد عبر مسار الإجراءات — لا تعدّل /v1/cart لذلك الاقتراح.
  5. بعد message_end فضّل message.blocks المحلولة على الدلتا الحية إن اختلفا.
  6. لا تخترع بيانات الكتالوج؛ اعرض فقط ما أرسلته الواجهة.