מושגים ופתרון בעיות

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

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

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

לסימון SIP, צריך לאפשר את טווח כתובות ה-IP כולו 74.125.88.128/25 ‏ (TCP) דרך יציאה 5672. כדי להגדיר קבוצה מחמירה יותר של כללי חומת אש, אפשר להגביל את אותות ה-SIP רק לשרת SIP אחד או יותר של GTP באזור מסוים:

  • אזור ארה"ב: us.telephony.goog (74.125.88.132)
  • אזור האיחוד האירופי: eu.telephony.goog (74.125.88.133)
  • אזור אסיה-פסיפיק (APAC): ap.telephony.goog (74.125.88.134)
  • אזור דרום אמריקה: sa.telephony.goog (74.125.88.135)

למדיה מסוג RTP, צריך להגדיר כללים של חומת אש כדי לאפשר תעבורה שמיועדת לטווח כתובות ה-IP של CIDR ‏74.125.39.0/24. בדרך כלל היציאות שנדרשות למדיה הן רק 16384-32767 (TCP+UDP), אבל יכול להיות שטווח היציאות הזה יורחב בעתיד.

ספקי SBC או מודלים נתמכים

בטבלה הבאה מפורטים ספקי ה-SBC או הדגמים הנתמכים וגרסאות הקושחה. הוראות מפורטות לשילוב של כל ספק מקושרות בגרסת הקושחה.

ספקים ודגמים גרסאות הקושחה
‫AudioCodes VE SBC גרסה 7.60A.100.022 (SIPREC, ‏ SIP)
‫Avaya Session Border Controller for Enterprise ‫v10.2.1.1-104-25336 (SIPREC, ‏ SIP)
Oracle E-SBC Acme Packet 4600 SCZ9.3.0 GA (Build 46) (SIPREC, SIP)
Ribbon Swe Core SBC ‫v12.01.07R000 (SIPREC, ‏ SIP)
Cisco Unified Border Element (CUBE) גרסה 17.15.4‏ (SIPREC, ‏ SIP)

פרוטוקולים נתמכים של SBC לאותות ולמדיה

פרוטוקול איתות SIP over TLS
מדיה SRTP
הצפנת מדיה SDES
יש תמיכה בסט האלגוריתמים להצפנה של מדיה AES_CM_128_HMAC_SHA1_80, AEAD_AES_256_GCM
פורמטי Codec נתמכים של מדיה ‫G.711 µ-law (PCMU), ‏ G.711 A-law (PCMA), ‏ Opus

כותרות SIP

כשמגדירים פרופיל שיחה ומספר טלפון, נוצר פרופיל שיחה של CCAI עם הערך sipConfig.createConversationOnTheFly שמוגדר ל-true. מזהה השיחה צריך להיווצר באופן דינמי במהלך SIP INVITE באמצעות ערך הכותרת של SIP‏ Call-Info או UUI.

ערך כותרת ה-SIP מצביע על נקודת הקצה של Dialogflow על ידי הגדרתGoogle Cloud מזהה הפרויקט ומזהה השיחה:

  1. מזהה הפרויקט הוא הפרויקט שבו השתמשתם כשהגדרתם פרויקט ב- Google Cloud . Google Cloud
  2. מזהה השיחה צריך להיווצר באופן דינמי על ידי ה-SBC. מזהה השיחה צריך להיות תואם לנוסחת הביטוי הרגולרי [a-zA-Z][a-zA-Z0-9_-]*, עם אורך תווים בטווח של [3,64]. כדי ליצור באופן דינמי את מזהה השיחה, אפשר להשתמש בערך Call-ID ב-SIP INVITE ולהוסיף לו קידומת של אותיות כדי שהוא יעמוד בדרישות של הביטוי הרגולרי שצוין קודם. לדוגמה, אם ערך מזהה השיחה הוא 297363723_79131759_799783510, הוספת הקידומת "CID-" לערך מזהה השיחה תגרום לכך שהוא יעמוד בדרישות של הביטוי הרגולרי [a-zA-Z][a-zA-Z0-9_-]*.

Call-Info כותרת SIP

מוסיפים כותרת SIP בהתאמה אישית בשם Call-Info להודעת ה-SIP INVITE כדי להגדיר באופן ייחודי את מזהה השיחה:

Call-Info: <http://dialogflow.googleapis.com/v2beta1/projects/$PROJECT_ID/conversations/$CONVERSATION_ID>;purpose=Goog-ContactCenter-Conversation

דוגמה:

Call-Info: <http://dialogflow.googleapis.com/v2beta1/projects/gcp-project-id-12345/conversations/CID-297363723_79131759_799783510>;purpose=Goog-ContactCenter-Conversation

UUI כותרת SIP

אם אין תמיכה בהגדרת כותרת SIP מותאמת אישית Call-Info, אפשר להגדיר את כותרת ה-SIP UUI (User-to-User) ב-SIP INVITE כדי להעביר את מזהה השיחה.

משתמשים באותם נתונים שנדרשו ב-Call-Info עם כתובת ה-URL שמקודדת בפורמט הקסדצימלי והמטרה מוגדרת כ-Goog-ContactCenter-Conversation. הדוגמה הבאה היא של כותרת, שבה המחרוזת ההקסדצימלית אחרי פענוח היא http://dialogflow.googleapis.com/v2beta1/projects/gcp-project-id-12345/conversations/CID-297363723_79131759_799783510:

User-to-User: 687474703a2f2f6469616c6f67666c6f772e676f6f676c65617069732e636f6d2f763262657461312f70726f6a656374732f6763702d70726f6a6563742d69642d31323334352f636f6e766572736174696f6e732f4349442d3239373336333732335f37393133313735395f373939373833353130;encoding=hex;purpose=Goog-ContactCenter-Conversation

אם צריך להעביר נתונים נוספים לסוכן ולהגדיר אותם כפרמטר של הסשן, אפשר לעשות זאת על ידי העברה של רשימה של צמדי מפתח/ערך שמופרדים באמצעות נקודה-ופסיק, מקודדים בפורמט הקסדצימלי ומסתיימים ב-;encoding=hex;purpose=Goog-Session-Param. הפעולה הזו תיצור פרמטר סשן בשם uui-headers שמכיל רשימה של מחרוזות מטען ייעודי (payload) מפוענחות.

לדוגמה, אם צריך להעביר את המחרוזת key1=value1;key2=value2, יישלח כותרת UUI הבאה, שבה המטען הייעודי (payload) הוא הערך המקודד בקידוד הקסדצימלי של key1=value1;key2=value2.

User-to-User: 6B6579313D76616C7565313B6B6579323D76616C756532;encoding=hex;purpose=Goog-Session-Param

כתוצאה מכך, נוצר פרמטר הסשן הבא.

{
    "uui-headers": ["key1=value1;key2=value2"]
}

אם ה-SBC שלכם תומך בשליחת כמה כותרות UUI, אתם יכולים לשלוח מחרוזות נפרדות של צמדי מפתח/ערך לכל כותרת UUI, והן יהיו זמינות כערכים נפרדים בפרמטר uui-headers session.

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

$sys.func.GET($sys.func.SPLIT($sys.func.GET($sys.func.SPLIT($session.params.uui-headers,";"),1),"="),1)

בדוגמה הבאה מוצגת פונקציה שמופעלת מטריגר בבלוקי הקוד של Playbook, למשל: ‫@PlaybookStartHandler, שמופעל כשנכנסים למדריך. פונקציות אחרות קוראות לפונקציה הזו כדי לקבל ערכים מהפרמטר uui-headers.

def _get_fromuui(attribute):
    try:
        uui_headers_src = history.playbook_input.action_parameters['uui-headers']
        # If uui_headers_src is a string, split by ';'
        if isinstance(uui_headers_src, str):
            headers = uui_headers_src.split(';')
        else:
            # If it's a list, join and split
            headers = ';'.join(uui_headers_src).split(';')
        for header in headers:
            header = header.strip()
            if header.lower().startswith(f"{attribute.lower()}="):
                return header[len(attribute) + 1:]
        return ""
    except Exception:
        return ""

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

כותרות x של SIP

אפשר להעביר כותרות SIP שמתחילות ב-x- לסוכן ולהגדיר אותן כפרמטר של סשן. כותרות ה-SIP זמינות בפרמטר של הסשן x-headers. התחילית x- מוסרת משם הכותרת בפרמטר של הסשן.

לדוגמה, אם הודעת ה-SIP INVITE מכילה את ה-header הבא:

x-billing-id: 12345

הפרמטר של הסשן x-headers יכיל:

{
    "x-headers": {
        "billing-id": "12345"
    }
}

כדי לגשת לערך:

$session.params.x-headers.billing-id

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

אם אתם צריכים להעביר מידע ספציפי לסוכנים אנושיים, אתם יכולים להגדיר את מאפיין תווית המדיה של פרוטוקול תיאור הסשן (SDP), עבור זרם פרוטוקול התעבורה בזמן אמת (RTP) של הסוכן האנושי, לערך הנתונים הנדרש. דוגמה: none a=label:7382373482 הנתונים האלה יאוכלסו בשדה sip_recording_media_label ויהיו זמינים בנושא New message notification ב-Pub/Sub שמכיל את התמלילים. מחפשים את השדה sip_recording_media_label בהודעה של pubsub Message.attributes.

הגדרת תפקידי המשתתפים והסדר של זרמי המדיה

כברירת מחדל, זרם המדיה הראשון משויך לתפקיד END_USER משתתף, וזרמי מדיה נוספים משויכים לתפקיד HUMAN_AGENT משתתף.

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

לדוגמה: none http://dialogflow.googleapis.com/v2beta1/projects/gcp-project-id-12345/conversations/CID-297363723_79131759_799783510?roles=HUMAN_AGENT,END_USER

כתובת ה-URL מציינת שלזרם המדיה הראשון צריך להיות התפקיד HUMAN_AGENT ולזרם המדיה השני צריך להיות התפקיד END_USER. אפשר להחיל את פרמטר התפקידים באמצעות Call-Info או UUI כותרת SIP.

הגדרת פרמטרים נוספים בשיחה מסוימת

כדי להגדיר פרמטרים נוספים בשיחה מסוימת, משתמשים בקריאת ה-RPC‏ MatchIntentRequest. אפשר להגדיר את query_params.parameters לזוגות של מפתח וערך שנדרשים ואת query_input.text למשהו כמו 'הגדרת פרמטרים'.

מבצעים את קריאה ל-API אחרי התגובה 200 OK להזמנת ה-SIP הראשונית, שבה השיחה נוצרה. מזהה הסשן של MatchIntentRequest זהה למזהה השיחה שמופיע בכותרת Call-Info בהזמנה.

שימוש ב-SIP REFER כדי להעביר שיחה לנקודת קצה SIP

כדי להעביר שיחה מנציג וירטואלי לנקודת קצה של SIP, משתמשים בשיטת SIP REFER. כוללים מטען ייעודי (payload) בשדה Live agent handoff ומגדירים את השדה Telephony transfer call למספר שמוגדר בשדה SIP REFER Refer-To של השיחה היוצאת. המטען הייעודי (payload) שלכם Live agent handoff צריך להיראות בערך כמו בדוגמת הקוד הבאה.

{
    "sip-refer": true
}

אם צריך להעביר נתונים מ-Dialogflow CX, אפשר להשתמש בכותרות UUI ובכותרות x כדי להעביר מחרוזות של נתונים. אם רוצים לבצע SIP REFER ולהעביר 2 זוגות של ערכי מפתח בכותרת UUI ו-2 כותרות x, אפשר להשתמש במטען ייעודי (payload) של Live agent handoff שדומה לדוגמת הקוד הבאה.

{
    "sip-refer": true,
    "uui-headers": [
        "key1=value1;key2=value2"
    ],
    "x-headers": {
        "header1": "value1",
        "header2": "value2"
    }
}

המערכת תיצור SIP REFER עם ה-UUI וכותרות ה-x הבאות.

User-to-User: <hex encoded "key1=value1;key2=value2">;encoding=hex;purpose=Goog-Session-Param
x-header1: value1
x-header2: value2

איך משתמשים ב-SIP INVITE כדי להוסיף לשיחה נקודת קצה אחרת של SIP

כדי להעביר שיחה מלקוח קצה לסוכן אנושי שאפשר להגיע אליו באמצעות נקודת קצה של SIP, צריך להשתמש בשיטת SIP INVITE. כך Google נשארת בנתיב המדיה ואפשר להשתמש בתכונות של Agent Assist. מגדירים את השדה Telephony transfer call למספר שמוגדר בשדה SIP INVITE To של השיחה היוצאת.

אם צריך להעביר נתונים מ-Dialogflow CX, אפשר להשתמש בכותרות UUI ובכותרות x כדי להעביר מחרוזות של נתונים. אם רוצים לבצע SIP INVITE ולהעביר 2 זוגות של ערכי מפתח בכותרת UUI ו-2 כותרות x, אפשר להשתמש במטען ייעודי (payload) של Live agent handoff שדומה לדוגמת הקוד הבאה.

{
    "uui-headers": [
        "key1=value1;key2=value2"
    ],
    "x-headers": {
        "header1": "value1",
        "header2": "value2"
    }
}

הפעולה הזו תיצור SIP INVITE עם ה-UUI וכותרות ה-x הבאות.

User-to-User: <hex encoded "key1=value1;key2=value2">;encoding=hex;purpose=Goog-Session-Param
x-header1: value1
x-header2: value2

העברת נתונים ב-SIP BYE

ניווט אל End Session יפעיל הודעת SIP BYE. אם רוצים להעביר נתונים מ-Dialogflow CX, אפשר להשתמש בכותרות UUI או בכותרות x כדי להעביר מחרוזות של נתונים. הקריאה מנותבת לדף שהוגדר בו מטען ייעודי (Payload) מסוג Live agent handoff, בדומה לדוגמת הקוד הבאה, לפני המעבר ל-End Session.

{
    "uui-headers": [
        "key1=value1;key2=value2"
    ],
    "x-headers": {
        "header1": "value1",
        "header2": "value2"
    }
}

הפעולה הזו תיצור הודעת SIP BYE עם ה-UUI וכותרות ה-x הבאות.

User-to-User: <hex encoded "key1=value1;key2=value2">;encoding=hex;purpose=Goog-Session-Param
x-header1: value1
x-header2: value2

הפעלת פעולה כשמתקשר מרוחק מנתק את השיחה

ה-API החדש של BiDi ‏ (use_bidi_streaming=True ב-ConversationProfile) תומך בהפעלת קריאה לכלי בתוך תוכנית פעולה או קריאה ל-webhook בתוך תהליך, כשהמתקשר מרחוק מנתק את השיחה.

כשמי שהתקשר מרחוק מנתק את השיחה ו-Dialogflow CX מקבל הודעת SIP BYE, מופעל האירוע המותאם אישית sys.remote-call-disconnected. אם יוצרים פונקציית handler עם שם האירוע הספציפי הזה, אפשר להשתמש בה כדי להפעיל קריאה לכלי באמצעות תוכנית פעולה או קריאה ל-webhook במסגרת תהליך.

אפשר לבצע שיחות רק מ-SBC

כדי לדחות שיחות מרשת הטלפוניה הציבורית (PSTN) ולאפשר רק שיחות שמקורן ב-SBC, צריך לעדכן את האובייקט PhoneNumber כדי לציין את ההודעה allowedSipTrunks. אם השילוב משתמש ב-SIP trunk, אפשר לציין רשימה של מזהי SIP trunk ספציפיים. אם ההודעה נוצרת עם רשימה ריקה, כל תא מטען של SIP מותר. אם מקימים חיבור פרטי, צריך לספק את מזהה הספק שהוקצה על ידי צוות הטלפוניה של Google.

פתרון בעיות

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

  1. תיעוד חבילות נתונים ברשת
  2. עקבות ניפוי באגים של SIP עם הכותרת המלאה ו-SIP SDP:
    • ערך מזהה השיחה
    • ערך Call-Info (אם קיים)

תיעוד חבילות נתונים ברשת

בלכידת חבילות הנתונים ברשת צריך להופיע:

  1. לחיצת יד מלאה בת 3 שלבים (SYN,‏ SYN-ACK,‏ ACK) של TCP בין ה-SBC לשרתי ה-SIP של GTP, שמתקשרים דרך יציאת TCP ‏5672. אם חיבור ה-TCP לא נוצר, יכול להיות שיש בעיות כמו:

    • הרשת חוסמת תנועה יוצאת.
    • התקשורת לא נשלחת לאחד משרתי ה-SIP של GTP האזוריים. דרישות הרשת לחיבור טלפוני
    • התקשורת לא נשלחת דרך יציאת TCP‏ 5672.
  2. לחיצת יד מלאה של חיבור TLS עם הפרטים הבאים:

    • פרוטוקול TLS בגרסה 1.2 ואילך שהופעל על ידי ה-SBC.
    • ה-SBC יוזם Client Hello וה-GTP מגיב עם Server Hello.
    • תהליך אימות TLS בו-זמני (mTLS).
      • ה-GTP מגיב עם אישור TLS משלו לשרת, שמאומת על ידי ה-SBC.
      • ה-SBC שולח אישור לקוח TLS משלו, שמאומת על ידי GTP.
    • הערוץ המוצפן נוצר כפי שניתן לראות בהודעה 'לחיצת יד מוצפנת'.
    • הוכחה לכך ש'נתוני האפליקציה' מועברים בערוץ TLS.

    אם יצירת חיבור TLS נכשלה, יכול להיות שהבעיות הן:

    • לא נוצר SIP trunk בצד של GTP.
    • ה-FQDN שהוגדר ב-SIP trunk לא זהה ל-FQDN שמופיע באישור ה-TLS (מאפיין CN או SAN) מ-SBC.
    • אין תמיכה בגרסת TLS, יש תמיכה רק בגרסה 1.2 ומעלה של TLS.
    • סט האלגוריתמים להצפנה (cipher suite) המבוקש לא נתמך. אפשר לעיין בהגדרת ה-TLS של SBC.
    • ספקי אישורי TLS לא מהימנים, אפשר לעיין במאמר בנושא הגדרת TLS ב-SBC.
  3. במעקב הניפוי באגים של SIP צריכים להופיע הנתונים הבאים:

    • כותרת ה-SIP של הלקוח Call-Info מוכנסת בפורמט הבא: none Call-Info: <http://dialogflow.googleapis.com/v2beta1/projects/$PROJECT_ID/conversations/$CONVERSATION_ID>;purpose=Goog-ContactCenter-Conversation

      לדוגמה: none Call-Info: <http://dialogflow.googleapis.com/v2beta1/projects/gcp-project-id-12345/conversations/CID-297363723_79131759_799783510>;purpose=Goog-ContactCenter-Conversation

    • כותרות ה-SIP מציגות את מספר הטלפון בפורמט E.164‏ (‎+16501234567).

    • בכותרות של SIP מוצגות כתובות IP ציבוריות שנעשה בהן שימוש ב-URI של הבקשה ובשדות אחרים של כותרת SIP (לדוגמה, To,‏ From,‏ Via). כתובות IP פרטיות יידחו.

    • פרטי החיבור של SIP SDP ‏ (c= ... ) מצוינים עם כתובת IP ציבורית. כתובות IP פרטיות יידחו.

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

    אם מתקבל קוד תגובה לשגיאת SIP:

    • קוד התגובה של שגיאת SIP 400 (לדוגמה, 488 Not Acceptable Here) כנראה מציין ש-GTP דחה כותרת SIP או הגדרת SDP של מדיה SIP.
    • קוד התגובה של שגיאה מסוג SIP 600 (שגיאה מסוג SIP 603 Declined) מצביע כנראה על בעיה שקשורה למכסת השימוש. בדף המכסות והמגבלות מוסבר איך לבקש הגדלה.