メッセージを処理する前に呼び出しを行う
プレメッセージWebhookは、顧客が入力を送信するたびに、外部サービスまたはアプリケーションに呼び出しを行います。 外部サービスは、あなたのアシスタントがメッセージを処理する前に、メッセージを処理することができます。
各着信メッセージがアシスタントによって処理される前にWebhookをトリガーしたい場合は、プレメッセージWebhookをアシスタントに追加します。
カスタムチャネルを使用している場合、pre-message webhookは v2 /message
API(ステートレスおよびステートフル)のみで動作します。 詳しくは、API リファレンスを参照してください。 すべての組み込みチャネル統合で、この API が使用されます。
プレメッセージWebhookは以下のような用途に使用できます:
-
顧客の入力をアシスタントが使う言語に翻訳する。
-
顧客が送信する可能性のある個人情報 (E メール・アドレスや社会保障番号など) を確認し、削除します。
このウェブフックは、ポストメッセージのウェブフックと連携して使用することができます。 例えば、ポストメッセージのウェブフックは、レスポンスを顧客の言語に翻訳したり、プライバシーの理由で削除された情報を追加したりすることができる。 詳しくは、メッセージの処理後に呼び出しを行う を参照してください。
プライベート・エンドポイントが使用されている環境では、Web フックがトラフィックをインターネット経由で送信することに留意してください。
Classicエクスペリエンスでは、会話中に必要なときに1回限りのアクションを実行する必要がある場合は、ダイアログWebhookを使用します。 たとえば、アシスタントが口座番号、ユーザーID、口座の秘密など、必要な情報をすべて収集した時点で条件は満たされる。 詳しくは、ダイアログからのプログラマチック呼び出しの実行を参照してください。
Web フックの定義
すべての着信メッセージの前処理に使用する Webhook URL を 1 つ定義できます。
外部サービスへのプログラマチック呼び出しは、以下の要件を満たす必要があります。
-
呼び出しは POST HTTP 要求であること。
-
要求本体は JSON オブジェクト (
Content-Type: application/json
) でなければなりません。 -
呼び出しは 30 秒以内に戻らなければなりません。
外部サービスがGETリクエストのみをサポートしている場合、または実行時に URL パラメータを動的に指定する必要がある場合は、実行時の値を含むJSONペイロードでPOSTリクエストを受け付ける中間サービスを作成することを検討する。 その後、中間サービスは、これらの値を URL パラメーターとして渡してターゲット・サービスに要求を行い、応答をダイアログに返すことができます。
アシスタントがデプロイされ、お客様と対話している実稼働環境では、Web フックをセットアップしてテストしないでください。
手順
Web フックの詳細を追加するには、以下の手順を実行します。
-
アシスタントで、 「環境」 に移動し、Webhook を構成する環境を開きます。
-
アイコンをクリックして、環境設定を開きます。
-
環境設定ページで、 プリメッセージ・ウェブフックをクリックします。
クラシックを体験するには、以下のステップを完了する:
-
設定したいアシスタントの[
クリックし、[ Assistant settings ]を選択します。
-
Webhooks > Pre-message webhook をクリックします。
-
-
プリメッセージ Webhook スイッチを 有効に設定します。
-
Synchronous event(同期イベント )で、以下のオプションから1つを選択する:
-
エラーが発生した場合は、Webhookを更新せずにユーザー入力の処理を続行します。
-
Webhookの呼び出しに失敗した場合、クライアントにエラーを返します。
詳細については、「 前処理のためのウェブフック・エラー処理の設定 」を参照してください。
-
-
**「URL」**フィールドに、HTTP POST 要求コールアウトを送信する外部アプリケーションの URL を追加します。
例えば、メッセージが英語以外の言語で書かれているかどうかをチェックし、それを英語に変換するために Language Translator サービスに送信する Cloud Functions ウェブ・アクションを書くことができる。 以下の例にあるように、Web アクションの URL を指定します。
https://us-south.functions.cloud.ibm.com/api/v1/web/my_org_dev/default/translateToEnglish.json
SSL プロトコルを使用する URL を指定する必要があります。したがって、
https
で始まる URL を指定してください。 -
クラシック体験のためにシークレット欄を埋める。 詳しくは、 クラシック体験のみの秘密の追加を ご覧ください。
-
Timeoutフィールドで、アシスタントがエラーを返す前にWebhookからの応答を待つ時間(秒)を指定します。 タイムアウト期間は、1 秒未満に短くすることも、30 秒超に長くすることもできません。
-
ヘッダーセクションで、 ヘッダーの追加をクリックし、サービスに渡したいヘッダーを1つずつ追加します。
Classicエクスペリエンスを使用している場合、サービスは自動的にJWT付きの認証ヘッダーを送信します。 認可を自分で処理したい場合は、独自の認可ヘッダーを追加し、サービスがそれを代わりに使用する。
あなたが呼び出した外部アプリケーションが応答を返す場合、そのアプリケーションは異なるフォーマットで応答を送信できるかもしれない。 Webhook では、応答が JSON でフォーマットされている必要があります。 以下の表は、結果として返される値がJSON形式であることを示すヘッダーの追加方法を示している。
ヘッダー名 | ヘッダー値 |
---|---|
Content-Type |
application/json |
ヘッダー値を保存すると、文字列はアスタリスクに置き換えられ、再度表示することはできません。
Web フックの詳細は自動的に保存されます。
クラシック体験のためだけの秘密の追加
Classicエクスペリエンスを使用している場合は、外部サービスとの認証リクエストに渡す秘密鍵を Secret フィールドに追加します。
-
purple unicorn
のように、テキスト文字列としてキーを入力する。 -
最大1,024文字まで。
-
コンテキスト変数は使用しないでください。
外部サービスは秘密のチェックと検証に責任を負う。 トークンが不要な場合は、任意の文字列を指定する。 このフィールドを空欄にすることはできない。
入力中に秘密を表示するには、入力前に パスワードを表示する アイコン をクリックします。 秘密を保存すると、文字列がアスタリスクに置き換えられ、二度と見ることができなくなる。
このフィールドの使用方法の詳細については、 クラシック・エクスペリエンス専用のWebhook セキュリティを参照してください。
前処理のためのウェブフック・エラー処理の設定
ウェブフック・コールが失敗した場合、前処理ステップでエラーを返すかどうかを決めることができます。 次の 2 つのオプションがあります。
-
エラーが発生した場合、Webhook を更新せずにユーザー入力の処理を続行します。アシスタントはエラーを無視し、Webhook の結果なしでメッセージを処理します。 前処理が有用だが必須ではない場合は、このオプションを検討する。
-
Webhook 呼び出しが失敗した場合、クライアントにエラーを返します :アシスタントがメッセージを処理する前に前処理が重要な場合は、このオプションを選択します。
ウェブフック呼び出しが失敗した場合、クライアントにエラーを返すを有効にすると、前処理ステップが正常に完了するまで、すべてが停止します。
定期的に外部プロセスをテストし、潜在的な障害を特定する。 必要に応じてこの設定を調整し、メッセージ処理の中断を防いでください。
Webhook のテスト
本番環境で使用されるアシスタントのためにそれを有効にする前に、Webhookの広範なテストを行ってください。
Webhook は、メッセージがアシスタントに送信されて処理されるときにトリガーされます。
Webhook のトラブルシューティング
以下のエラー・コードは、発生する可能性がある問題の原因を追跡するのに役立ちます。 例えば、Web チャット統合がある場合、送信するすべてのテスト・メッセージが There is an error with the message you just sent, but feel free to ask me something else
などのメッセージを返すと、Web フックに問題があることが分かります。 このメッセージが表示された場合、cURL,などのREST
APIツールを使ってテスト用の'/message
APIリクエストを送信し、エラーコードと返されるメッセージの全文を確認する。
エラー・コードとメッセージ | 説明 |
---|---|
422 Webhook が無効な JSON 本体で応答しました | Webhook の HTTP 応答本体を JSON として構文解析できませんでした。 |
422 Webhook 応答の検証中にエラーが発生しました | Webhook の HTTP 応答本体が有効な /message 本体ではありませんでした。 |
422 Webhook が [500] 状況コードで応答しました |
あなたが呼び出した外部サービスに問題があります。 コードが失敗したか、外部サーバーが要求を拒否しました。 |
500 プロセッサー例外: [connections to all backends failing] |
Webhook マイクロサービスでエラーが発生しました。 バックエンド・サービスに接続できませんでした。 |
クラシック・エクスペリエンス専用のWebhookセキュリティ
Classicエクスペリエンスを使用している場合は、リクエストとともに送信されるJSON Web Token(JWT)を検証することによって、Webhookリクエストを認証します。 ウェブフック・マイクロサービスは自動的にJWTを生成し、各ウェブフック・コールで Authorization
ヘッダーにそれを送信する。
-
新しい Webhook または Edit 認証で更新された Webhook の場合、authorization ヘッダーは無視されます。
-
保存された認証ヘッダーを持つ既存の Webhook の場合、 認証の編集オプションは無効になります。
-
新しい認証設定を使用するように既存のWebhookを更新すると、その動作が変更されます。
詳細については、 プレ・メッセージとポスト・メッセージのウェブフックの認証方法の定義を 参照してください。
JWT検証をテストする必要がある場合は、外部サービスにコードを追加できます。 例えば、 Secret フィールドに purple unicorn
:
const jwt = require('jsonwebtoken');
...
const token = request.headers.authentication; // grab the "Authentication" header
try {
const decoded = jwt.verify(token, 'purple unicorn');
} catch(err) {
// error thrown if token is invalid
}
要求本文
外部コードが処理できるように、プレメッセージWebhookのリクエストボディのフォーマットを知っておくと便利です。
ペイロードには、/message
(ステートフルまたはステートレス) v2 API 要求の要求本体が含まれています。 イベント名 message_received
は、リクエストがプレメッセージウェブフックによって生成されたことを示す。 メッセージ要求本体について詳しくは、 API リファレンスを参照してください。
{
"payload" : { Copy of request body sent to /message }
"event": {
"name": "message_received"
}
}
クラシック経験者のみアシスタント処理をスキップ
Classicエクスペリエンスを使用している場合、プレメッセージWebhookの機能強化により、 watsonx Assistant、メッセージ処理をスキップし、Webhookからのレスポンスを直接返すことができます。 この機能は、ウェブフックの HTTP レスポンスに x-watson-assistant-webhook-returnheader
を設定することで有効になります。
開始前に
クラシックを体験するには以下のステップを踏む:
- ウェブフックからの HTTP の応答に、任意の値を指定した
x-watson-assistant-webhook-returnheader
を含めます。 - ウェブフックのレスポンスが、 watsonx Assistant の要件に従ってフォーマットされた有効なメッセージレスポンスを含むことを確認してください。
この機能により、ウェブフックが会話の流れを動的に制御できるようになり、必要なときに即座に対応できるようになります。
応答本体
Webhook から POST 要求を受け取るサービスは、JSON オブジェクト (Accept: application/json
) を返す必要があります。
応答本体には、以下の構造が必要です。
{
"payload": {
...
}
}
レスポンス payload
、リクエストボディの payload
。 あなたのコードは、プロパティ値を変更したり、コンテキスト変数を変更したりできますが、返されるメッセージのペイロードは、 message
メソッドのスキーマに従わなければなりません。 詳細は APIリファレンスを 参照。
例 1
この例では、入力テキストの言語をチェックし、その言語情報を入力テキスト文字列に追加する方法を示します。
プレメッセージWebhook設定ページでは、以下の値を指定します:
クラシック経験者にとって、 シークレットフィールドに価値はない。
- URL:
https://us-south.functions.appdomain.cloud/api/v1/web/e97d2516-5ce4-4fd9-9d05-acc3dd8ennn/default/check_language
- ヘッダー名: Content-Type
- ヘッダー値: application/json
プレメッセージ Webhook は IBM Cloud Functions Web アクション名 check_language
を呼び出します。
check_language
Web アクションの node.js コードは以下のようになります。
let rp = require("request-promise");
function main(params) {
console.log(JSON.stringify(params))
if (params.payload.input.text !== '') {
// Send a request to the Watson Language Translator service to check the language of the input text.
const options = { method: 'POST',
url: 'https://api.us-south.language-translator.watson.cloud.ibm.com/instances/572b37be-09f4-4704-b693-3bc63869nnnn/v3/identify?version=2018-05-01',
auth: {
'username': 'apikey',
'password': 'nnn'
},
headers: {
"Content-Type":"text/plain"
},
body: [
params.payload.input.text
],
json: true,
};
return rp(options)
.then(res => {
params.payload.context.skills["actions skill"].user_defined["language"] = res.languages[0].language;
console.log(JSON.stringify(params))
//Append "in" plus "the language code" to the input text, surrounded by parentheses.
const response = {
body : {
payload : {
input : {
text : params.payload.input.text + ' ' + '(in ' + res.languages[0].language + ')'
},
},
},
};
return response;
})
}
return {
body : params
}
};
Webhook をテストするには、プレビューをクリックします。 テキスト Buenos días
を送信します。 アシスタントはおそらく入力を理解できず、 Anything else ノードからの応答を返します。 しかし、アシスタントの「分析」ページで 「会話」を開くと、投稿された内容を見ることができます。 最新のユーザー会話を確認します。 ログには、ユーザー入力が
Buenos días (in es)
であることが示されます。 括弧内の es
はスペイン語の言語コードを表しているため、ウェブフックは機能し、送信されたテキストがスペイン語のフレーズであることを認識した。
例 2
この例では、受信メッセージの言語をチェックし、英語でなければアシスタントに送信する前に英語に翻訳する方法を示しています。
IBM Cloud Functions で Web アクションのシーケンスを定義します。 シーケンス内の最初のアクションは、着信テキストの言語を検査します。 シーケンス内の 2 番目のアクションは、テキストを元の言語から英語に変換します。
プレメッセージWebhook設定ページでは、以下の値を指定します:
クラシック経験者にとって、 シークレットフィールドに価値はない。
- URL:
https://us-south.functions.appdomain.cloud/api/v1/web/e97d2516-5ce4-4fd9-9d05-acc3dd8ennn/default/translation_sequence
- ヘッダー名: Content-Type
- ヘッダー値: application/json
シーケンス内の最初の Web アクションの node.js コードは、以下のようになります。
let rp = require("request-promise");
function main(params) {
console.log(JSON.stringify(params))
if (params.payload.input.text !== '') {
const options = { method: 'POST',
url: 'https://api.us-south.language-translator.watson.cloud.ibm.com/instances/572b37be-09f4-4704-b693-3bc63869nnnn/v3/identify?version=2018-05-01',
auth: {
'username': 'apikey',
'password': 'nnn'
},
headers: {
"Content-Type":"text/plain"
},
body: [
params.payload.input.text
],
json: true,
};
return rp(options)
.then(res => {
//Set the language property of the incoming message to the language that was identified by Watson Language Translator.
params.payload.context.skills["actions skill"].user_defined["language"] = res.languages[0].language;
console.log(JSON.stringify(params))
return params;
})
}
else {
params.payload.context.skills["actions skill"].user_defined["language"] = 'none'
return params
}
};
シーケンス内の 2 番目の Web アクションは、テキストを Watson Language Translator サービスに送信して、前の Web アクションで識別された言語からの入力テキストを英語に変換します。 翻訳されたストリングは、元のテキストではなく、アシスタントに送信されます。
シーケンス内の 2 番目のアクションの node.js コードは、以下のようになります。
let rp = require("request-promise");
function main(params) {
console.log(JSON.stringify(params))
//If the the incoming message is not null and is not English, translate it.
if ((params.payload.context.skills["actions skill"].user_defined.language !== 'en') && (params.payload.context.skills["actions skill"].user_defined.language !== 'none')) {
const options = { method: 'POST',
url: 'https://api.us-south.language-translator.watson.cloud.ibm.com/instances/572b37be-09f4-4704-b693-3bc63869nnnn/v3/translate?version=2018-05-01',
auth: {
'username': 'apikey',
'password': 'nnn'
},
headers: {
"Content-Type":"application/json"
},
//The body includes the parameters that are required by the Language Translator service, the text to translate and the target language to translate it into.
body: {
text: [
params.payload.input.text
],
target: 'en'
},
json: true
};
return rp(options)
.then(res => {
params.payload.context.skills["actions skill"].user_defined["original_input"] = params.payload.input.text;
const response = {
body : {
payload : {
"context" : params.payload.context,
"input" : {
"text" : res.translations[0].translation,
"options" : {
"export" : true
}
},
},
},
};
return response
})
}
return {
body : params
}
};
プレビュー・パネルで Webhook をテストすると、Buenos días
を実行依頼できます。アシスタントは、Good morning
と英語で応答した場合と同様に応答します。 実際、アシスタントの「分析 (Analyze)」ページを確認して 「会話 (Conversations)」 を開くと、ログにはユーザー入力が Good morning
であったことが示されます。
あなたは、メッセージの応答が表示される前に顧客の言語に翻訳し直すために、メッセージ後のWebhookを追加することができます。 詳しくは 例2を 参照。
例 3
この例では、 watsonx Assistant にメッセージの処理を省略させ、webhook のレスポンスを直接返すように webhook レスポンスを構成する方法を示します。
Webhook 構成
ウェブフック設定ページで、以下の値を指定します
クラシック経験者にとって、 シークレットフィールドに価値はない。
- URL: https://your-webhook-url/webhook_skip
- ヘッダー名: Content-Type
- ヘッダー値: application/json
webhook_skip ウェブ・アクションの node.js コードは以下のようになる。
function main(params) {
// Your custom logic to determine the response
let responseText = "This response is directly from the pre-message webhook.";
const response = {
headers: {
"X-Watson-Assistant-Webhook-Return": "true"
},
body: {
output: {
generic: [
{
response_type: "text",
text: responseText
}
]
}
}
};
return response;
}
Webhook の削除
Webhookで顧客の入力を前処理したくないと判断した場合は、次の手順を実行します:
-
アシスタントで、 「環境」 に移動し、Web フックを削除する環境を開きます。
-
アイコンをクリックして、環境設定を開きます。
-
環境設定ページで、 プリメッセージ・ウェブフックをクリックします。
クラシックを体験するには、以下のステップを完了する:
-
設定したいアシスタントの[
クリックし、[ Assistant settings ]を選択します。
-
Webhooks > Pre-message webhook をクリックします。
-
-
以下のいずれかのステップを実行します。
-
受信メッセージを処理するために Webhook を呼び出すのを止めるには、 Pre-message Webhook スイッチを Disabled に設定します。
-
呼び出す Webhook を変更するには、 Delete webhook をクリックします。