طلبات إعادة الطلب (Dialogflow)

الاستكشاف في Dialogflow

انقر على متابعة لاستيراد نموذج الطلبات في Dialogflow. بعد ذلك، اتّبِع الخطوات أدناه لنشر النموذج واختباره:

  1. أدخِل اسم وكيل وأنشِئ وكيل Dialogflow جديدًا للنموذج.
  2. بعد الانتهاء من استيراد الوكيل، انقر على الانتقال إلى الوكيل.
  3. من قائمة التنقّل الرئيسية، انتقِل إلى توصيل الطلبات.
  4. فعِّل المحرِّر المضمّن، ثم انقر على نشر. ويتضمّن المحرِّر نموذج الرمز.
  5. من قائمة التنقّل الرئيسية، انتقِل إلى عمليات الدمج، ثم انقر على مساعد Google.
  6. في النافذة المشروطة التي تظهر، فعِّل تغييرات المعاينة التلقائية وانقر على اختبار لفتح محاكي الإجراءات.
  7. في المحاكي، أدخِل Talk to my test app لاختبار العيّنة.
متابعة

يمكنك استخدام الميزات التالية للتعامل مع الحالات التي لا يُدخل فيها المستخدمون مدخلات إلى الإجراءات الخاصة بك (أخطاء عدم الإدخال):

  • الطلبات التلقائية للنظام - تعيد هذه الطلبات إلى المستخدم تلقائيًا إرسال طلبات معدة مسبقًا تكون عامة في جميع الحالات.
  • الطلبات الديناميكية: التصريح بأنّك تريد معالجة طلب إعادة النظر بنفسك، وتلقّي هدف (حزمة تطوير البرامج (SDK) للإجراءات) أو حدث (Dialogflow) في كل مرة يتمّ فيها عدم إدخال أي إدخال، لكي تتمكّن من التعامل معها على أساس كل حالة على حدة.

الطلبات التلقائية للنظام

عند عرض ردّ على "مساعد Google" بشكل تلقائي، يستخدم النظام الطلبات التلقائية للطلب من المستخدمين تكرار الإدخال أو إعادة كتابته.

Dialogflow

يفرض Dialogflow ثلاثة إدخالات كحد أقصى بلا مطابقة وعدم إدخال. عندما تصل المحادثة إلى ثلاث محاولات لجمع البيانات، سينهي موظّف الدعم في Dialogflow المحادثة برد تلقائي. ويتم إدخال عدم مطابقة في Dialogflow عند تشغيل أحد الأغراض الاحتياطية.

الطلبات الديناميكية

يمكن أن تتلقّى حدث intent أو حدث Dialogflow في كل مرة يتعذّر فيها على الإجراء الخاص بك تلقّي أي إدخالات. يسمح لك هذا بعرض رد مختلف بناءً على بعض المنطق، إذا لزم الأمر، وإعادة مطالبة المستخدم بشكل مناسب.

Dialogflow

يمكنك إنشاء نوعين من الأغراض لعدم الإدخال:

  • هدف عادي - لا تنطبق هذه الطريقة أي سياقات، لذا سيتم تشغيلها عندما لا يكون هناك هدف آخر أكثر سياقًا لتشغيله. يُعدّ ذلك مفيدًا للطلبات العامة التي تريد تطبيقها في معظم الحالات.

  • القصد من المتابعة - يتم فرض أغراض المتابعة من خلال سياقات Dialogflow، ما يضمن عدم بدء الطلبات إلا بعد منعطفات معينة من المحادثة. يُعدّ ذلك مفيدًا للطلبات المخصّصة التي تريد تطبيقها على مواقف محدّدة.

لمعالجة أحداث عدم الإدخال:

  1. في شريط التنقّل الأيمن، انقر على Intents.
  2. أنشئ نية عادية أو النية من أجل المتابعة.
    • بالنسبة إلى الأغراض العادية: انقر على رمز + بجانب عنصر القائمة Intent وأدخِل اسمًا للهدف، مثل "إعادة الطلب".

    • بالنسبة إلى أغراض المتابعة: مرِّر مؤشر الماوس فوق الغرض الذي تريد تخصيص طلب عدم الإدخال له وانقر على إضافة الغرض من المتابعة > مخصّص. يتم إنشاء هدف جديد أسفل الغرض الأصلي.

  3. انقر على الغرض الذي تم إنشاؤه حديثًا لفتح محرِّر الأهداف.
  4. انقر على قسم الأحداث وأدخِل "actions_intent_NO_INPUT" في الحقل إضافة حدث.
  5. في قسم الإجراءات، أدخِل اسم الإجراء أو استخدِم الاسم المقدَّم تلقائيًا. في هذا المثال، سنستخدم "no.input".

  6. انقر على حفظ.
  7. في شريط التنقّل الأيمن، انقر على عمليات الدمج.
  8. اختَر مساعد Google وانقر على اختبار للتأكّد من أنّ التغييرات تظهر في مشروع المهام.

عند عدم حدوث أي إدخال لهذا الغرض، يمكنك استخدام تنفيذك لعرض رد مناسب أو إنشاء رد في Dialogflow. على سبيل المثال، إليك بعض أكواد التنفيذ التي تستخدم مكتبة العميل للتعامل مع نية عادية لعدم الإدخال تسمى "إعادة الطلب".

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 أدناه يصف طلب الردّ التلقائي على الويب.

{
  "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 أدناه يصف الردّ التلقائي على الويب.

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

حزمة تطوير برامج المهام

لمعالجة أغراض عدم الإدخال:

  1. في عنصر conversations داخل حزمة الإجراءات، وضِّح أنّك تريد تلقّي الغرض actions.intent.NO_INPUT عندما لا يقدّم المستخدم أي إدخال.
    
    {
      "actions": [
        {
          "description": "Default Welcome Intent",
          "name": "MAIN",
          "fulfillment": {
            "conversationName": "conversation_1"
          },
          "intent": {
            "name": "actions.intent.MAIN"
          }
        }
      ],
      "conversations": {
        "conversation_1": {
          "name": "conversation_1",
          "url": "YOUR_FULFILLMENT_URL",
          "inDialogIntents": [
            {
              "name": "actions.intent.NO_INPUT"
            }
          ]
        }
      }
    }
    
  2. عندما لا يتلقّى "مساعد Google" أي معلومات من المستخدم، ستتلقّى الغرض من عدم الإدخال في الطلب التالي لإكمال تنفيذ الطلب. يمكنك بعد ذلك معالجة الهدف وعرض استجابة مناسبة. إليك مثال:

    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 أدناه يصف طلب الردّ التلقائي على الويب.

    {
      "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 أدناه يصف الردّ التلقائي على الويب.

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