使用 Webhook 记录活动
Plus
您可以通过在客户每次向助手提交输入时调用外部服务或应用程序来记录活动。
网络挂钩是一种机制,您可以根据程序中的事件调用外部程序。
此功能仅适用于Plus和Enterprise计划用户。 Plus 套餐允许每个实例不超过 5 个日志 Webhook。 此限制不适用于企业套餐实例。
如果要使用外部服务来记录活动,请向助手添加日志 Webhook。 您可以记录两种类型的活动:
-
消息和响应: 每次助手响应客户输入时,都会触发日志 Webhook。 您可以使用此选项作为内置分析功能的替代方法来自行处理日志记录。 (有关内置分析支持的更多信息,请参阅 查看整个助手概览。)
如果您正在使用定制通道,那么日志 Webhook 仅使用 v2
/message
API (无状态和有状态)。 更多信息,请参阅 API参考。 所有内置通道集成都使用此 API。 -
呼叫详细信息记录 (CDR): 在用户对使用电话集成的助手进行每次电话呼叫后,将触发日志 Webhook。 呼叫详细记录 (CDR) 是一个摘要报告,用于记录电话呼叫的详细信息,包括电话号码,呼叫长度,等待时间和其他诊断信息。 CDR 记录仅适用于使用电话集成的助手。
日志 Webhook 不会向助手返回任何内容。
在使用私有端点的情况下,请记住,网络挂钩通过互联网发送流量。
定义 Webhook
您可以定义一个 Webhook URL 以用于记录每个入局消息或 CDR 事件。
对外部服务的程序化调用必须满足以下需求:
- 调用必须是 POST HTTP 请求。
要添加 Webhook 详细信息,请完成以下步骤:
-
在助手中,打开要在其中配置 Webhook 的环境。
-
单击
图标以打开环境设置。
-
在“环境设置”页面上,单击 日志 Webhook。
-
或者,如果您正在使用经典体验,请打开“助手”页面。
-
对于要配置的助手,单击
图标,然后选择 设置。
-
单击 Webhook,然后单击 日志 Webhook。
-
-
将 日志 Webhook 开关设置为 已启用。
如果无法启用 Webhook,那么可能需要升级服务套餐。
-
在 URL 字段中,添加要向其发送 HTTP POST 请求调出的外部应用程序的 URL。 例如,
https://example.com/my_log_service
。必须指定使用 SSL 协议的 URL,因此请指定以
https
开头的 URL。 -
在 私钥 字段中,添加要与可用于向外部服务进行认证的请求一起传递的令牌。
必须将私钥指定为文本字符串,例如
purple unicorn
。 最多可输入1024个字符。 不能指定上下文变量。外部服务负责检查和验证私钥。 如果外部服务不需要令牌,请指定所需的任何字符串。 不能将此字段留空。
如果要在输入私钥时查看该私钥,请单击 显示密码 图标
,然后开始输入。 保存私钥后,字符串将被星号替换,无法再次查看。
-
单击相应的复选框以选择要记录的活动类型:
- 要记录消息和响应,请选择 预订对话日志。
- 要记录电话集成的 CDR 事件,请选择 预订 CDR (呼叫详细记录)。
-
在“头”部分中,通过单击添加头来添加要传递给服务的任何头,一次添加一个头。
服务会自动发送带有 JWT 的
Authorization
头; 您不需要添加一个头。 如果要自行处理授权,请添加自己的授权头,并改为使用该头。保存头值后,字符串将被星号替换,无法再次查看。
这将自动保存 Webhook 详细信息。
除去 Webhook
如果您决定不希望使用 Webhook 记录消息,请完成以下步骤:
-
在助手中,转至 环境 并打开要在其中配置 Webhook 的环境。
-
单击
图标以打开环境设置。
-
在“环境设置”页面上,单击 日志 Webhook。
-
或者,如果您正在使用经典体验,请打开“助手”页面。
-
对于要配置的助手,单击
图标,然后选择 设置。
-
单击 Webhook,然后单击 日志 Webhook。
-
-
执行下列其中一个操作:
- 要更改要调用的 Webhook,请单击 删除 Webhook 以删除当前指定的 URL 和私钥。 然后,您可以添加 URL 和其他详细信息。
- 要停止调用 Webhook 以记录每条消息和响应,请单击 日志 Webhook 开关以完全禁用 Webhook。
Webhook 安全性
要认证 Webhook 请求,请验证随请求一起发送的 JSON Web 令牌 (JWT)。 Webhook 微服务会自动生成 JWT,并通过每个 Webhook 调用在 Authorization
头中发送该 JWT。 您负责向用于验证 JWT 的外部服务添加代码。
例如,如果在 私钥 字段中指定 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 请求主体
Webhook 发送到外部服务的请求主体是具有以下结构的 JSON 对象:
{
"event": {
"name": "{event_type}"
},
"payload": {
...
}
}
其中,{event_type}
是 message_logged
(对于消息和响应) 或 cdr_logged
(对于 CDR 事件)。
payload
对象包含要记录的事件数据。 payload
对象的结构取决于事件类型。
消息事件有效内容
对于 message_logged
事件,payload
对象包含有关发送到助手的消息请求以及返回到集成或客户机应用程序的消息响应的数据。 有关属于消息请求和响应的字段的更多信息,请参阅 API 参考。
日志 Webhook 有效内容可能包含 API 当前不支持的数据。 API 参考文档中未定义的任何字段都可随时更改。
CDR 事件有效内容
对于 cdr_logged
事件,payload
对象包含有关电话集成所处理的呼叫详细记录 (CDR) 事件的数据。 CDR 事件的 payload
对象的结构如以下示例所示:
{
"primary_phone_number": "+18005550123",
"global_session_id": "9caa8bad-aaa8-4a5a-a4b5-62bccc703d15",
"failure_occurred": false,
"transfer_occurred": false,
"active_calls": 0,
"warnings_and_errors": [
{
"code": "CWSMR0033W",
"message": "CWSMR0033W: The inbound RTP audio stream jitter of 43 ms exceeds the maximum jitter threshold of 30 ms."
},
{
"code": "CWSMR0070W",
"message": "CWSMR0070W: A request to the Watson Speech To Text service failed for the following reason = Unexpected server response: 403, response headers = {\"strict-transport-security\":\"max-age=31536000; includeSubDomains;\",\"content-length\":\"157\",\"content-type\":\"application/json\",\"x-dp-watson-tran-id\":\"23860083-88b6-41d7-9130-30bbfebe647e\",\"x-request-id\":\"23860083-88b6-41d7-9130-30bbfebe647e\",\"x-global-transaction-id\":\"6c764df3-81db-41bb-a14f-62384facffca\",\"server\":\"watson-gateway\",\"x-edgeconnect-midmile-rtt\":\"1\",\"x-edgeconnect-origin-mex-latency\":\"28\",\"date\":\"Thu, 13 May 2021 20:31:12 GMT\",\"connection\":\"keep-alive\"}, response body = {\"code\":403,\"trace\":\"23860083-88b6-41d7-9130-30bbfebe647e\",\"error\":\"Forbidden\",\"more_info\":\"[https://cloud.ibm.com/docs/watson?topic=watson-forbidden-error](https://cloud.ibm.com/docs/watson?topic=watson-forbidden-error)\"}, x-global-transaction-id = 6c764df3-81db-41bb-a14f-62384facffca. The Media Relay will reattempt to send the request."
}
],
"realtime_transport_network_summary": {
"inbound_stream": {
"average_jitter": 4,
"canonical_name": "b74f3689-1ae8-4a0a-bde3-adf5b488553e",
"maximum_jitter": 18,
"packets_lost": 0,
"packets_transmitted": 952,
"tool_name": ""
},
"outbound_stream": {
"average_jitter": 0,
"canonical_name": "voice.gateway",
"maximum_jitter": 0,
"packets_lost": 0,
"packets_transmitted": 838,
"tool_name": "IBM Voice Gateway/1.0.7.0"
}
},
"call": {
"start_timestamp": "2021-10-12T20:54:02.591Z",
"stop_timestamp": "2021-10-12T20:54:20.375Z",
"milliseconds_elapsed": 17784,
"outbound": false,
"end_reason": "assistant_hangup",
"security": {
"media_encrypted": false,
"signaling_encrypted": false,
"sip_authenticated": false
}
},
"session_initiation_protocol": {
"invite_arrival_time": "2021-10-12T20:54:00.565Z",
"setup_milliseconds": 2026,
"headers": {
"call_id": "17465345_115257202@10.90.150.99",
"from_uri": "sip:+18885550456@pstn.twilio.com",
"to_uri": "sip:+18005550123@public.voip.us-south.assistant.test.watson.cloud.ibm.com"
}
},
"max_response_milliseconds": {
"assistant": 339,
"text_to_speech": 535,
"speech_to_text": 0
},
"assistant_interaction_summaries": [
{
"session_id": "7874ec3a-1330-4180-afe1-46bfb220af5b",
"assistant_id": "97f16ba4-ad94-41af-aa6c-33cd56ad5e7e",
"turns": [
{
"assistant": {
"log_id": "58bebfd1-0118-419b-a555-b152a1efbbe8",
"response_milliseconds": 339,
"start_timestamp": "2021-10-12T20:54:00.722Z"
},
"request": {
"type": "start"
},
"response": [
{
"barge_in_occurred": true,
"streaming_statistics": {
"response_milliseconds": 301,
"start_timestamp": "2021-10-12T20:54:00.722Z",
"stop_timestamp": "2021-10-12T20:54:01.023Z",
"transaction_id": "3dce431c-fb2f-4b62-9fce-585f4e06fe00"
},
"type": "text_to_speech"
}
]
},
{
"assistant": {
"log_id": "38f36bfb-c2aa-4600-9418-6ab422664e31",
"response_milliseconds": 158,
"start_timestamp": "2021-10-12T20:54:05.621Z"
},
"request": {
"type": "dtmf"
},
"response": [
{
"type": "disable_speech_barge_in"
},
{
"type": "text_to_speech",
"barge_in_occurred": false,
"streaming_statistics": {
"transaction_id": "af4c47c3-5cc4-43c8-9b9c-81d6f997c52f",
"start_timestamp": "2021-10-12T20:54:06.321Z",
"stop_timestamp": "2021-10-12T20:54:14.338Z",
"response_milliseconds": 535
}
},
{
"type": "enable_speech_barge_in"
},
{
"type": "text_to_speech",
"barge_in_occurred": true,
"streaming_statistics": {
"transaction_id": "eafdd846-2829-4e1a-8068-b1035510b1e1",
"start_timestamp": "2021-10-12T20:54:14.795Z",
"stop_timestamp": "2021-10-12T20:54:20.388Z",
"response_milliseconds": 447
}
}
]
},
{
"assistant": {
"log_id": "07d74b35-0205-43e4-923c-1e43e1cb429c",
"response_milliseconds": 0,
"start_timestamp": "2021-10-12T20:54:20.377Z"
},
"request": {
"type": "hangup"
},
"response": []
}
]
}
]
}
有关 CDR 事件有效内容的结构的更多信息,请参阅 CDR 日志事件参考。