מדריך לשילוב של API עם פלטפורמת צ'אט

במדריך הזה מוסבר איך ליצור שילוב של צ'אט בצד השרת באמצעות Apps API. בסיום, השילוב יוכל:

  • אימות ל-Apps API.

  • יצירה או עדכון של משתמש קצה.

  • מתחילים צ'אט עם משתמש הקצה.

  • לקבל ולאמת אירועי webhook מ-Contact Center AI Platform.

  • לשלוח הודעות טקסט לצ'אט.

  • טיפול בענפים אופציונליים כמו ייבוא תמליל של שיחה עם נציג, בחירת תור, ניתוב לסוכן וירטואלי, הפניית שיחות לטיפול ברמה גבוהה יותר וקבצים מצורפים של מדיה.

  • בסיום השיחה, סוגרים את הצ'אט.

המדריך הזה מיועד למפתחים שיוצרים שירות לקצה העורפי שמקשר בין ממשק צ'אט בבעלות הלקוח לבין CCAI Platform. ההנחה היא שאתם יכולים ליצור פרטי כניסה ל-API ב-CCAI Platform, לארח נקודת קצה של webhook ב-HTTPS, לאחסן סודות בצורה מאובטחת ולשלוח בקשות HTTP מהשרת שלכם.

המדריך הזה הוא תוספת לנקודות הקצה (endpoints) של Apps API Chat. אפשר להיעזר בהפניה ל-API כדי לקבל את סכימת הבקשות והתגובות המלאה, ובמדריך הזה כדי לקבל את תהליך ההטמעה המומלץ מקצה לקצה.

הסברים על המונחים

ההגדרות הבאות חלות על המסמך הזה:

  • לקוח: לקוח של CCAI Platform שמטמיע את שילוב הצ'אט בתוכנה שלו.

  • צרכן: האפליקציה בצד השרת שנמצאת בבעלות הלקוח, ששולחת בקשות ל-Apps API ומקבלת אירועי webhook של CCAI Platform.

  • משתמש קצה: האדם שמשתמש בתוכנה של הלקוח כדי להתחיל או להמשיך שיחה עם נציג או עם נציג וירטואלי.

  • Chat: משאב השיחה בפלטפורמת CCAI שנוצר על ידי Apps API.

  • נקודת הקצה של ה-webhook: נקודת הקצה מסוג HTTPS באפליקציית הצרכן שמקבלת אירועים של צ'אט מ-CCAI Platform.

לפני שמתחילים

לפני שמתחילים, חשוב לוודא שיש לכם:

  • פרטי הכניסה של Apps API

    • יוצרים פרטי כניסה ל-API ב-CCAI Platform דרך Settings (הגדרות) > Developer Settings (הגדרות למפתחים) > API Credentials (פרטי כניסה ל-API).

    • אחסון סוד פרטי הכניסה באופן מאובטח. לא לחשוף אותו בקוד של דפדפן או של לקוח לנייד.

  • פרטים של כתובת URL של דייר

    • מזהים את הדומיין ואת דומיין המשנה של פלטפורמת CCAI.

    • כתובת הבסיס של Apps API היא: https://YOUR_SUBDOMAIN.YOUR_DOMAIN/apps/api/v1

  • נקודת הקצה של ה-webhook

    • מארחים נקודת קצה ציבורית של HTTPS שיכולה לקבל בקשות POST מ-CCAI Platform.

    • מגדירים את נקודת הקצה בהגדרות הפיתוח של פלטפורמת CCAI.

    • יוצרים ושומרים את הסודות הראשיים והמשניים של ה-webhook.

  • הגדרות של תור או תפריט

    • לזהות את התור או התפריט שאליהם מגיעות שיחות חדשות.

    • אם אתם משתמשים בנציג וירטואלי לבחירת תור, הגדירו את הנציג הווירטואלי והקצו אותו לתור הכניסה לפני שיוצרים צ'אטים דרך ה-API.

  • זהות משתמש הקצה

    • קובעים באיזה מזהה יציב המערכת תשתמש לכל משתמש קצה.

    • שמירת מזהה משתמש הקצה של CCAI Platform שמוחזר על ידי Apps API.

  • טיפול בהגבלת קצב

    • בפלטפורמת CCAI יש הגבלות על קצב הבקשות ל-Apps API. כדאי להטמיע ניסיונות חוזרים והשהיה לפני ניסיון חוזר בשילוב, ולהימנע משליחת פרצי בקשות לדייר יחיד.

אימות ואבטחת תגובות לפעולות מאתר אחר (Webhook)

השילוב שלכם משתמש בשני נתיבי אימות:

  • אימות של בקשות משרת שלכם ל-CCAI Platform באמצעות Apps API.

  • אימות חתימת ה-webhook לבקשות מ-CCAI Platform לשרת שלכם.

אימות בקשות Apps API

הבקשות משתמשות באימות בסיסי של HTTP. יוצרים אסימון API ב-CCAI Platform בקטע Settings (הגדרות) > Developer Settings (הגדרות למפתחים) > API Credentials (פרטי כניסה ל-API), ומעבירים אותו בשדה password (סיסמה) (מומלץ). אם הדייר שלכם משתמש בנתיב אימות מדור קודם, אתם יכולים להעביר את המפתח של החברה בתור שם המשתמש ואת הסוד של החברה בתור הסיסמה. הוראות מלאות להגדרת האימות מופיעות במאמר הפניית Apps API. בדוגמה הבאה אפשר לראות איך מאמתים בקשה ל-Apps API באמצעות אימות בסיסי:

curl -X GET \
  https://YOUR_SUBDOMAIN.YOUR_DOMAIN/apps/api/v1/chats/{chat_id} \
  -u "YOUR_SUBDOMAIN:YOUR_API_TOKEN" \
  -H "Accept: application/json"

מאחסנים את פרטי הכניסה במאגר סודי בצד השרת, מבצעים רוטציה שלהם בהתאם למדיניות האבטחה שלכם, ואף פעם לא שולחים אותם באפליקציות לנייד או בדפדפני אינטרנט.

אימות בקשות webhook

פלטפורמת CCAI שולחת אירועים של צ'אט לנקודת הקצה של ה-webhook. כל בקשת webhook כוללת:

  • X-Signature

  • X-Signature-Timestamp

הכותרת X-Signature יכולה להכיל חתימה ראשית, חתימה משנית או את שתיהן:

primary=<primary_signature> secondary=<secondary_signature>

כל חתימה היא תקציר הודעה (digest) בקידוד Base64 של HMAC-SHA256. הערך החתום הוא כותרת חותמת הזמן שמשורשרת עם תוכן בקשת ה-JSON הגולמי:

X-Signature-Timestamp + raw_request_body

ב-handler של ה-webhook:

  1. מידע נוסף זמין במאמרים בנושא X-Signature וX-Signature-Timestamp.

  2. אם אחת מהכותרות חסרה, צריך לדחות את הבקשה.

  3. דחייה של חותמות זמן ישנות כדי להפחית את הסיכון להפעלת התקפה חוזרת.

  4. צריך לקרוא את תוכן הבקשה הגולמי לפני שמנתחים את ה-JSON.

  5. מחשבים את החתימה הצפויה באמצעות כל סוד פעיל של webhook.

  6. משווים בין החתימה שהתקבלה לבין החתימה הצפויה באמצעות השוואה בזמן קבוע.

  7. אם יש התאמה לסוד פעיל, מאשרים את הבקשה.

בדוגמה הבאה מוצגת הטמעה של Ruby שממחישה איך מאמתים חתימות של webhook ב-UJET:

require "base64"
require "openssl"
require "active_support/security_utils"

def parse_ujet_signature(header)
  header.to_s.split(/\s+/).each_with_object({}) do |part, result|
    key, value = part.split("=", 2)
    result[key] = value if key && value
  end
end

def expected_signature(secret, timestamp, raw_body)
  Base64.strict_encode64(
    OpenSSL::HMAC.digest(
      OpenSSL::Digest.new("sha256"),
      secret,
      "#{timestamp}#{raw_body}"
    )
  )
end

def secure_match?(received, expected)
  return false if received.nil? || expected.nil?
  return false unless received.bytesize == expected.bytesize

  ActiveSupport::SecurityUtils.secure_compare(received, expected)
end

def verify_ujet_webhook!(request, primary_secret:, secondary_secret:)
  signature_header = request.headers["X-Signature"]
  timestamp = request.headers["X-Signature-Timestamp"]

  return false if signature_header.nil? || timestamp.nil?

  # Optional but recommended: reject stale requests.
  return false if (Time.now.utc - Time.at(timestamp.to_i).utc).abs > 5.minutes

  raw_body = request.body.read
  signatures = parse_ujet_signature(signature_header)

  expected = [
    expected_signature(primary_secret, timestamp, raw_body),
    expected_signature(secondary_secret, timestamp, raw_body)
  ].compact

  received = [
    signatures["primary"],
    signatures["secondary"]
  ].compact

  received.any? do |received_signature|
    expected.any? do |expected_signature_value|
      secure_match?(received_signature, expected_signature_value)
    end
  end
end

אם האימות מצליח, מחזירים במהירות תגובת הצלחה ומעבדים את האירוע באופן אידמפוטנטי. ההודעות שמתקבלות מ-Webhook והתגובות של API יכולות להגיע בסדר שונה, לכן צריך לבנות את האינטגרציה כך שתהיה אפשרות לקבל את אותו שינוי סטטוס יותר מפעם אחת בלי ליצור רשומות כפולות.

תהליך השילוב

בתרשים הבא מוצג תהליך שבו נוצר משתמש קצה, מתחיל צ'אט, מתקבלים אירועים של פלטפורמת CCAI, מתבצע חילוף הודעות והצ'אט מסתיים.

יצירה או עדכון של משתמש הקצה

המטרה: לוודא שיש רשומה של משתמש קצה ב-CCAI Platform לפני שיוצרים את הצ'אט.

נקודת קצה (endpoint)

כדי ליצור או לעדכן משתמש קצה, משתמשים בנקודת הקצה הבאה:

POST /apps/api/v1/end_users

דוגמה לבקשה

בדוגמה הבאה מוצגת גוף בקשה ליצירה או לעדכון של משתמש קצה:

{
  "identifier": "customer-user-12345",
  "email": "customer.user@example.com",
  "name": "Customer User",
  "phone": "+15551234567"
}

מה צריך לאחסן

שומרים במערכת את מזהה משתמש הקצה של CCAI Platform מהתשובה. משתמשים במזהה הזה כשיוצרים צ'אט.

מה קורה אחר כך

  • אם משתמש הקצה לא קיים, פלטפורמת CCAI יוצרת רשומה חדשה.

  • אם משתמש קצה כבר קיים עם אותו מזהה, CCAI Platform מעדכן את הרשומה ומחזיר את פרטי משתמש הקצה הקיים.

יצירת הצ'אט

יעד: פתיחת צ'אט חדש ב-CCAI Platform עבור משתמש הקצה.

נקודת קצה (endpoint)

כדי להתחיל צ'אט חדש, משתמשים בנקודת הקצה הבאה:

POST /apps/api/v1/chats

דוגמה לבקשה

בדוגמה הבאה מוצג גוף בקשה ליצירת צ'אט:

{
  "chat": {
    "menu_id": 123,
    "end_user_id": 456,
    "lang": "en"
  }
}

הקשר אופציונלי לניתוב של סוכן וירטואלי

אם נציג וירטואלי לבחירת תור צריך לקבל הקשר מהאפליקציה, צריך לכלול מטען ייעודי (payload) של הקשר כשיוצרים את הצ'אט, כמו בדוגמה הבאה:

{
  "chat": {
    "menu_id": 123,
    "end_user_id": 456,
    "lang": "en",
    "context": {
      "value": {
        "customer_tier": "gold",
        "issue_type": "billing"
      }
    }
  }
}

נציג וירטואלי יכול להשתמש בערכים מההקשר הזה כדי להחליט לאיזו רשימת המתנה תועבר הצ'אט.

מה קורה אחר כך

  • ‫Apps API מחזיר את מקור המידע של הצ'אט.

  • פלטפורמת CCAI שולחת אירוע chat_created webhook לנקודת הקצה של ה-webhook שהגדרתם.

  • התשובה של ה-API והאירוע של ה-webhook יכולים להגיע בכל סדר. התייחסו לשניהם כעדכונים לאותו רשומה של צ'אט, עם מפתח לפי מזהה הצ'אט.

עיבוד אירועים של webhook ב-Chat

יעד: לשמור על סנכרון בין אפליקציית הצרכן לבין מצב הצ'אט בפלטפורמת CCAI.

נקודת הקצה של ה-webhook מטפלת במחזור החיים של הצ'אט ובאירועי הודעות מפלטפורמת CCAI. לפחות, צריך לציין את החנות:

  • מזהה הצ'אט.

  • סוג האירוע.

  • חותמת הזמן של האירוע.

  • השולח של ההודעה, סוג ההודעה ותוכן ההודעה כשהאירוע מכיל הודעה.

  • נתונים לגבי העברה לטיפול ברמה גבוהה יותר או הפניה לפתרון עצמי, אם האירוע מתאר התנהגות של ניתוב.

התנהגות מומלצת

  • לפני שמבצעים עיבוד של האירוע, צריך לאמת את החתימה של כל webhook.

  • מאחסנים מזהי אירועים שעברו עיבוד או מפתח אירוע דטרמיניסטי, כדי שלא ייווצרו כפילויות בניסיונות חוזרים.

  • מחזירים תגובה מסוג 2xx אחרי אישור האירוע.

  • כשאפשר, מעבדים תופעות לוואי במורד הזרם באופן אסינכרוני.

מה קורה אחר כך

האפליקציה מעדכנת את מצב הצ'אט כשהפלטפורמה של CCAI שולחת אירועים כמו יצירת צ'אט, הודעות נכנסות, הודעות של נציגים, שינויים בהעברת שיחות וסיום צ'אט.

שליחת הודעת טקסט.

המטרה: שליחת הודעה ממשתמש קצה מהאפליקציה לצרכן לצ'אט של פלטפורמת CCAI.

נקודת קצה (endpoint)

משתמשים בנקודת הקצה הבאה כדי לשלוח הודעת טקסט לצ'אט:

POST /apps/api/v1/chats/{chat_id}/message

דוגמה לבקשה

בדוגמה הבאה מוצג גוף בקשה לשליחת הודעת טקסט:

{
  "from_user_id": 456,
  "message": {
    "type": "text",
    "content": "Hello, I need help with my order."
  }
}

מה קורה אחר כך

  • פלטפורמת CCAI מקבלת את ההודעה.

  • ההודעה מופיעה בשיחה עם הנציג או עם הנציג הווירטואלי.

  • נקודת הקצה של ה-webhook מקבלת אירוע הודעה לגבי ההודעה, כולל הודעות שהאפליקציה שלכם שלחה דרך Apps API.

קבלת הודעות והצגתן מ-CCAI Platform

המטרה: הצגת הודעות של סוכן או סוכן וירטואלי בחוויית הצ'אט שנמצאת בבעלות הלקוח.

כשנקודת הקצה של ה-webhook מקבלת אירוע של הודעה:

  1. מאמתים את חתימת ה-webhook.

  2. בודקים אם האירוע חדש.

  3. מזהים את הצ'אט לפי מזהה הצ'אט.

  4. זיהוי השולח וסוג ההודעה.

  5. הצגת ההודעה בממשק המשתמש של הצ'אט שבבעלות הלקוח.

  6. האירוע יישמר כך שרענונים או ניסיונות חוזרים לא יגרמו לאובדן היסטוריית השיחה.

מה קורה אחר כך

בממשק המשתמש של הצ'אט בבעלות הלקוח מוצגות ההודעות שנשלחו על ידי נציגים, נציגים וירטואליים ומשתמשי קצה בסדר הנכון. אם האירועים מגיעים לא לפי הסדר, צריך להשתמש בחותמות הזמן של האירועים ובשכבת ההתמדה שלכם כדי להתאים את סדר התצוגה.

העברה מנציג וירטואלי לנציג שירות אנושי

המטרה: להעביר את הצ'אט מטיפול של סוכן וירטואלי לתור של נציגים אנושיים כשהמשתמש זקוק לעזרה מנציג.

אם השילוב שלכם משתמש בנציג וירטואלי לבחירת תור, צריך להגדיר את הנציג הווירטואלי כך שינתב צ'אטים לתור היעד. אם השרת שלכם יוזם את ההעברה ישירות, צריך להשתמש בנקודת הקצה של Apps API להעברה לטיפול ברמה גבוהה יותר.

נקודת קצה (endpoint)

כדי להעביר צ'אט מסוכן וירטואלי לנציג אנושי, משתמשים בנקודת הקצה הבאה:

POST /apps/api/v1/chats/{chat_id}/escalations

דוגמה לבקשה

בדוגמה הבאה מוצג גוף בקשה להעברת צ'אט לטיפול ברמה גבוהה יותר:

{
  "reason": "by_end_user_ask",
  "force_escalate": false
}

מה קורה אחר כך

  • אם התור ליעד זמין, הצ'אט מועבר לטיפול של נציג.

  • אם התור לא זמין בגלל שעות לא פעילות או עומס יתר, פלטפורמת CCAI יכולה להחזיר או לשלוח אפשרויות להפניית שיחות דרך זרימת הצ'אט.

  • השילוב מציג למשתמש הקצה את האפשרויות הזמינות להפניית שיחות.

תיעוד של בחירה שמונעת העברה לטיפול ברמה גבוהה יותר

המטרה: להודיע ל-CCAI Platform איזו אפשרות להפניית שיחה בחר משתמש הקצה.

כש-CCAI Platform מציע אפשרויות למניעת העברה לטיפול ברמה גבוהה יותר, צריך לתעד את הבחירה של משתמש הקצה בנקודת הקצה של עדכון ההעברה לטיפול ברמה גבוהה יותר.

נקודת קצה (endpoint)

כדי לעדכן רשומת העלאה לטיפול ברמה גבוהה יותר עם בחירת הפניה לפתרון עצמי, משתמשים בנקודת הקצה הבאה:

PATCH /apps/api/v1/chats/{chat_id}/escalations/{escalation_id}

ערכים נתמכים של deflection_channel:

  • email — משתמש הקצה בוחר באפשרות של הפניית האימייל.

  • virtual_agent — משתמש הקצה בוחר להמשיך עם נציג וירטואלי.

  • human_agent — משתמש הקצה בוחר להמשיך להמתין לנציג אנושי. הערך הזה חל רק על העברות שיחה בגלל עומס.

דוגמה לבקשה

בדוגמה הבאה מוצג גוף בקשה לתיעוד של בחירת הפניה:

{
  "deflection_channel": "email"
}

צריך לשלוח לנקודת הקצה הזו רק ערך נתמך של deflection_channel. ‫external_link הוא לא ערך תקין לנקודת הקצה של עדכון ההעלאה לטיפול ברמה גבוהה יותר. במקום זאת, הצ'אט מסתיים כשמשתמש הקצה לוחץ על קישור חיצוני להפניית שיחה.

מה קורה אחר כך

פלטפורמת CCAI מעדכנת את רשומת ההעלאה ומעבירה את הצ'אט בהתאם לאפשרות שנבחרה.

סיום הצ'אט

המטרה: לסגור את הצ'אט כשהשיחה מסתיימת.

נקודת קצה (endpoint)

כדי לסיים שיחה פעילה, משתמשים בנקודת הקצה הבאה:

PATCH /apps/api/v1/chats/{chat_id}/end

דוגמה לבקשה

בדוגמה הבאה מוצג גוף בקשה לסיום צ'אט:

{
  "ended_by_user_id": 456
}

מה קורה אחר כך

  • פלטפורמת CCAI מסיימת את הצ'אט.

  • נקודת הקצה של ה-webhook מקבלת את אירוע מצב הצ'אט הסופי.

  • האפליקציה מסמנת את הצ'אט כהשלמה ומפסיקה לקבל הודעות חדשות של משתמשי קצה בצ'אט הזה.

תהליכים מתקדמים

ההסתעפויות הבאות הן אופציונליות. צריך להטמיע רק את רצפי הפעולות שרלוונטיים לשילוב.

ייבוא תמליל של שיחה מקדימה

משתמשים בתרשים הזרימה הזה אם למשתמש הקצה כבר הייתה שיחה במערכת לפני שיצרתם את הצ'אט של פלטפורמת CCAI, למשל שיחה עם צ'אטבוט.

מוסיפים את מטען הנתונים של התמליל כשיוצרים את הצ'אט. התמליל מספק לסוכן את ההקשר, כך שמשתמש הקצה לא צריך לחזור על מידע.

הפניית ה-API של Apps כוללת את סכימת התמליל המדויקת.

ניתוב צ'אטים באמצעות נציג וירטואלי לבחירת תור

משתמשים בתהליך הזה כשהאפליקציה שולחת את כל הצ'אטים החדשים לתור כניסה ומאפשרת לסוכן וירטואלי להחליט על תור היעד הסופי.

  1. יצירת נציג וירטואלי לבחירת תור.

  2. מקצים את הנציג הווירטואלי לתור הכניסה.

  3. כשיוצרים את הצ'אט, כדאי לכלול בו הקשר.

  4. מגדירים את הנציג הווירטואלי כך שיבדוק את ההקשר ויעביר את הצ'אט לתור הנכון.

  5. טיפול באפשרויות להפניית שיחות אם התור המיועד לא זמין.

שליחת תמונות או סרטונים כקבצים מצורפים

משתמשים בתהליך הזה כשמשתמש הקצה שולח מדיה מממשק המשתמש של הצ'אט שנמצא בבעלות הלקוח.

תהליך העברת המדיה כולל ארבעה שלבים.

שלב 1 – שליחת בקשה לכתובת URL להעלאה עם חתימה מראש

כדי לבקש כתובת URL עם חתימה מראש להעלאת תמונה או סרטון, משתמשים בנקודות הקצה הבאות:

POST /apps/api/v1/chats/{chat_id}/photos/upload
POST /apps/api/v1/chats/{chat_id}/videos/upload

שלב 2 – העלאת הקובץ לכתובת ה-URL של האחסון שהוחזרה

כוללים את הקובץ ואת כל השדות שמוחזרים על ידי CCAI Platform בתגובה presigned-upload.

שלב 3 – הוספת הקובץ שהועלה לצ'אט

כדי להוסיף לצ'אט תמונה או סרטון שהועלו, משתמשים בנקודות הקצה הבאות:

POST /apps/api/v1/chats/{chat_id}/photos
POST /apps/api/v1/chats/{chat_id}/videos

מאחסנים את media_id שמוחזר מ-CCAI Platform. מטענים ייעודיים (payloads) של הודעות צ'אט מפנים למדיה באמצעות מזהה המדיה.

שלב 4 — שליחת המדיה כהודעה

משתמשים בנקודת הקצה הבאה כדי לשלוח הודעת מדיה לצ'אט:

POST /apps/api/v1/chats/{chat_id}/message

דוגמה לבקשה

בדוגמה הבאה מוצג גוף בקשה לשליחת תמונה מצורפת:

{
  "from_user_id": 456,
  "message": {
    "type": "photo",
    "content": {
      "media_id": 789
    }
  }
}

משתמשים בסוג ההודעה video ובסרטון media_id כדי לשלוח הודעות עם סרטונים.

שליחת נתונים בהתאמה אישית במהלך צ'אט

משתמשים בנקודת הקצה הבאה כשהשילוב צריך לצרף הקשר שהוגדר על ידי הלקוח לצ'אט פעיל:

POST /apps/api/v1/chats/{chat_id}/custom_data

במסמכי העיון של Apps API מוגדרים הצורה המדויקת של המטען הייעודי (payload) וההתנהגות של מפתחות שמורים.

עדכון הזהות של משתמש קצה במהלך צ'אט

משתמשים בנקודת הקצה הבאה כשהזהות של משתמש הקצה משתנה או מתגלה אחרי שהשיחה מתחילה:

POST /apps/api/v1/chats/{chat_id}/end_user

לדוגמה, אפשר להשתמש בנקודת הקצה הזו כשמשתמש קצה אנונימי נכנס לחשבון במהלך צ'אט פעיל, והשילוב שלכם צריך את CCAI Platform כדי לשייך את הצ'אט לזהות המעודכנת של משתמש הקצה.

איסוף נתונים של שביעות רצון לקוחות או נתוני דירוג

אם האינטגרציה שלכם אחראית על חוויית הדירוג אחרי הצ'אט, אתם יכולים להשתמש בנקודות הקצה הבאות של דירוג שביעות רצון הלקוחות (CSAT) ודירוג הצ'אט:

GET /apps/api/v1/chats/{chat_id}/csat
GET /apps/api/v1/chats/{chat_id}/rating
PATCH /apps/api/v1/chats/{chat_id}/rating

לכללי הזכאות המדויקים ומטעני הנתונים של הדירוגים, ראו את הפניית ה-API של Apps.