Dialogflow Webhook 形式

ここでは、Actions on Google が Dialogflow v2 を通じてフルフィルメントを呼び出すときの JSON ペイロードの形式について説明します。

Dialogflow を使用してアクションを作成している場合、フルフィルメントは、Actions on Google の会話 Webhook 形式ではなく、独自の標準 Webhook 形式で Dialogflow とやり取りします。Dialogflow Webhook 形式には、会話 Webhook 形式のすべての情報と、コンテキストやパラメータに関する情報などのその他の Dialogflow 固有のデータが含まれています。

Dialogflow Webhook の JSON メッセージの他の例は、この GitHub プロジェクトをご覧ください。

リクエストの本文

Dialogflow からのリクエスト メッセージには、Dialogflow Webhook 形式のデータが含まれています。このオブジェクトには、Actions on Google 固有の情報が含まれています。その内容を以下にまとめます。

  • originalDetectIntentRequest.source 値は「google」です。
  • originalDetectIntentRequest.version は、リクエストに対する Actions on Google のバージョンを示します。
  • originalDetectIntentRequest.payload には、アシスタントからの会話リクエスト JSON など、Actions on Google 固有の情報が含まれています。
  • Conversation.conversationToken フィールドは、Dialogflow Webhook リクエストには含まれていません。代わりに、フルフィルメントは Dialogflow コンテキストを使用して、会話の存続期間全体でデータを永続化できます。

単純な呼び出しリクエストの例

以下のスニペットは、Dialogflow Webhook 形式の呼び出しリクエストの例を示しています。

{
  "responseId": "c4b863dd-aafe-41ad-a115-91736b665cb9",
  "queryResult": {
    "queryText": "GOOGLE_ASSISTANT_WELCOME",
    "action": "input.welcome",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "fulfillmentText": "",
    "fulfillmentMessages": [],
    "outputContexts": [
      {
        "name": "projects/${PROJECTID}/agent/sessions/${SESSIONID}/contexts/google_assistant_welcome"
      },
      {
        "name": "projects/${PROJECTID}/agent/sessions/${SESSIONID}/contexts/actions_capability_screen_output"
      },
      {
        "name": "projects/${PROJECTID}/agent/sessions/${SESSIONID}/contexts/google_assistant_input_type_voice"
      },
      {
        "name": "projects/${PROJECTID}/agent/sessions/${SESSIONID}/contexts/actions_capability_audio_output"
      },
      {
        "name": "projects/${PROJECTID}/agent/sessions/${SESSIONID}/contexts/actions_capability_web_browser"
      },
      {
        "name": "projects/${PROJECTID}/agent/sessions/${SESSIONID}/contexts/actions_capability_media_response_audio"
      }
    ],
    "intent": {
      "name": "projects/${PROJECTID}/agent/intents/8b006880-0af7-4ec9-a4c3-1cc503ea8260",
      "displayName": "Default Welcome Intent"
    },
    "intentDetectionConfidence": 1,
    "diagnosticInfo": {},
    "languageCode": "en-us"
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "isInSandbox": true,
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.SCREEN_OUTPUT"
          },
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          },
          {
            "name": "actions.capability.WEB_BROWSER"
          },
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          }
        ]
      },
      "inputs": [
        {
          "rawInputs": [
            {
              "query": "Talk to my test app",
              "inputType": "VOICE"
            }
          ],
          "intent": "actions.intent.MAIN"
        }
      ],
      "user": {
        "lastSeen": "2018-03-16T22:08:48Z",
        "permissions": [
          "UPDATE"
        ],
        "locale": "en-US",
        "userId": "ABwppHEvwoXs18xBNzumk18p5h02bhRDp_riW0kTZKYdxB6-LfP3BJRjgPjHf1xqy1lxqS2uL8Z36gT6JLXSrSCZ"
      },
      "conversation": {
        "conversationId": "${SESSIONID}",
        "type": "NEW"
      },
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            }
          ]
        }
      ]
    }
  },
  "session": "projects/${PROJECTID}/agent/sessions/${SESSIONID}"
}

単純な会話リクエストの例

以下のスニペットは、ユーザー入力がテキスト文字列である Dialogflow Webhook 形式の会話リクエストの例を示しています。

{
  "responseId": "68efa569-4ba1-4b7f-9b1b-ac2865deb539",
  "queryResult": {
    "queryText": "query from the user",
    "action": "action.name.of.matched.dialogflow.intent",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "outputContexts": [
      {
        "name": "projects/${PROJECTID}/agent/sessions/${SESSIONID}/contexts/actions_capability_screen_output"
      },
      {
        "name": "projects/${PROJECTID}/agent/sessions/${SESSIONID}/contexts/actions_capability_audio_output"
      },
      {
        "name": "projects/${PROJECTID}/agent/sessions/${SESSIONID}/contexts/google_assistant_input_type_keyboard"
      },
      {
        "name": "projects/${PROJECTID}/agent/sessions/${SESSIONID}/contexts/actions_capability_media_response_audio"
      },
      {
        "name": "projects/${PROJECTID}/agent/sessions/${SESSIONID}/contexts/actions_capability_web_browser"
      }
    ],
    "intent": {
      "name": "projects/${PROJECTID}/agent/intents/1f4e5bd9-a670-4161-a22e-2c97b077f29f",
      "displayName": "Name of Dialogflow Intent"
    },
    "intentDetectionConfidence": 1,
    "diagnosticInfo": {},
    "languageCode": "en-us"
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "isInSandbox": true,
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.SCREEN_OUTPUT"
          },
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          },
          {
            "name": "actions.capability.WEB_BROWSER"
          },
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          }
        ]
      },
      "inputs": [
        {
          "rawInputs": [
            {
              "query": "query from the user",
              "inputType": "KEYBOARD"
            }
          ],
          "arguments": [
            {
              "rawText": "query from the user",
              "textValue": "query from the user",
              "name": "text"
            }
          ],
          "intent": "actions.intent.TEXT"
        }
      ],
      "user": {
        "lastSeen": "2017-10-06T01:06:56Z",
        "locale": "en-US",
        "userId": "AI_yXq-AtrRh3mJX5D-G0MsVhqun"
      },
      "conversation": {
        "conversationId": "1522951193000",
        "type": "ACTIVE",
        "conversationToken": "[]"
      },
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            }
          ]
        }
      ]
    }
  },
  "session": "projects/${PROJECTID}/agent/sessions/${SESSIONID}"
}

ヘルパー結果の例

以下のスニペットは、Dialogflow Webhook 形式のヘルパー結果の例を示しています。この例は、Webhook がアシスタントにユーザーの確認を取得する必要があることを示した後のユーザーのレスポンスを示しています。

{
  "responseId": "cb6f5ec2-c26e-4349-b561-a9ddd6a0e495",
  "queryResult": {
    "queryText": "actions_intent_CONFIRMATION",
    "action": "Dialogflow action name of matched intent",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "outputContexts": [
      {
        "name": "projects/${PROJECTID}/agent/sessions/${SESSIONID}/contexts/actions_intent_confirmation",
        "parameters": {
          "CONFIRMATION": true
        }
      }
    ],
    "intent": {
      "name": "projects/${PROJECTID}/agent/intents/1777d616-a5f7-4838-a9a9-870f2956bd14",
      "displayName": "Dialogflow action name of matched intent"
    },
    "intentDetectionConfidence": 1,
    "diagnosticInfo": {},
    "languageCode": "en-us"
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "isInSandbox": true,
      "surface": {},
      "inputs": [
        {
          "rawInputs": [
            {
              "query": "yes",
              "inputType": "VOICE"
            }
          ],
          "arguments": [
            {
              "name": "CONFIRMATION",
              "boolValue": true
            }
          ],
          "intent": "actions.intent.CONFIRMATION"
        }
      ],
      "user": {},
      "conversation": {},
      "availableSurfaces": []
    }
  },
  "session": "projects/${PROJECTID}/agent/sessions/${SESSIONID}"
}

レスポンスの本文

フルフィルメント エンドポイントからアシスタントへの HTTP POST のヘッダーの Content-Type は、application/json にする必要があります。

フルフィルメントが Dialogflow に送信するレスポンス メッセージは、Dialogflow Webhook 形式にする必要があります。

アシスタントと通信するとき、レスポンスには通常、「google」オブジェクトをカプセル化した payload オブジェクトが含まれています。「google」ペイロード オブジェクトには、Actions on Google 固有の情報が含まれています。少なくとも、expectUserResponse フィールドと、richResponse または systemIntent フィールドのいずれかが含まれていなければなりません。

google」ペイロード オブジェクトのキーフィールドは以下の通りです。

フィールド 説明
expectUserResponse フルフィルメントがユーザーのレスポンスを期待するかどうかを示します。会話を継続する場合は値を true に設定し、会話を終了する場合は false に設定します。
userStorage 特定のユーザーに関連付けられた永続データを格納します。合計容量は 10,000 バイトです。
richResponse このフィールドには、アシスタントがレンダリングする音声、テキスト、カード、提案、または構造化データが含まれています。Actions on Google でのリッチ レスポンスの使用方法の詳細については、レスポンスをご覧ください。
systemIntent このフィールドは ExpectedInput.possibleIntents と同じ構造です。フルフィルメントがヘルパー インテントを使用している場合、レスポンスには通常 systemIntent が含まれます。systemIntent 内の possibleIntents フィールドを ExpectedIntent オブジェクトに設定し、inputValueData フィールド名を data に変更する必要があります。

ExpectedIntent オブジェクト内で、以下の値を指定します。

  • intent: ユーザーに提供させる情報の種類を示すヘルパーのインテント名。
  • data: 値の仕様。アシスタントがヘルパーを実行するために必要なデータを説明する文字列です。

たとえば、ユーザーの許可を求めている場合は、intentactions.intent.PERMISSSION に設定し、値仕様の data"@type": "type.googleapis.com/google.actions.v2.PermissionValueSpec" に設定し、その型をフィールドにします。

次のリストは、Dialogflow Webhook レスポンスの systemIntent を設定できるヘルパーの値仕様文字列をまとめたものです。会話制御のための Actions on Google インテントの完全なリストについては、インテント参照をご覧ください。

インテントの名前 Dialogflow イベントの名前 値の仕様 説明
actions.intent.CONFIRMATION actions_intent_CONFIRMATION "@type": "type.googleapis.com/google.actions.v2.ConfirmationValueSpec" ユーザーから確認を取得します(たとえば、「はい」または「いいえ」で答える質問の回答)。
actions.intent.DATETIME actions_intent_DATETIME "@type": "type.googleapis.com/google.actions.v2.DateTimeValueSpec" ユーザーが入力した日時を取得します。
actions.intent.DELIVERY_ADDRESS actions_intent_DELIVERY_ADDRESS "@type": "type.googleapis.com/google.actions.v2.DeliveryAddressValueSpec" ユーザーが入力した配送先住所を取得します。
actions.intent.LINK actions_intent_LINK "@type": "type.googleapis.com/google.actions.v2.LinkValueSpec" Android アプリへのディープリンク フローを要求します。
actions.intent.OPTION actions_intent_OPTION "@type": "type.googleapis.com/google.actions.v2.OptionValueSpec" リストまたはカルーセル UI から選択した項目を取得します。
actions.intent.PERMISSION actions_intent_PERMISSION "@type": "type.googleapis.com/google.actions.v2.PermissionValueSpec" フルネーム、大まかな位置または正確な位置などのユーザー情報を取得します。
actions.intent.SIGN_IN actions_intent_SIGN_IN "@type": "type.googleapis.com/google.actions.v2.SignInValueSpec" ユーザーのアカウントをリンクするためのアカウント リンクフローを要求します。

単純なレスポンス例

以下のスニペットは、Dialogflow Webhook 形式の単純なレスポンスの例を示しています。

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "this is a simple response"
            }
          }
        ]
      }
    }
  }
}

ヘルパーの例

以下のスニペットは、Dialogflow Webhook 形式でヘルパー インテントを使用する例を示しています。この例では、Webhook は actions.intent.OPTIONS ヘルパー インテントを使用して、2 つのオプションからユーザー選択を取得するようにアシスタントに指示しています。

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "Choose a item"
            }
          }
        ]
      },
      "systemIntent": {
        "intent": "actions.intent.OPTION",
        "data": {
          "@type": "type.googleapis.com/google.actions.v2.OptionValueSpec",
          "listSelect": {
            "title": "Hello",
            "items": [
              {
                "optionInfo": {
                  "key": "first title key"
                },
                "description": "first description",
                "image": {
                  "url": "https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png",
                  "accessibilityText": "first alt"
                },
                "title": "first title"
              },
              {
                "optionInfo": {
                  "key": "second"
                },
                "description": "second description",
                "image": {
                  "url": "https://lh3.googleusercontent.com/Nu3a6F80WfixUqf_ec_vgXy_c0-0r4VLJRXjVFF_X_CIilEu8B9fT35qyTEj_PEsKw",
                  "accessibilityText": "second alt"
                },
                "title": "second title"
              }
            ]
          }
        }
      }
    }
  }
}

前の例からのメッセージを受け取ると、アシスタントは一時的に会話を引き継ぎ、与えられたオプションに基づいて選択するようにユーザーに促します。必要なユーザー入力をすべて収集すると、アシスタントは Dialogflow Webhook リクエストでこのヘルパー結果をフルフィルメントに返します。

以下のスニペットは、ユーザーが選択肢から選択した場合のヘルパー結果の例を示しています。

{
  "responseId": "ea166558-615a-48f3-ae5b-7f55d895784b",
  "queryResult": {
    "queryText": "actions_intent_OPTION",
    "action": "",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "fulfillmentText": "",
    "fulfillmentMessages": [],
    "outputContexts": [
      {
        "name": "projects/${PROJECTID}/agent/sessions/${SESSIONID}/contexts/actions_intent_option",
        "parameters": {
          "OPTION": "key of selected item"
        }
      }
    ],
    "intent": {
      "name": "projects/${PROJECTID}/agent/intents/1777d616-a5f7-4838-a9a9-870f2956bd14",
      "displayName": "Dialogflow intent name of matched intent"
    },
    "intentDetectionConfidence": 1,
    "diagnosticInfo": {},
    "languageCode": "en-us"
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "isInSandbox": true,
      "surface": {
        "capabilities": []
      },
      "inputs": [
        {
          "rawInputs": [
            {
              "query": "Title of selected item",
              "inputType": "TOUCH"
            }
          ],
          "arguments": [
            {
              "textValue": "Key of selected item",
              "name": "OPTION"
            }
          ],
          "intent": "actions.intent.OPTION"
        }
      ],
      "user": {},
      "conversation": {},
      "availableSurfaces": []
    }
  },
  "session": "projects/${PROJECTID}/agent/sessions/${SESSIONID}"
}

会話の終了の例

以下のスニペットは、Dialogflow Webhook 形式で会話セッションを終了する単純なレスポンスの例を示しています。レスポンス メッセージ内の expectUserResponse 値が false の場合、それ以上のユーザー入力は期待されておらず、現在の会話を終了する必要があることをアシスタントに通知します。

{
  "payload": {
    "google": {
      "expectUserResponse": false,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "Goodbye!"
            }
          }
        ]
      }
    }
  }
}

ユーザーが標準フレーズを呼び出してアシスタントとの会話を終了したときにデフォルトの動作をオーバーライドする方法については、アプリ終了ガイドをご覧ください。