Dialogflow API v1, v2 の webhook リクエスト JSON 例

参考

Dialogflow の設定

  • Agent 名: HelloDialogflowAPI2
  • Intent 名: TestIntent1
  • Training phrases:
    • I like green
    • I like red
    • I like blue
  • Parameters:
    • Parameter name: color
    • Entity: @sys.color

呼び出し元

  • Device: Simulator
  • Surface: Phone
  • Language: en-us
  • Location: Googleplex, Mountain View, CA 94043, United States

Webhook リクエスト時に送られる JSON

I like *** をキーボードで入力して呼び出し

v1 API

{
  "originalRequest": {
    "source": "google",
    "version": "2",
    "data": {
      "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"
          }
        ]
      },
      "requestType": "SIMULATOR",
      "inputs": [
        {
          "rawInputs": [
            {
              "query": "I like green",
              "inputType": "KEYBOARD"
            }
          ],
          "arguments": [
            {
              "rawText": "I like green",
              "textValue": "I like green",
              "name": "text"
            }
          ],
          "intent": "actions.intent.TEXT"
        }
      ],
      "user": {
        "lastSeen": "2019-02-11T09:04:57Z",
        "locale": "en-US",
        "userId": "ABwppHGQGr22Z3CnjL-7Hnww_VTTiG9h8n-q9aNsdNlm0OnXPmnX5O8mBi0xJtP5GrhYpQ9gCjJh8khWcmBPuMgnwQ"
      },
      "conversation": {
        "conversationId": "ABwppHH85J9F5oe1VxwSp5TvgkfR-W6DT0Rb_vzAWROIahZIFkKoZHghfajfLrnwSAQqNWYCGVWol7fP1pRRVcVp4A",
        "type": "ACTIVE",
        "conversationToken": "[]"
      },
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            },
            {
              "name": "actions.capability.WEB_BROWSER"
            }
          ]
        }
      ]
    }
  },
  "id": "baa9ed27-e99b-41b0-9d09-35fe3af565ea",
  "timestamp": "2019-02-11T11:26:09.201Z",
  "lang": "en-us",
  "result": {
    "source": "agent",
    "resolvedQuery": "I like green",
    "speech": "",
    "action": "",
    "actionIncomplete": false,
    "parameters": {
      "color": "green"
    },
    "contexts": [
      {
        "name": "actions_capability_screen_output",
        "parameters": {
          "color": "green",
          "color.original": "green"
        },
        "lifespan": 0
      },
      {
        "name": "actions_capability_audio_output",
        "parameters": {
          "color": "green",
          "color.original": "green"
        },
        "lifespan": 0
      },
      {
        "name": "google_assistant_input_type_keyboard",
        "parameters": {
          "color": "green",
          "color.original": "green"
        },
        "lifespan": 0
      },
      {
        "name": "actions_capability_web_browser",
        "parameters": {
          "color": "green",
          "color.original": "green"
        },
        "lifespan": 0
      },
      {
        "name": "actions_capability_media_response_audio",
        "parameters": {
          "color": "green",
          "color.original": "green"
        },
        "lifespan": 0
      }
    ],
    "metadata": {
      "matchedParameters": [
        {
          "dataType": "@sys.color",
          "name": "color",
          "value": "$color",
          "isList": false
        }
      ],
      "isFallbackIntent": "false",
      "intentName": "TestIntent1",
      "isResponseToSlotfilling": false,
      "intentId": "43e7fce7-6325-4087-968d-6a65ed66b34a",
      "webhookUsed": "true",
      "webhookForSlotFillingUsed": "false",
      "nluResponseTime": 23
    },
    "fulfillment": {
      "speech": "",
      "messages": [
        {
          "type": 0,
          "speech": ""
        }
      ]
    },
    "score": 1.0
  },
  "status": {
    "code": 200,
    "errorType": "success"
  },
  "sessionId": "ABwppHH85J9F5oe1VxwSp5TvgkfR-W6DT0Rb_vzAWROIahZIFkKoZHghfajfLrnwSAQqNWYCGVWol7fP1pRRVcVp4A"
}

v2 API

{
  "responseId": "acb3e31d-6d01-47e0-a862-4724a11049af",
  "queryResult": {
    "queryText": "i like blue",
    "parameters": {
      "color": "blue"
    },
    "allRequiredParamsPresent": true,
    "fulfillmentMessages": [
      {
        "text": {
          "text": [
            ""
          ]
        }
      }
    ],
    "outputContexts": [
      {
        "name": "projects/hellodialogflowapi2/agent/sessions/ABwppHFWb_kxnN18WEBdA9fzj55t2I1kIs88kEAwhj2vY4J0xDAEfw9iU-2t48aI3MSIxVEAIfxNZNt-EJvfUibRfA/contexts/actions_capability_screen_output",
        "parameters": {
          "color": "blue",
          "color.original": "blue"
        }
      },
      {
        "name": "projects/hellodialogflowapi2/agent/sessions/ABwppHFWb_kxnN18WEBdA9fzj55t2I1kIs88kEAwhj2vY4J0xDAEfw9iU-2t48aI3MSIxVEAIfxNZNt-EJvfUibRfA/contexts/actions_capability_audio_output",
        "parameters": {
          "color": "blue",
          "color.original": "blue"
        }
      },
      {
        "name": "projects/hellodialogflowapi2/agent/sessions/ABwppHFWb_kxnN18WEBdA9fzj55t2I1kIs88kEAwhj2vY4J0xDAEfw9iU-2t48aI3MSIxVEAIfxNZNt-EJvfUibRfA/contexts/google_assistant_input_type_keyboard",
        "parameters": {
          "color": "blue",
          "color.original": "blue"
        }
      },
      {
        "name": "projects/hellodialogflowapi2/agent/sessions/ABwppHFWb_kxnN18WEBdA9fzj55t2I1kIs88kEAwhj2vY4J0xDAEfw9iU-2t48aI3MSIxVEAIfxNZNt-EJvfUibRfA/contexts/actions_capability_media_response_audio",
        "parameters": {
          "color": "blue",
          "color.original": "blue"
        }
      },
      {
        "name": "projects/hellodialogflowapi2/agent/sessions/ABwppHFWb_kxnN18WEBdA9fzj55t2I1kIs88kEAwhj2vY4J0xDAEfw9iU-2t48aI3MSIxVEAIfxNZNt-EJvfUibRfA/contexts/actions_capability_web_browser",
        "parameters": {
          "color": "blue",
          "color.original": "blue"
        }
      }
    ],
    "intent": {
      "name": "projects/hellodialogflowapi2/agent/intents/43e7fce7-6325-4087-968d-6a65ed66b34a",
      "displayName": "TestIntent1"
    },
    "intentDetectionConfidence": 1.0,
    "languageCode": "en-us"
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "isInSandbox": true,
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.WEB_BROWSER"
          },
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          },
          {
            "name": "actions.capability.SCREEN_OUTPUT"
          },
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          }
        ]
      },
      "requestType": "SIMULATOR",
      "inputs": [
        {
          "rawInputs": [
            {
              "query": "i like blue",
              "inputType": "KEYBOARD"
            }
          ],
          "arguments": [
            {
              "rawText": "i like blue",
              "textValue": "i like blue",
              "name": "text"
            }
          ],
          "intent": "actions.intent.TEXT"
        }
      ],
      "user": {
        "lastSeen": "2019-02-11T05:33:45Z",
        "locale": "en-US",
        "userId": "ABwppHGQGr22Z3CnjL-7Hnww_VTTiG9h8n-q9aNsdNlm0OnXPmnX5O8mBi0xJtP5GrhYpQ9gCjJh8khWcmBPuMgnwQ"
      },
      "conversation": {
        "conversationId": "ABwppHFWb_kxnN18WEBdA9fzj55t2I1kIs88kEAwhj2vY4J0xDAEfw9iU-2t48aI3MSIxVEAIfxNZNt-EJvfUibRfA",
        "type": "ACTIVE",
        "conversationToken": "[]"
      },
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.WEB_BROWSER"
            },
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            }
          ]
        }
      ]
    }
  },
  "session": "projects/hellodialogflowapi2/agent/sessions/ABwppHFWb_kxnN18WEBdA9fzj55t2I1kIs88kEAwhj2vY4J0xDAEfw9iU-2t48aI3MSIxVEAIfxNZNt-EJvfUibRfA"
}

Actions on Google で位置情報を毎回使用したい場合

Actions on Google では、ユーザーの位置情報や名前を取得して使用することが出来る。 が、無制限に使用できるわけではなく、情報を得たい場合はユーザーに許可を申請し、ユーザーがその許可を承認して初めて取得できる。 つまり、その為だけにユーザーとのやりとりが一度増えてしまう。

更に、この承認は当該やりとりのみ有効なので、次回のやりとりではまた許可の申請から行う必要がある。 ユーザー名やスマートスピーカーの位置情報の場合は基本的に変わることがないので、毎回承認作業が追加で必要になるのが、お互いに非常にネックとなる。

この問題の対応方法としては、下記

  • 毎回ユーザーに許可申請をする
  • インテント内に位置情報 (位置名) を含めて送ってもらうようにする (送ってもらった名称から必要な位置情報にサーバー側で変換できる必要がある)
  • 最初に取得した位置情報を userId に紐づけて保存しておき、次回以降は保存しておいた情報を使用する

参考

UWP アプリ開発メモ

証明書の有効期間が切れて申請用パッケージの作成に失敗する時の、更新方法

  1. VS で当該プロジェクトを開く
  2. [ソリューション エクスプローラー] で当該プロジェクトを右クリックし、プロパティを表示する
  3. [アプリケーション] タブを選択し、[パッケージ マニフェスト] ボタンをクリックする
  4. [パッケージ化] タブをクリックし、[発行者] テキストボックスに表示されている文字列をコピーしておく(後で使用する)
  5. [証明書の選択...] ボタンをクリックする
  6. [証明書の構成] ボタンをクリックし、[テスト証明書の作成...] ボタンをクリックする
  7. [発行者共通名] テキストボックスに、コピーしておいた [発行者] の文字列のうち「CN=」から後ろの文字列を貼り付け、[OK] ボタンをクリックする
  8. 有効期限が更新されていることを確認して、[OK] ボタンをクリックする

補足: 公開中アプリの [発行者共通名] については、Partner Center ダッシュボードで当該アプリを選択し、[App Management] - [App identity] - [Package/Identity/Publisher] の値でも確認できる

「'ValidateAppxPackage' に失敗しました。ファイル '...\Package.StoreAssociation.xml' が見つかりませんでした。」エラーが表示される場合の対処方法

  1. VS で当該プロジェクトを開く
  2. [ソリューション エクスプローラー] で当該プロジェクトを右クリックし、プロパティを表示する
  3. [アプリケーション] タブを選択し、[パッケージ マニフェスト] ボタンをクリックする
  4. [パッケージ化] タブをクリックし、[パッケージ名] テキストボックスに表示されている文字列を控えておく(この画面を表示したまま以降の作業実施でも可)
  5. [ソリューション エクスプローラー] で当該プロジェクトを右クリックし、[ストア] - [アプリケーションをストアと関連付ける] をクリックする
  6. [アプリケーション名を選択] 画面で、[既にパッケージに使用されているアプリケーション名を含める] チェックボックスにチェックを入れ、[既存のアプリケーション名] リストから目的のアプリを選択する。[Windows ストア内のパッケージ ID] 情報が、事前に確認していた [パッケージ名] の ID と合っているか、確認しておく
  7. 本当にこのアプリで合っているかなどの確認が表示されるので、問題なければ [次へ] ボタンをクリックする
  8. [関連付け] ボタンをクリックして、関連付けを行う。"Package.StoreAssociation.xml" ファイルが生成される

ソルデフ データ

自分で確認した情報をスプレッドシートにまとめているので、それを公開。 今の所、下記情報を記載。

  • 通常マップ (3-2 まで)
    • ルーン

行ヘッダでフィルタ設定して公開したつもりなんですが、閲覧者として使おうとするとうまくフィルタされないので、フィルタ等についてはご自身で行ってください。

何かありましたら、ツイッターやっていますのでお気軽にご連絡ください。(@poke_dev)

docs.google.com

.NET で文字列の暗号化を行う

非対称アルゴリズム(ハッシュ化)

System.Web.Helpers.Crypt.HashPassword() が使える(他のも色々あるっぽいけど)。 ハッシュ化された文字列には使用された salt も含まれるので、使う側は salt の保存などは考慮する必要なく、また、同一文字列をハッシュ化しても別文字列を得ることが出来る。

Password management made easy in ASP.NET with the Crypto API | brockallen

対照アルゴリズム

種類はいくつかあるようだが、実質的に AesManaged クラス一択の様子。

暗号化に使用する IV については分かっても問題ないらしいので、毎回生成して、暗号化後の文字列の先頭に追加する形式をとった方が良い。 毎回生成することで、仮に同じ文字列を暗号化したとしても得られる暗号化済みの文字列は異なる文字列になる。 復号化の際は、先頭に IV が追加されていることを前提に処理する必要がある。

Key についてはどこか安全な場所に保存して使用する必要がある。Azure であればアプリ設定で良いと思うが、更に厳重に管理する必要があるなら Key Vault とかになるのではないかと思う。

BlockSize, Mode, Padding などのオプションは、既定の設定で問題ないっぽい。

AesManaged Class (System.Security.Cryptography) | Microsoft Docs

ASP.NET MVC の認証周りについて

ASP.NET のセッションは Session Fixation 問題を抱えるため、認証には認証用に用意されている Form 認証を使用する。

MVC で認証ありサイトを作る時は、RegisterGlobalFilters() で AuthorizeAttribute を Filter に追加して、基本的にサイト全体で認証必要な状態にした方がたぶん安全。 認証不要なページ(コントローラー)は、明示的に AllowAnonymous 属性を付加して対応する。

(Form 認証ではなく)セッションが有効な状態かは、コントローラーの OnAuthorization() でチェックする。ベースコントローラーレベルでチェックするのを推奨。 なお、このイベントでリダイレクトする時は、Response.Redirect() ではなく、filterContext.Result にセットすることで行う必要がある。