בקשות להחזר (Dialogflow)

אפשרויות נוספות ב-Dialogflow

לוחצים על Continue (המשך) כדי לייבא את דוגמת Reprompts ב-Dialogflow. לאחר מכן, פועלים לפי כדי לפרוס ולבדוק את הדוגמה:

  1. מזינים שם של נציג ויוצרים סוכן חדש ב-Dialogflow לדוגמה.
  2. כשהייבוא של הנציג מסתיים, לוחצים על מעבר לנציג.
  3. בתפריט הניווט הראשי עוברים אל Fulfillment (מילוי).
  4. מפעילים את העורך המוטבע ולוחצים על פריסה. כלי העריכה מכיל את הדוגמה
  5. בתפריט הניווט הראשי, עוברים אל Integrations, ואז לוחצים על Google Assistant.
  6. בחלון החלון שנפתח, מפעילים את האפשרות שינויים בתצוגה מקדימה אוטומטית ולוחצים על בדיקה. כדי לפתוח את סימולטור הפעולות.
  7. בסימולטור, מזינים Talk to my test app כדי לבדוק את הטעימה.
המשך

אפשר להשתמש בתכונות הבאות כדי לטפל במקרים שבהם המשתמשים לא מספקים קלט לפעולות שלכם (שגיאות ללא קלט):

  • הודעות ברירת מחדל של המערכת – בקשות אלה יישלחו מחדש למשתמש באופן אוטומטי עם הוראות מוכנות מראש שכלליות לכל המקרים.
  • הודעות דינמיות – הצהרה על כך שאתם רוצים לטפל ב-repromps ולקבל Intent (Actions SDK) או אירוע (Dialogflow) בכל פעם אין קלט, לכן אפשר לטפל בכל מקרה לגופו.

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

כברירת מחדל, כשמחזירים תגובה ל-Assistant, המערכת משתמשת בקשות ברירת מחדל שבהן המשתמשים יתבקשו לחזור על הקלט או להקליד אותו שוב.

Dialogflow

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

התראות דינמיות

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

Dialogflow

יש שני סוגים של אובייקטים מסוג Intent ללא קלט:

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

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

כדי לטפל באירועים ללא קלט:

  1. בחלונית הניווט הימנית, לוחצים על אובייקטים מסוג Intent.
  2. ליצור כוונה רגילה או כוונה נורמלית בהמשך.
    • לאובייקטים רגילים של Intent: לוחצים על הסמל + לצד התפריט Intent. ונותנים לכוונה שם, למשל "Reprompt".

    • לכוונות המשך: מעבירים את העכבר מעל הכוונה שאתם רוצים להתאים אישית את הבקשה ללא קלט, וללחוץ על Add and continueupIntent > בהתאמה אישית. נוצרת Intent חדש מתחת ל-Intent המקורי.

  3. לוחצים על ה-Intent החדש שנוצר כדי לפתוח את עורך ה-Intent.
  4. לוחצים על הקטע אירועים ומזינים "actions_intent_NO_INPUT" לתוך השדה הוספת אירוע.
  5. בקטע פעולות מזינים שם פעולה או משתמשים בשם שמופיע למעלה. כברירת מחדל. בדוגמה הזו נשתמש ב-'no.input'.

  6. לוחצים על שמירה.
  7. בחלונית הניווט הימנית, לוחצים על Integrations (שילובים).
  8. בוחרים באפשרות Google Assistant ולוחצים על בדיקה כדי לבצע מוודאים שהשינויים משתקפים בפרויקט הפעולות.

אם לא מזינים קלט למטרה הזו, אפשר להשתמש את מילוי הבקשה כדי להחזיר תשובה מתאימה או ליצור תשובה ב-Dialogflow. לדוגמה, הנה קוד מילוי הזמנה שמשתמש בספריית הלקוח כדי לטיפול ב-Intent רגיל ללא קלט שנקרא "Reprompt".

Node.js

const {dialogflow} = require('actions-on-google');
const functions = require('firebase-functions');

const app = dialogflow({debug: true});

app.intent('Reprompt', (conv) => {
  const repromptCount = parseInt(conv.arguments.get('REPROMPT_COUNT'));
  if (repromptCount === 0) {
  conv.ask(`What was that?`);
  } else if (repromptCount === 1) {
  conv.ask(`Sorry I didn't catch that. Could you repeat yourself?`);
  } else if (conv.arguments.get('IS_FINAL_REPROMPT')) {
  conv.close(`Okay let's try this again later.`);
  }
});

exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);

Java

package com.example;

import com.google.actions.api.ActionRequest;
import com.google.actions.api.ActionResponse;
import com.google.actions.api.DialogflowApp;
import com.google.actions.api.ForIntent;
import com.google.actions.api.response.ResponseBuilder;

public class MyActionsApp extends DialogflowApp {

  @ForIntent("Reprompt")
  public ActionResponse reprompt(ActionRequest request) {
    ResponseBuilder responseBuilder = getResponseBuilder(request);
    int repromptCount = request.getRepromptCount();
    String response;
    if (repromptCount == 0) {
      response = "What was that?";
    } else if (repromptCount == 1) {
      response = "Sorry, I didn't catch that. Could you repeat yourself?";
    } else {
      responseBuilder.endConversation();
      response = "Okay let's try this again later.";
    }
    return responseBuilder.add(response).build();
  }
}

בקשת JSON

הערה: קובץ ה-JSON שבהמשך מתאר בקשת webhook.

{
  "responseId": "f26a9188-4998-42eb-ac16-d0e6e273b137-712767ed",
  "queryResult": {
    "queryText": "actions_intent_NO_INPUT",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "fulfillmentText": "Webhook failed for intent: Reprompt",
    "fulfillmentMessages": [
      {
        "text": {
          "text": [
            "Webhook failed for intent: Reprompt"
          ]
        }
      }
    ],
    "outputContexts": [
      {
        "name": "projects/df-reprompts-kohler/agent/sessions/ABwppHFi9Dpwy6KiEtS0UIPDNVfa7mlkrPIEZRlikFkjuN_4SGPixgX8OCatpXu38ln7VG43-nk-7veZWhds3nLljA/contexts/actions_capability_media_response_audio"
      },
      {
        "name": "projects/df-reprompts-kohler/agent/sessions/ABwppHFi9Dpwy6KiEtS0UIPDNVfa7mlkrPIEZRlikFkjuN_4SGPixgX8OCatpXu38ln7VG43-nk-7veZWhds3nLljA/contexts/actions_capability_account_linking"
      },
      {
        "name": "projects/df-reprompts-kohler/agent/sessions/ABwppHFi9Dpwy6KiEtS0UIPDNVfa7mlkrPIEZRlikFkjuN_4SGPixgX8OCatpXu38ln7VG43-nk-7veZWhds3nLljA/contexts/actions_capability_audio_output"
      },
      {
        "name": "projects/df-reprompts-kohler/agent/sessions/ABwppHFi9Dpwy6KiEtS0UIPDNVfa7mlkrPIEZRlikFkjuN_4SGPixgX8OCatpXu38ln7VG43-nk-7veZWhds3nLljA/contexts/google_assistant_input_type_voice"
      },
      {
        "name": "projects/df-reprompts-kohler/agent/sessions/ABwppHFi9Dpwy6KiEtS0UIPDNVfa7mlkrPIEZRlikFkjuN_4SGPixgX8OCatpXu38ln7VG43-nk-7veZWhds3nLljA/contexts/actions_intent_no_input",
        "parameters": {
          "REPROMPT_COUNT": 2,
          "IS_FINAL_REPROMPT": true
        }
      }
    ],
    "intent": {
      "name": "projects/df-reprompts-kohler/agent/intents/75dfd97d-6368-4436-9533-70f05ae76c96",
      "displayName": "Reprompt"
    },
    "intentDetectionConfidence": 1,
    "languageCode": "en"
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "user": {
        "locale": "en-US",
        "userVerificationStatus": "VERIFIED"
      },
      "conversation": {
        "conversationId": "ABwppHFi9Dpwy6KiEtS0UIPDNVfa7mlkrPIEZRlikFkjuN_4SGPixgX8OCatpXu38ln7VG43-nk-7veZWhds3nLljA",
        "type": "ACTIVE",
        "conversationToken": "[]"
      },
      "inputs": [
        {
          "intent": "actions.intent.NO_INPUT",
          "rawInputs": [
            {
              "inputType": "VOICE"
            }
          ],
          "arguments": [
            {
              "name": "REPROMPT_COUNT",
              "intValue": "2"
            },
            {
              "name": "IS_FINAL_REPROMPT",
              "boolValue": true
            }
          ]
        }
      ],
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          },
          {
            "name": "actions.capability.ACCOUNT_LINKING"
          },
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          }
        ]
      },
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            },
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.WEB_BROWSER"
            }
          ]
        }
      ]
    }
  },
  "session": "projects/df-reprompts-kohler/agent/sessions/ABwppHFi9Dpwy6KiEtS0UIPDNVfa7mlkrPIEZRlikFkjuN_4SGPixgX8OCatpXu38ln7VG43-nk-7veZWhds3nLljA"
}

תגובה בפורמט JSON

הערה: קובץ ה-JSON שבהמשך מתאר תגובת webhook.

{
  "payload": {
    "google": {
      "expectUserResponse": false,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "Okay let's try this again later."
            }
          }
        ]
      }
    }
  }
}

Actions SDK

כדי לטפל באובייקטים מסוג Intent ללא קלט:

  1. באובייקט conversations בתוך חבילת הפעולות, מצהירים שרוצים לקבל את הכוונה מסוג actions.intent.NO_INPUT בכל פעם שהמשתמש לא מספק מהקלט.
    {
      a"ctions:" [
        {
          d"escription:" D"efault Welcome Intent,"
          n"ame:" M"AIN,"
          f"ulfillment:" {
            c"onversationName:" c"onversation_1
    "      },
          i"ntent:" {
            n"ame:" a"ctions.intent.MAIN
    "      }
        }
      ],
      c"onversations:" {
        c"onversation_1:" {
          n"ame:" c"onversation_1,"
          u"rl:" Y"OUR_FULFILLMENT_URL,"
          i"nDialogIntents:" [
            {
              n"ame:" a"ctions.intent.NO_INPUT
    "        }
          ]
        }
      }
    }a
  2. כש-Assistant לא מקבלת קלט מהמשתמש, יתקבלו את הכוונה ללא קלט בבקשה הבאה למילוי ההזמנות. לאחר מכן אפשר לעבד את הכוונה ולהחזיר תגובה מתאימה. הנה דוגמה:

    Node.js

    const {actionssdk} = require('actions-on-google');
    const functions = require('firebase-functions');
    
    const app = actionssdk({debug: true});
    
    app.intent('actions.intent.MAIN', (conv) => {
      conv.ask(`Hi! Try this sample on a speaker device, ` +
        `and stay silent when the mic is open. If trying ` +
        `on the Actions console simulator, click the no-input ` +
        `button next to the text input field.`);
    });
    
    app.intent('actions.intent.TEXT', (conv, input) => {
      conv.ask(`You said ${input}`);
      conv.ask(`Try this sample on a speaker device, ` +
        `and stay silent when the mic is open. If trying ` +
        `on the Actions console simulator, click the no-input ` +
        `button next to the text input field.`);
    });
    
    app.intent('actions.intent.NO_INPUT', (conv) => {
      const repromptCount = parseInt(conv.arguments.get('REPROMPT_COUNT'));
      if (repromptCount === 0) {
        conv.ask(`What was that?`);
      } else if (repromptCount === 1) {
        conv.ask(`Sorry I didn't catch that. Could you repeat yourself?`);
      } else if (conv.arguments.get('IS_FINAL_REPROMPT')) {
        conv.close(`Okay let's try this again later.`);
      }
    });
    
    exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);

    Java

    package com.example;
    
    import com.google.actions.api.ActionRequest;
    import com.google.actions.api.ActionResponse;
    import com.google.actions.api.ActionsSdkApp;
    import com.google.actions.api.ConstantsKt;
    import com.google.actions.api.ForIntent;
    import com.google.actions.api.response.ResponseBuilder;
    import com.google.actions.api.response.helperintent.Confirmation;
    import com.google.actions.api.response.helperintent.DateTimePrompt;
    import com.google.actions.api.response.helperintent.Permission;
    import com.google.actions.api.response.helperintent.Place;
    import com.google.api.services.actions_fulfillment.v2.model.DateTime;
    import com.google.api.services.actions_fulfillment.v2.model.Location;
    
    public class MyActionsApp extends ActionsSdkApp {
    
      @ForIntent("actions.intent.MAIN")
      public ActionResponse welcome(ActionRequest request) {
        ResponseBuilder responseBuilder = getResponseBuilder(request);
        responseBuilder.add("Hi! Try this sample on a speaker device, and stay silent when the mic is open. If trying on the Actions console simulator, click the no-input button next to the text input field.");
        return responseBuilder.build();
      }
    
      @ForIntent("actions.intent.TEXT")
      public ActionResponse fallback(ActionRequest request) {
        ResponseBuilder responseBuilder = getResponseBuilder(request);
        responseBuilder.add("You said " + request.getRawInput().getQuery());
        responseBuilder.add("Try this sample on a speaker device, and stay silent when the mic is open. If trying on the Actions console simulator, click the no-input button next to the text input field.");
        return responseBuilder.build();
      }
    
      @ForIntent("actions.intent.NO_INPUT")
      public ActionResponse reprompt(ActionRequest request) {
        ResponseBuilder responseBuilder = getResponseBuilder(request);
        int repromptCount = request.getRepromptCount();
        String response;
        if (repromptCount == 0) {
          response = "What was that?";
        } else if (repromptCount == 1) {
          response = "Sorry, I didn't catch that. Could you repeat yourself?";
        } else {
          responseBuilder.endConversation();
          response = "Okay let's try this again later.";
        }
        return responseBuilder.add(response).build();
      }
    
    }

    בקשת JSON

    הערה: קובץ ה-JSON שבהמשך מתאר בקשת webhook.

    {
      "user": {
        "locale": "en-US",
        "userVerificationStatus": "VERIFIED"
      },
      "conversation": {
        "conversationId": "ABwppHEVDuKUPjdZ4Ud-F2yBXN5ssRg2funUp59hSHQheAi-B5Y3EzehAKFtVwMkduqMRWscUp77ScrDjYnYxISqAM-qOXuXEuCw",
        "type": "ACTIVE",
        "conversationToken": "{\"data\":{}}"
      },
      "inputs": [
        {
          "intent": "actions.intent.NO_INPUT",
          "rawInputs": [
            {
              "inputType": "VOICE"
            }
          ],
          "arguments": [
            {
              "name": "REPROMPT_COUNT",
              "intValue": "2"
            },
            {
              "name": "IS_FINAL_REPROMPT",
              "boolValue": true
            }
          ]
        }
      ],
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          },
          {
            "name": "actions.capability.ACCOUNT_LINKING"
          },
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          }
        ]
      },
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.WEB_BROWSER"
            },
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            }
          ]
        }
      ]
    }

    תגובה בפורמט JSON

    הערה: קובץ ה-JSON שבהמשך מתאר תגובת webhook.

    {
      "expectUserResponse": false,
      "finalResponse": {
        "richResponse": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "Okay let's try this again later."
              }
            }
          ]
        }
      }
    }