外部イベント
アプリケーション・イベント・タイプ(外部アプリケーションによって生成されたイベントに基づく)を定義し、デジタル・アシスタントのユーザーにデジタル・アシスタントにそれらのタイプのイベントが渡されたときに通知されるようにできます。
これらのイベント・タイプは、サービス、プラットフォームおよびシステム間で相互運用できるようにイベント・データの共通フォーマットを定義するクラウド・イベント仕様に従う必要があります。この仕様については、https://cloudevents.io/を参照してください。
アプリケーション・イベントを実装するためのワークフロー
- イベントのソースを指定します。
- デジタル・アシスタントで、イベント・タイプを登録します。
- そのイベント・タイプのイベントを消費するようにスキルを構成し、そのスキルをデジタル・アシスタントに追加します。
- イベント・チャネルを作成し、デジタル・アシスタントにマップします。
- 作成したイベント・チャネルから、インバウンドURLおよび秘密キーを取得し、イベントを生成する外部アプリケーションで使用できるようにします。
イベントを使用するスキルは、複数のデジタル・アシスタントの一部にできます。
イベント・タイプの定義
スキルがクラウド・イベントを受信できるようにするには、Oracle Digital Assistantでイベント・タイプを定義する必要があります。イベント・タイプを定義するには:
-
をクリックしてサイド・メニューを開き、「開発」→「イベント」を選択し、「新規イベント」をクリックして、イベント・タイプの名前を入力します。
ヒント:
イベント・タイプにネーミング規則を使用して、他の開発者が何をするかを理解できるように、意味のあるコンテキストを指定する必要があります。ピザ・オーダーのイベント・タイプの簡単な例は、pizza.order
です。 - 作成したばかりの新規イベントのページで、説明を入力します。
- 「JSONスキーマ」フィールドでイベントのスキーマを入力します。
このフィールドには、必須要素を含むサンプル・スキーマが事前に移入されています。
schema
属性には、次のいずれかの値があります。"http://json-schema.org/draft-04/schema#"
"http://json-schema.org/draft-06/schema#"
"http://json-schema.org/draft-07/schema#"
"http://json-schema.org/draft/2019-09/schema#"
properties
オブジェクトでは、プロパティをキーと値のペアとして定義します。ここで、値はプロパティの検証対象となるスキーマです。例:
"properties": { "firstName": { "type": "string", "description": "The person's first name." }, "lastName": { "type": "string", "description": "The person's last name." }, "age": { "description": "Age in years which must be equal to or greater than zero.", "type": "integer", "minimum": 0 } }
これらのプロパティの定義の詳細は、https://json-schema.org/understanding-json-schema/reference/object.htmlを参照してください。
- スキーマでの作業が終了し、その内容を確定する場合は、「確定済としてマーク」をクリックします。
この時点で、このイベント・タイプをスキルで使用できます。
後でスキーマを変更する必要があると判断した場合は、スキーマの新規バージョンを作成できます。
例: クラウド・イベント・タイプ・スキーマ
{
"$schema":"http://json-schema.org/draft-07/schema#",
"description":"Pizza Order Schema",
"title":"Pizza Order Schema",
"type":"object",
"properties":{
"size":{
"description":"The pizza size",
"type":"string"
},
"orderid":{
"description":"The pizza orderid",
"type":"string"
},
"type":{
"description":"The pizza type",
"type":"string"
},
"topping":{
"description":"The pizza topping",
"type":"string"
}
}
}
イベントを消費するためのスキルの構成
スキルがイベントを使用するために必要な一般的なステップは次のとおりです:
- スキルで、イベントを使用する「ユーザーに通知」コンポーネントを使用してフローを作成します。(このコンポーネントは、ビジュアル・モードで開発されたダイアログ・フローでのみ使用できます。)
実行時にイベントが生成されると、イベントはスキルに渡されます。式を使用して、イベントのデータおよびコンテキストにアクセスできます。
- 特定の認証済ユーザーをターゲットにするようにイベント・タイプ(OCI IAMアイデンティティ・ドメインのユーザーIDを使用)を設計する場合は、スキルにOAuth 2.0コンポーネントを使用した認可があり、有効なチャネル・アカウント・リンクがあることを確認してください。
- ダイアログ・フローのメイン・フローで、イベントとイベントのユーザー通知状態を含むフローの間のアプリケーション・イベント・マッピングを作成します。
- スキルをデジタル・アシスタントに追加します。
イベントのユーザー通知の作成
スキルがイベントに応答するには、そのイベントのフローを追加し、イベントの発生時に「ユーザーに通知」状態を使用してメッセージを表示します:
- イベントを使用するスキルで、
をクリックし、「+フローの追加」をクリックします。
- フロー名を入力して、「作成」をクリックします。
- フロー開始のメニュー
をクリックし、「開始状態の追加」をクリックして「状態の追加」ダイアログを開きます。
- 「サービス統合」→「ユーザーに通知」を選択し、状態の名前を入力して、「挿入」をクリックします。
- 挿入された「ユーザーに通知」状態のプロパティ・インスペクタで、「コンポーネント」タブを選択し、「通知メッセージ」フィールドに、イベントの発生時にユーザーに表示するメッセージを入力します。
このメッセージでは、次の形式の式を使用して、イベントのデータにアクセスできます。
${skill.system.event.value.application.data.<propertyName>}
ノート
次のタイプの式を使用して、イベントからコンテキスト情報にアクセスすることもできます:
使用可能なコンテキスト属性の詳細は、「イベント・コンテキスト属性」を参照してください。${skill.system.event.value.application.context.<attributeName>}
- オプションで、「ユーザーID」プロパティに、フロー内(カスタム・コンポーネントなど)から動的に決定できる特定のユーザーのIDを入力します。このプロパティは、主に、ユーザーIDがイベント・ペイロードで送信されておらず、かつユーザーが統合ユーザーで、「統合ユーザーとの関連付け」プロパティがtrueに設定されているOAuth 2.0コンポーネントを使用して認証されている場合に役立ちます。統合ユーザーの詳細は、統合ユーザー・アイデンティティの構成を参照してください。
フローからのイベント受信者の決定
イベントを特定のユーザーにターゲット指定する必要があるが、そのユーザーがイベント自体で指定されていない場合は、イベントを処理するフロー内のユーザーを決定できる場合があります。その作業を行う一般的なステップは次のとおりです:
- イベントを処理するフローの開始時に、(イベント・ペイロードまたはカスタム・ロジック(あるいはその両方)に基づいて)ユーザーIDを決定するカスタム・コンポーネントを追加し、そのIDを変数に割り当てます。
- カスタム・コンポーネントの状態の後、ユーザーに通知コンポーネントを挿入し、そのコンポーネントの「ユーザーID」プロパティをカスタム・コンポーネントによって返される変数に設定します。
外部イベントのハンドラの作成
スキルがイベントを受信するには、メイン・フローでそのイベントのイベント・ハンドラを作成します。イベント・ハンドラで、イベントを受信するために作成した通知ユーザー状態を含むフローにイベントをマップします。
- フローのリストで、「メイン・フロー」を選択します。
- そのフローの「イベント」タブで、「アプリケーション・イベント」セクションの横にある
をクリックします。
- 「アプリケーション・イベント・ハンドラの作成」ダイアログで、イベント・タイプ、イベント・タイプのバージョンおよびイベントのマップ先のフローを選択し、「閉じる」をクリックします。
ノート
「確定済」イベント・タイプのみが「未解決イベント・タイプ」フィールドに提供されます。
スキルをデジタル・アシスタントに追加
スキルが外部イベントを使用するには、デジタル・アシスタントの一部である必要があります。イベントをデジタル・アシスタントに消費するように構成されたスキルを追加するには:
をクリックしてサイド・メニューを開き、開発→デジタル・アシスタントを選択して、使用するデジタル・アシスタントをダブルクリックします。
-
「スキルの追加」をクリックします。
- イベントを使用するように構成されているスキルのタイルで、
を選択します。
探しているスキルが見つからない場合は、言語モードがデジタル・アシスタントの言語モードと互換性がない可能性があります。デジタル・アシスタントにスキルを追加するための条件を参照してください。
- 「完了」ボタンをクリックしてスキル・カタログを閉じ、デジタル・アシスタントでスキルのページを表示します。
-
ページの「対話モデル」セクションまでスクロールし、「起動」の値が、ユーザーがスキルの起動に使用する名前であることを確認します。
この名前は、これらの起動名のガイドラインに従う必要があります。
-
ユーザーがスキルを起動する方法に典型的な発話例をいくつか指定します。
これらの発話は、デジタル・アシスタントのデフォルトのようこそ状態およびヘルプ状態で選択可能なオプションとして使用されます。
外部アプリケーションのチャネルの作成
外部アプリケーションからデジタル・アシスタントにイベントを送信できるようにするには、アプリケーション・チャネルを作成する必要があります。チャネルの作成後、デジタル・アシスタントは秘密キーとインバウンドURLを割り当てます。イベントを生成するアプリケーションでこれらの値を使用する必要があります。
- デジタル・アシスタントで、左側のメニューの「チャネル」をクリックして、「イベント」を選択します。
- 「チャネルの追加」をクリックします。
- チャネル名フィールドに、チャネルの一意の名前を入力します。
- (オプション)「アウトバウンド・アプリケーションURL」フィールドに、POSTリクエストを介して送信されるチャネル関連のエラー・メッセージの宛先となるWebサービスURLを入力します。
ユーザー・チャネルを介した会話の開始に関する問題などのエラーが発生した場合、デジタル・アシスタントはエラー・メッセージをクラウド・イベントとして送信し、イベント・データにはエラーを説明する
code
およびmessage
属性が含まれます。例:{ "code": "InvalidParameter", "message": "The event contains invalid or missing attributes: firstName" }
- 「作成」をクリックします。
- 「アプリケーション有効」を「オン」に切り替えます。
- 「ルート先」ドロップダウンから、イベントを使用するフローがあるスキルを含むデジタル・アシスタントを選択します。
- 秘密キーとインバウンドURLをノートにとります。
これらは、イベントを生成する外部アプリケーションで必要になります。外部アプリケーションは、インバウンドURLにPOSTリクエストを送信してメッセージを送信し、秘密キーを使用してPOSTリクエストを認証します。
外部アプリケーションからのイベントの生成
- アプリケーション・チャネルの秘密キーを使用するリクエスト本文のSHA-256ハッシュを含む
X-Hub-Signature
ヘッダーがあります。例:X-Hub-Signature: sha256=<HMAC SHA-256 signature of body using the secret key for the channel>
- コンテンツ・タイプは
application/cloudevents+json
です。
イベント・ペイロードは、構造化形式(すべての属性がHTTP本文のJSONの一部)またはバイナリ形式(イベント・コンテキスト属性がce-
接頭辞付きヘッダーに存在する場合)のいずれかです。これらのフォームについてさらに学習するには、https://github.com/cloudevents/spec/blob/v1.0/http-protocol-binding.md#3-http-message-mappingを参照してください。
イベント送信の構造化フォーム
次の例は、イベントを送信するための構造化形式の使用を示しています。
curl --location --request POST 'https://<server>/events/v2/listeners/appevent/channels/<id>' \
--header 'Content-Type: application/cloudevents+json' \
--header 'X-Hub-Signature: sha256=<SHA256 encoded request body using the channel's secret key>' \
--data-raw \
'{
"specversion": "1.0", //Version # of Digital Assistant's Events support
"type": "<event_name>", //The event type that the skill is listening for
"source": "< event source>", //URI-reference - identifies the context in which an event happened
"id": "<event id>", //Unique id for the event
"version":"<event version>", //An extension attribute(not part of CloudEvent spec) for the version # of the event type
"data": { //The business data that matches with the schema defined for the event
}
}'
Node.jsでイベントを送信するためのフォーム
async pushEvent(eventName, eventVersion, userId, channelName, eventData){
try {
// Build event data
const event = {
specversion: "1.0", //Version # of Digital Assistant's Events support
type: eventName, // Name of Event you created in ODA
source: "< event source>", //URI-reference - identifies the context in which an event happened
id: "<event id>", //Unique id for the event
time: "2022-09-07T21:19:24Z", // Any Date value will do now
channelname: <channelName>, // Can be set to System_Global_Test if you want to test in tester
version: <eventVersion>, // version of the event that you defined in Digital Assistant
userid: <userId>,
datacontenttype: "application/json",
data: <eventData> // JSON object represting your payload which should confirm to the event's JSON schema
};
// Build Required headers
const headers = {
"X-Hub-Signature" : this._buildSignatureHeader(event, <EVENTS_CHANNEL_SECRET_KEY> , "utf8"),
"Content-Type" : "application/cloudevents+json"
};
// POST to EVENT_LISTENER_CHANNEL_URL
....
} catch (error) {
logger.error(error.message);
const errorMessage = `Error pushing event [ ${eventData} ] to Digital Assistant`;
logger.debug(errorMessage);
throw new Error(error.message);
}
}
_buildSignatureHeader(body, secret, encoding) {
const buf = Buffer.from(JSON.stringify(body), "utf8");
return "sha256=" + this._buildSignature(buf, secret, encoding);
}
_buildSignature(buf, secret, encoding) {
const hmac = crypto.createHmac("sha256", Buffer.from(secret || "", encoding || "utf8"));
if (buf) {
hmac.update(buf);
}
return hmac.digest("hex");
}
イベント・ペイロード属性
次に、イベント・ペイロードで使用できる一般的な属性を示します。
specversion
: (必須) Digital Assistantのイベント・サポートのバージョン番号。現在、有効な値は1.0
のみです。type
: (必須)スキルがリスニングしているイベント・タイプ。これは、「イベント・タイプの定義」タスクで指定したイベント・タイプの名前に対応している必要があります。source
: (必須)イベントが発生したコンテキストを識別します。自由形式の文字列を指定できます。id
: (必須)アプリケーションによってイベントに対して生成される一意のID。version
: (必須)送信するイベント・タイプのバージョンの名前。この属性の値は、イベント・ペイロードに含める必要であり、「外部イベントのハンドラの作成」タスクで指定したイベント・タイプ・バージョンに指定した値と一致する必要があります。ノート
この属性は、拡張属性の1つであり、CloudEvent仕様の一部ではないことを意味します。data
: (必須)イベントに定義されたスキーマと一致するビジネス・データ。
イベント・コンテキスト属性
生成されるイベントごとに、デジタル・アシスタントによって、イベントが生成されるコンテキストを説明する拡張属性が追加されます。ツールとアプリケーション・コードでは、この情報を使用して、生成されたイベントのソースやその他のイベントとの関係などを識別できます。イベント・ペイロードでこれらの属性の値も指定できます。
拡張属性(すべてString
型)のリストを次に示します。
-
version
: 送信されるイベント・タイプのバージョンの名前。この属性の値は、イベント・ペイロードに含める必要であり、「外部イベントのハンドラの作成」タスクで指定したイベント・タイプ・バージョンに指定した値と一致する必要があります。 -
userid
: メッセージのターゲットとなっているユーザーのID。次の2つの形式のいずれかを取ります。- OCI IAMユーザーID。この場合、ペイロードに
usertenancy
属性も含める必要があります。 - チャネルによって提供されるユーザーID。この場合、ペイロードに
channelname
属性も含める必要があります。ノート
Twilioの場合、この値はユーザーの携帯電話番号になります。
- OCI IAMユーザーID。この場合、ペイロードに
-
usertenancy
: ユーザーのアイデンティティ・プロバイダのOIC IAMテナンシの名前。 -
channelname
: デジタル・アシスタントが公開されるチャネルの名前。 -
tenancy
: デジタル・アシスタント・インスタンスのOracle Cloud Infrastructureテナンシの名前。(通常、テナンシに関する情報はリクエスト・ヘッダーに渡されるため、この属性を明示的に含める必要はありません。)
例: イベント・ペイロード
{
"specversion": "1.0",
"type": "com.pizzastore.pizza.ordercreated",
"source": "pizzastore/orders",
"id": "12345678-90ab-cdef-1234-567890abcdef",
"time": "2022-08-10T12:31:00Z",
"contenttype": "application/json",
"tenancy": "mydigitalassistantinstance",
"version": "1.0",
"data": {"size": "Large",
"type": "Veg"
}
}
例: OCI IAMユーザーIDを使用したペイロード
ペイロードでユーザーのOCI IAMユーザーIDを渡す必要がある場合は、userid
およびusertenancy
属性も指定します。
{
"specversion": "1.0", //Version # of Digital Assistant's Events support
"type": "<event_name>", //The event type that the skill is listening for
"source": "< event source>", //URI-reference - identifies the context in which an event happened
"id": "<event id>", //Unique id for the event
"version":"<event version>", //An extension attribute(not part of CloudEvent spec) for the version # of the event type
"userid":"<IAM user id>", //An extension attribute(not part of CloudEvent spec) for the user ID
"usertenancy":<IAM tenancy>", //Extension attribute, IAM
"data": { //The business data that matches with the schema defined for the event
}
}
イベントがペイロードでOCI IAMユーザーIDを渡すように設計されている場合は、スキルにOAuth 2.0コンポーネントを使用した認可があり、その「統合ユーザーとの関連付け」プロパティが「True」に設定されていることを確認します。
例: ユーザーIDおよびチャネル名を使用したペイロード
TwilioおよびWebチャネルを介して公開されるデジタル・アシスタントの場合、外部アプリケーションはチャネル名とチャネルによって提供されるユーザーIDを指定してユーザーに通知することもできます。
{
"specversion": "1.0", //Version # of Digital Assistant's Events support
"type": "<name_of_event_type>", //The event type that the skill is listening for
"source": "< event source>", //URI-reference - identifies the context in which an event happened
"id": "<event id>", //Unique id for the event
"version":"<event version>", //An extension attribute(not part of CloudEvent spec) for the version # of the event type
"userid":"<channel user id>", //An extension attribute(not part of CloudEvent spec) for the user ID
"channelname":"<channel name>", //Name of the channel through which the digital assistant is exposed
"data": { //The business data that matches with the schema defined for the event
}
}
スキルからのイベントの公開
スキルで外部イベントを使用する以外に、スキルを使用して、Oracle Digital Assistantに登録したタイプのイベントを外部アプリケーションに公開できます。これは、「イベントの公開」コンポーネント(「サービス統合」カテゴリ)を使用して実行できます。この方法でイベントが生成されると、外部アプリケーションのチャネルで指定した「アウトバウンド・アプリケーションURL」で指定したURLに公開されます。