IBM Cloud Docs
在处理消息后进行调用

在处理消息后进行调用

消息后网络钩子会在助手每次做出响应时调用外部服务或应用程序。 外部服务可以先处理助手的输出,然后再将其发送到通道。

如果想在向客户显示每条信息回复之前触发 webhook,可以在助手中添加“信息后 webhook”。

您可以使用消息后网络钩子来做一些事情,比如从外部内容存储库中提取自定义响应。 例如,您可以使用响应中的定制标识 (而不是文本) 来定义操作。 消息后网络钩子可将这些 ID 传递给外部数据库,以检索存储的文本响应。

您可以将此网络钩子与预消息网络钩子配合使用。 例如,如果您使用信息前网络钩子从客户的输入中剥离个人身份信息,您可以使用信息后网络钩子将其添加回来。 如果使用信息前网络钩子将客户的输入翻译成助手的语言,则可以使用信息后网络钩子将响应翻译成客户的语言,然后再返回。 有关更多信息,请参阅 在处理消息之前进行调用

对于使用专用端点的环境,请记住网络钩子会通过互联网发送流量。

定义 Webhook

您可以定义一个 Webhook URL,用于处理每个消息响应,然后将其发送到通道并显示给客户。

准备工作

对外部服务的程序化调用必须满足以下需求:

  • 请勿在部署了助手并与客户进行交互的生产环境中设置和测试 Webhook。
  • 调用必须是 POST HTTP 请求。
  • 调用必须在 30 秒或更短的时间内完成。
  • 请求和响应的格式必须为 JSON。 例如,Content-Type: application/json

如果需要在对话期间执行一次性操作,请使用对话 webhook。 例如,当助手收集到所有必需的详细信息(如账号、用户 ID 和账户保密信息)时,就满足了条件。 有关更多信息,请参阅从对话发起程序化调用

为每种部署类型设置信息发布后网络钩子的步骤

选择您使用的 watsonx Assistant 部署类型,查看消息后 webhook 配置步骤:

要确定您使用的部署类型,请单击“管理 ”菜单管理菜单。 如果您看到切换到经典体验,说明您正在使用新体验。 如果您看到 “切换到新体验”,则表示您正在使用经典体验

本节将介绍定义、测试和移除信息后网络钩子的步骤,这些钩子用于 IBM Cloud Pak for Data:

本节介绍为 IBM Cloud Pak for Data- 经典体验定义、测试和删除消息后网络钩子的步骤:

本节包括定义、测试和移除信息后网络钩子的步骤,这些钩子包括 watsonx Assistant:

本节介绍为 watsonx Assistant- 经典体验定义、测试和删除消息后网络钩子的步骤:

程序 IBM Cloud Pak for Data

要添加 Webhook 详细信息,请完成以下步骤:

  1. 从导航面板中单击环境,然后打开要配置 webhook 的环境。

  2. 单击 环境设置图标 图标以打开环境设置。

  3. Post-message Webhook 开关设置为 Enabled

  4. 同步事件中,从以下选项中选择一个:

    • 如果出现错误,则继续处理用户输入,不更新 webhook。

    • 如果 webhook 调用失败,则向客户端返回错误信息。

    更多信息,请参阅“为后处理配置网络钩子错误处理”。

  5. URL 字段中,添加要向其发送 HTTP POST 请求调出的外部应用程序的 URL。

    例如,可以将助手的响应存储在单独的内容管理系统中。 当助手理解了输入内容后,处理过的操作会返回一个唯一的 ID,该 ID 与 CMS 中的响应相对应。 要调用从内容CMS中检索特定唯一 ID 响应的服务,请指定服务实例的 URL。 例如,https://example.com/get_answer

    您必须指定一个使用 SSL 协议的 URL,因此请指定一个以 https 开头的 URL。

  6. 要配置消息后网络钩子的身份验证,请单击编辑身份验证。 有关详细说明,请参阅 为信息前和信息后网络钩子定义身份验证方法

  7. 在“超时”字段中,指定助手在返回错误前等待网络钩子响应的时间长度(秒)。 超时持续时间不能短于 1 秒或长于 30 秒。

  8. 在“标头”部分,单击“添加标头 +”,一次添加一个要传递给服务的标头。

    如果您调用的外部应用程序返回响应,它可能会以不同的格式发送响应。 Webhook 要求以 JSON 格式格式化响应。 下表说明了如何添加标头,以表明您希望返回 JSON 格式的结果值。

    头示例
    头名称 头值
    Content-Type application/json
  9. 保存标题值后,字符串将被替换为星号,无法再次查看。

  10. 这将自动保存 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) 时,您会知道您的 Webhook 存在问题。 如果显示此消息,请使用 REST API 工具(如 cURL, 发送测试 /message API 请求),以便查看错误代码和返回的完整消息。

错误代码详细信息
错误代码和消息 描述
422 Webhook 响应了无效的 JSON 主体 网络钩子的 HTTP 响应体无法解析为 JSON。
422 Webhook 响应了 [500] 状态码 您所拨打的外部服务出现了问题。 代码失败或外部服务器拒绝了请求。
500 处理器异常: [connections to all backends failing] 在 Webhook 微服务中发生错误。 无法连接到后端服务。

示例请求主体

了解请求后消息 Webhook 主体的格式非常有用,这样外部代码就能对其进行处理。

有效负载包含助手为 v2 /message(有状态和无状态)API 调用返回的响应体。 事件名称 message_processed 表示消息后网络钩子生成了请求。 有关消息请求主体的更多信息,请参阅 API 参考

以下示例展示了如何格式化简单的请求正文:

{
 "event": {
    "name": "message_processed"
},
"options": {},
"payload": {
    "output": {
        "intents": [
            {
                "intent": "General_Greetings",
                "confidence": 1
            }
        ],
        "entities": [],
        "generic": [
            {
                "response_type": "text",
                "text": "Hello. Good evening"
            }
        ]
    },
    "user_id": "test user",
    "context": {
        "global": {
            "system": {
                "user_id": "test user",
                "turn_count": 11
            },
            "session_id": "sxxx"
        },
        "skills": {
            "actions skill": {
                "user_defined": {
                    "var": "anthony"
                },
                "system": {
                    "state": "nnn"
                }
            }
        }
    }
}

示例 1

本示例展示了如何在助手的每个回复末尾添加 y'all

在后消息 webhook 配置页面中,可指定以下值:

  • URL: https://your-webhook-url/
  • 头名称:Content-Type
  • 头值:application/json

消息后网络钩子调用 IBM Cloud Functions 网络操作名称 add_southern_charm

add_southern_charm Web 操作中的 node.js 代码如下所示:

function main(params) {
  console.log(JSON.stringify(params))
  if (params.payload.output.generic[0].text !== '') {
      //Get the length of the input text
        var length = params.payload.output.generic[0].text.length;
        //create a substring that removes the last character from the input string, which is typically punctuation.
        var revision = params.payload.output.generic[0].text.substring(0,length-1);
        const response = {
            body : {
                payload : {
                    output : {
                        generic : [
                              {
                                  //Replace the input text with your shortened revision and append y'all to it.
                                "response_type": "text",
                                "text": revision + ', ' + 'y\'all.'
                              }
                        ],
                    },
                },
            },
        };
        return response;
  }
  else {
    return {
        body : params
    }
  }
}

示例 2

本例展示了如何将信息回复翻译成客户语言。 只有执行 例 2 中的步骤,定义一个将原始信息翻译成英文的预发信息 webhook,它才会起作用。

在 IBM Cloud Functions中定义一系列网络操作。 序列中的第一个操作是检查原始输入文本的语言,该语言存储在消息前 Webhook 代码中名为 original_input 的上下文变量中。 序列中的第二个操作将对话响应文本从英语转换为客户使用的原始语言。

在预消息 webhook 配置页面中,可指定以下值:

  • URL: https://your-webhook-url/
  • 头名称:Content-Type
  • 头值:application/json

序列中第一个 Web 操作的 node.js 代码如下所示:

let rp = require("request-promise");

function main(params) {
console.log(JSON.stringify(params))

if (params.payload.output.generic[0].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': 'nnnn'
       },
  headers: {
    "Content-Type":"text/plain"
},
  body: [
          params.payload.context.skills['actions skill'].user_defined.original_input
  ],
  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 param
}
};

序列中的第二个 Web 操作如下所示:

let rp = require("request-promise");

function main(params) {
  console.log(JSON.stringify(params))
    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'
        },
    body: {
        text: [
            params.payload.output.generic[0].text
            ],
            target: params.payload.context.skills["actions skill"].user_defined.language
    },
    json: true
    };
      return rp(options)
      .then(res => {
          params.payload.context.skills["actions skill"].user_defined["original_output"] = params.payload.output.generic[0].text;
          params.payload.output.generic[0].text = res.translations[0].translation;
          return {
            body : params
          }
  })
  }
  return {
    body : params
  }
};

除去 Webhook

如果您决定不使用网络挂钩处理消息响应,请完成以下步骤:

  1. 在您的助手中,进入“环境”,打开您要移除webhook的环境。

  2. 单击 环境设置图标 图标以打开环境设置。

  3. 在“环境设置”页面上,单击 发布消息 Webhook

  4. 执行下列其中一个操作:

  • 要停止调用网络挂钩处理每条传入消息,请将 “消息后”网络挂钩开关设置为“禁用”。

  • 要更改要调用的网络钩子,请单击删除网络钩子

程序 IBM Cloud Pak for Data- 经典体验

要添加 Webhook 详细信息,请完成以下步骤:

  1. 对于要配置的助手,单击溢出菜单 图标,然后选择设置

  2. 单击 Webhooks > Post-message webhook

  3. Post-message Webhook 开关设置为 Enabled

  4. 同步事件中,从以下选项中选择一个:

    • 如果出现错误,则继续处理用户输入,不更新 webhook。

    • 如果 webhook 调用失败,则向客户端返回错误信息。

    更多信息,请参阅“为后处理配置网络钩子错误处理”。

  5. URL 字段中,添加要向其发送 HTTP POST 请求调出的外部应用程序的 URL。

    例如,可以将助手的响应存储在单独的内容管理系统中。 当助手理解了输入内容后,处理过的操作会返回一个唯一的 ID,该 ID 与 CMS 中的响应相对应。 要调用从内容CMS中检索特定唯一 ID 响应的服务,请指定服务实例的 URL。 例如,https://example.com/get_answer

    您必须指定一个使用 SSL 协议的 URL,因此请指定一个以 https 开头的 URL。

  6. 填写秘密字段。 更多信息,请参阅 添加秘密

  7. 在“超时”字段中,指定助手在返回错误前等待网络钩子响应的时间长度(秒)。 超时持续时间不能短于 1 秒或长于 30 秒。

  8. 在“标头”部分,单击“添加标头 +”,一次添加一个要传递给服务的标头。

    服务会自动发送带有 JWT 的授权标头。 如果您想自己处理授权,请添加自己的授权标头,然后服务会使用它。

    如果您调用的外部应用程序返回响应,它可能会以不同的格式发送响应。 Webhook 要求以 JSON 格式格式化响应。 下表说明了如何添加标头,以表明您希望返回 JSON 格式的结果值。

    头示例
    头名称 头值
    Content-Type application/json
  9. 保存标题值后,字符串将被替换为星号,无法再次查看。

  10. 这将自动保存 Webhook 详细信息。

添加秘密

密文字段中添加私人密钥,与外部服务的身份验证请求一起传递:

  • 以文本字符串形式输入密钥,如 purple unicorn

  • 最多使用 1 024 个字符。

  • 请勿使用上下文变量。

外部服务负责检查和验证密文。 如果不需要标记,可指定任何字符串。 该字段不能为空。

要在输入密码时查看密码,请在输入前单击显示密码图标查看图标。 保存秘密后,星号将取代字符串,您将无法再次查看。

有关如何使用此字段的更多信息,请参阅 Webhook 安全性

Webhook 安全性

通过验证随请求一起发送的 JSON 网络令牌(JWT)来验证 webhook 请求。 Webhook 微服务会自动生成 JWT,并在每次 Webhook 调用时通过 Authorization 标头发送:

  • 对于新的网络钩子或通过编辑身份验证更新的网络钩子,授权标头将被忽略。

  • 对于已保存身份验证标头的现有网络钩子,“编辑身份验证”按钮是禁用的。

  • 更新现有 Webhook 以使用新的身份验证配置将改变其行为。

如果需要测试 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 调用失败,则向客户端返回错误信息:如果在助手发送响应后,后处理至关重要,请选择此选项。

当您启用 “如果 webhook 调用失败则向客户端返回错误” 时,一切都会停止,直到后处理步骤成功完成。

定期测试外部流程,找出潜在故障。 如有必要,请调整此设置,以防止响应处理中断。

测试 Webhook

在为生产环境中使用的助手启用网络钩子之前,请对其进行大量测试。

只有当您的助手处理了一条信息并准备好向通道返回响应时,才会触发 webhook。

对 Webhook 进行故障诊断

以下错误代码可帮助您跟踪可能迂到的问题的原因。 例如,如果您具有 Web 聊天集成,那么当您提交的每条测试消息都返回一条消息 (例如 There is an error with the message you just sent, but feel free to ask me something else) 时,您会知道您的 Webhook 存在问题。 如果显示此消息,请使用 REST API 工具(如 cURL, 发送测试 /message API 请求),以便查看错误代码和返回的完整消息。

错误代码详细信息
错误代码和消息 描述
422 Webhook 响应了无效的 JSON 主体 网络钩子的 HTTP 响应体无法解析为 JSON。
422 Webhook 响应了 [500] 状态码 您所拨打的外部服务出现了问题。 代码失败或外部服务器拒绝了请求。
500 处理器异常: [connections to all backends failing] 在 Webhook 微服务中发生错误。 无法连接到后端服务。

示例请求主体

了解请求后消息 Webhook 主体的格式非常有用,这样外部代码就能对其进行处理。

有效负载包含助手为 v2 /message(有状态和无状态)API 调用返回的响应体。 事件名称 message_processed 表示消息后网络钩子生成了请求。 有关消息请求主体的更多信息,请参阅 API 参考

以下示例展示了如何格式化简单的请求正文:

{
 "event": {
    "name": "message_processed"
},
"options": {},
"payload": {
    "output": {
        "intents": [
            {
                "intent": "General_Greetings",
                "confidence": 1
            }
        ],
        "entities": [],
        "generic": [
            {
                "response_type": "text",
                "text": "Hello. Good evening"
            }
        ]
    },
    "user_id": "test user",
    "context": {
        "global": {
            "system": {
                "user_id": "test user",
                "turn_count": 11
            },
            "session_id": "sxxx"
        },
        "skills": {
            "actions skill": {
                "user_defined": {
                    "var": "anthony"
                },
                "system": {
                    "state": "nnn"
                }
            }
        }
    }
}

示例 1

本示例展示了如何在助手的每个回复末尾添加 y'all

在后消息 webhook 配置页面中,可指定以下值:

  • URL: https://your-webhook-url/
  • 秘密:无
  • 头名称:Content-Type
  • 头值:application/json

消息后网络钩子调用 IBM Cloud Functions 网络操作名称 add_southern_charm

add_southern_charm Web 操作中的 node.js 代码如下所示:

function main(params) {
  console.log(JSON.stringify(params))
  if (params.payload.output.generic[0].text !== '') {
      //Get the length of the input text
        var length = params.payload.output.generic[0].text.length;
        //create a substring that removes the last character from the input string, which is typically punctuation.
        var revision = params.payload.output.generic[0].text.substring(0,length-1);
        const response = {
            body : {
                payload : {
                    output : {
                        generic : [
                              {
                                  //Replace the input text with your shortened revision and append y'all to it.
                                "response_type": "text",
                                "text": revision + ', ' + 'y\'all.'
                              }
                        ],
                    },
                },
            },
        };
        return response;
  }
  else {
    return {
        body : params
    }
  }
}

示例 2

本例展示了如何将信息回复翻译成客户语言。 只有执行 例 2 中的步骤,定义一个将原始信息翻译成英文的预发信息 webhook,它才会起作用。

在 IBM Cloud Functions中定义一系列网络操作。 序列中的第一个操作是检查原始输入文本的语言,该语言存储在消息前 Webhook 代码中名为 original_input 的上下文变量中。 序列中的第二个操作将对话响应文本从英语转换为客户使用的原始语言。

在预消息 webhook 配置页面中,可指定以下值:

  • URL: https://your-webhook-url/
  • 秘密:无
  • 头名称:Content-Type
  • 头值:application/json

序列中第一个 Web 操作的 node.js 代码如下所示:

let rp = require("request-promise");

function main(params) {
console.log(JSON.stringify(params))

if (params.payload.output.generic[0].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': 'nnnn'
       },
  headers: {
    "Content-Type":"text/plain"
},
  body: [
          params.payload.context.skills['actions skill'].user_defined.original_input
  ],
  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 param
}
};

序列中的第二个 Web 操作如下所示:

let rp = require("request-promise");

function main(params) {
  console.log(JSON.stringify(params))
    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'
        },
    body: {
        text: [
            params.payload.output.generic[0].text
            ],
            target: params.payload.context.skills["actions skill"].user_defined.language
    },
    json: true
    };
      return rp(options)
      .then(res => {
          params.payload.context.skills["actions skill"].user_defined["original_output"] = params.payload.output.generic[0].text;
          params.payload.output.generic[0].text = res.translations[0].translation;
          return {
            body : params
          }
  })
  }
  return {
    body : params
  }
};

除去 Webhook

如果您决定不使用网络挂钩处理消息响应,请完成以下步骤:

  1. 对于要配置的助手,单击溢出菜单 图标,然后选择设置

  2. 单击 Webhooks > Post-message webhook

  3. 执行下列其中一个操作:

  • 要停止调用网络挂钩处理每条传入消息,请将 “消息后”网络挂钩开关设置为“禁用”。

  • 要更改要调用的网络钩子,请单击删除网络钩子

程序 {site.data.keyword.conversationshort}

要添加 Webhook 详细信息,请完成以下步骤:

  1. 从导航面板中单击环境,然后打开要配置 webhook 的环境。

  2. 单击 环境设置图标 图标以打开环境设置。

  3. Post-message Webhook 开关设置为 Enabled

  4. 同步事件中,从以下选项中选择一个:

    • 如果出现错误,则继续处理用户输入,不更新 webhook。

    • 如果 webhook 调用失败,则向客户端返回错误信息。

    更多信息,请参阅“为后处理配置网络钩子错误处理”。

  5. URL 字段中,添加要向其发送 HTTP POST 请求调出的外部应用程序的 URL。

    例如,可以将助手的响应存储在单独的内容管理系统中。 当助手理解了输入内容后,处理过的操作会返回一个唯一的 ID,该 ID 与 CMS 中的响应相对应。 要调用从内容CMS中检索特定唯一 ID 响应的服务,请指定服务实例的 URL。 例如,https://example.com/get_answer

    您必须指定一个使用 SSL 协议的 URL,因此请指定一个以 https 开头的 URL。

  6. 要配置消息后网络钩子的身份验证,请单击编辑身份验证。 有关详细说明,请参阅 为信息前和信息后网络钩子定义身份验证方法

  7. 在“超时”字段中,指定助手在返回错误前等待网络钩子响应的时间长度(秒)。 超时持续时间不能短于 1 秒或长于 30 秒。

  8. 在“标头”部分,单击“添加标头 +”,一次添加一个要传递给服务的标头。

    如果您调用的外部应用程序返回响应,它可能会以不同的格式发送响应。 Webhook 要求以 JSON 格式格式化响应。 下表说明了如何添加标头,以表明您希望返回 JSON 格式的结果值。

    头示例
    头名称 头值
    Content-Type application/json
  9. 保存标题值后,字符串将被替换为星号,无法再次查看。

  10. 这将自动保存 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) 时,您会知道您的 Webhook 存在问题。 如果显示此消息,请使用 REST API 工具(如 cURL, 发送测试 /message API 请求),以便查看错误代码和返回的完整消息。

错误代码详细信息
错误代码和消息 描述
422 Webhook 响应了无效的 JSON 主体 网络钩子的 HTTP 响应体无法解析为 JSON。
422 Webhook 响应了 [500] 状态码 您所拨打的外部服务出现了问题。 代码失败或外部服务器拒绝了请求。
500 处理器异常: [connections to all backends failing] 在 Webhook 微服务中发生错误。 无法连接到后端服务。

示例请求主体

了解请求后消息 Webhook 主体的格式非常有用,这样外部代码就能对其进行处理。

有效负载包含助手为 v2 /message(有状态和无状态)API 调用返回的响应体。 事件名称 message_processed 表示消息后网络钩子生成了请求。 有关消息请求主体的更多信息,请参阅 API 参考

以下示例展示了如何格式化简单的请求正文:

{
 "event": {
    "name": "message_processed"
},
"options": {},
"payload": {
    "output": {
        "intents": [
            {
                "intent": "General_Greetings",
                "confidence": 1
            }
        ],
        "entities": [],
        "generic": [
            {
                "response_type": "text",
                "text": "Hello. Good evening"
            }
        ]
    },
    "user_id": "test user",
    "context": {
        "global": {
            "system": {
                "user_id": "test user",
                "turn_count": 11
            },
            "session_id": "sxxx"
        },
        "skills": {
            "actions skill": {
                "user_defined": {
                    "var": "anthony"
                },
                "system": {
                    "state": "nnn"
                }
            }
        }
    }
}

示例 1

本示例展示了如何在助手的每个回复末尾添加 y'all

在后消息 webhook 配置页面中,可指定以下值:

  • URL: https://your-webhook-url/
  • 头名称:Content-Type
  • 头值:application/json

消息后网络钩子调用 IBM Cloud Functions 网络操作名称 add_southern_charm

add_southern_charm Web 操作中的 node.js 代码如下所示:

function main(params) {
  console.log(JSON.stringify(params))
  if (params.payload.output.generic[0].text !== '') {
      //Get the length of the input text
        var length = params.payload.output.generic[0].text.length;
        //create a substring that removes the last character from the input string, which is typically punctuation.
        var revision = params.payload.output.generic[0].text.substring(0,length-1);
        const response = {
            body : {
                payload : {
                    output : {
                        generic : [
                              {
                                  //Replace the input text with your shortened revision and append y'all to it.
                                "response_type": "text",
                                "text": revision + ', ' + 'y\'all.'
                              }
                        ],
                    },
                },
            },
        };
        return response;
  }
  else {
    return {
        body : params
    }
  }
}

示例 2

本例展示了如何将信息回复翻译成客户语言。 只有执行 例 2 中的步骤,定义一个将原始信息翻译成英文的预发信息 webhook,它才会起作用。

在 IBM Cloud Functions中定义一系列网络操作。 序列中的第一个操作是检查原始输入文本的语言,该语言存储在消息前 Webhook 代码中名为 original_input 的上下文变量中。 序列中的第二个操作将对话响应文本从英语转换为客户使用的原始语言。

在预消息 webhook 配置页面中,可指定以下值:

  • URL: https://your-webhook-url/
  • 头名称:Content-Type
  • 头值:application/json

序列中第一个 Web 操作的 node.js 代码如下所示:

let rp = require("request-promise");

function main(params) {
console.log(JSON.stringify(params))

if (params.payload.output.generic[0].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': 'nnnn'
       },
  headers: {
    "Content-Type":"text/plain"
},
  body: [
          params.payload.context.skills['actions skill'].user_defined.original_input
  ],
  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 param
}
};

序列中的第二个 Web 操作如下所示:

let rp = require("request-promise");

function main(params) {
  console.log(JSON.stringify(params))
    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'
        },
    body: {
        text: [
            params.payload.output.generic[0].text
            ],
            target: params.payload.context.skills["actions skill"].user_defined.language
    },
    json: true
    };
      return rp(options)
      .then(res => {
          params.payload.context.skills["actions skill"].user_defined["original_output"] = params.payload.output.generic[0].text;
          params.payload.output.generic[0].text = res.translations[0].translation;
          return {
            body : params
          }
  })
  }
  return {
    body : params
  }
};

除去 Webhook

如果您决定不使用网络挂钩处理消息响应,请完成以下步骤:

  1. 在您的助手中,进入“环境”,打开您要移除webhook的环境。

  2. 单击 环境设置图标 图标以打开环境设置。

  3. 在“环境设置”页面上,单击 发布消息 Webhook

  4. 执行下列其中一个操作:

  • 要停止调用网络挂钩处理每条传入消息,请将 “消息后”网络挂钩开关设置为“禁用”。

  • 要更改要调用的网络钩子,请单击删除网络钩子

{site.data.keyword.conversationshort}- 经典经验

要添加 Webhook 详细信息,请完成以下步骤:

  1. 对于要配置的助手,单击溢出菜单 图标,然后选择设置

  2. 单击 Webhooks > Post-message webhook

  3. Post-message Webhook 开关设置为 Enabled

  4. 同步事件中,从以下选项中选择一个:

    • 如果出现错误,则继续处理用户输入,不更新 webhook。

    • 如果 webhook 调用失败,则向客户端返回错误信息。

    更多信息,请参阅“为后处理配置网络钩子错误处理”。

  5. URL 字段中,添加要向其发送 HTTP POST 请求调出的外部应用程序的 URL。

    例如,可以将助手的响应存储在单独的内容管理系统中。 当助手理解了输入内容后,处理过的操作会返回一个唯一的 ID,该 ID 与 CMS 中的响应相对应。 要调用从内容CMS中检索特定唯一 ID 响应的服务,请指定服务实例的 URL。 例如,https://example.com/get_answer

    您必须指定一个使用 SSL 协议的 URL,因此请指定一个以 https 开头的 URL。

  6. 填写秘密字段。 更多信息,请参阅 添加秘密

  7. 在“超时”字段中,指定助手在返回错误前等待网络钩子响应的时间长度(秒)。 超时持续时间不能短于 1 秒或长于 30 秒。

  8. 在“标头”部分,单击“添加标头 +”,一次添加一个要传递给服务的标头。

    服务会自动发送带有 JWT 的授权标头。 如果您想自己处理授权,请添加自己的授权标头,然后服务会使用它。

    如果您调用的外部应用程序返回响应,它可能会以不同的格式发送响应。 Webhook 要求以 JSON 格式格式化响应。 下表说明了如何添加标头,以表明您希望返回 JSON 格式的结果值。

    头示例
    头名称 头值
    Content-Type application/json
  9. 保存标题值后,字符串将被替换为星号,无法再次查看。

  10. 这将自动保存 Webhook 详细信息。

添加秘密

密文字段中添加私人密钥,与外部服务的身份验证请求一起传递:

  • 以文本字符串形式输入密钥,如 purple unicorn

  • 最多使用 1 024 个字符。

  • 请勿使用上下文变量。

外部服务负责检查和验证密文。 如果不需要标记,可指定任何字符串。 该字段不能为空。

要在输入密码时查看密码,请在输入前单击显示密码图标查看图标。 保存秘密后,星号将取代字符串,您将无法再次查看。

有关如何使用此字段的更多信息,请参阅 Webhook 安全性

Webhook 安全性

通过验证随请求一起发送的 JSON 网络令牌(JWT)来验证 webhook 请求。 Webhook 微服务会自动生成 JWT,并在每次 Webhook 调用时通过 Authorization 标头发送:

  • 对于新的网络钩子或通过编辑身份验证更新的网络钩子,授权标头将被忽略。

  • 对于已保存身份验证标头的现有网络钩子,“编辑身份验证”按钮是禁用的。

  • 更新现有 Webhook 以使用新的身份验证配置将改变其行为。

如果需要测试 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 调用失败,则向客户端返回错误信息:如果在助手发送响应后,后处理至关重要,请选择此选项。

当您启用 “如果 webhook 调用失败则向客户端返回错误” 时,一切都会停止,直到后处理步骤成功完成。

定期测试外部流程,找出潜在故障。 如有必要,请调整此设置,以防止响应处理中断。

测试 Webhook

在为生产环境中使用的助手启用网络钩子之前,请对其进行大量测试。

只有当您的助手处理了一条信息并准备好向通道返回响应时,才会触发 webhook。

对 Webhook 进行故障诊断

以下错误代码可帮助您跟踪可能迂到的问题的原因。 例如,如果您具有 Web 聊天集成,那么当您提交的每条测试消息都返回一条消息 (例如 There is an error with the message you just sent, but feel free to ask me something else) 时,您会知道您的 Webhook 存在问题。 如果显示此消息,请使用 REST API 工具(如 cURL, 发送测试 /message API 请求),以便查看错误代码和返回的完整消息。

错误代码详细信息
错误代码和消息 描述
422 Webhook 响应了无效的 JSON 主体 网络钩子的 HTTP 响应体无法解析为 JSON。
422 Webhook 响应了 [500] 状态码 您所拨打的外部服务出现了问题。 代码失败或外部服务器拒绝了请求。
500 处理器异常: [connections to all backends failing] 在 Webhook 微服务中发生错误。 无法连接到后端服务。

示例请求主体

了解请求后消息 Webhook 主体的格式非常有用,这样外部代码就能对其进行处理。

有效负载包含助手为 v2 /message(有状态和无状态)API 调用返回的响应体。 事件名称 message_processed 表示消息后网络钩子生成了请求。 有关消息请求主体的更多信息,请参阅 API 参考

以下示例展示了如何格式化简单的请求正文:

{
 "event": {
    "name": "message_processed"
},
"options": {},
"payload": {
    "output": {
        "intents": [
            {
                "intent": "General_Greetings",
                "confidence": 1
            }
        ],
        "entities": [],
        "generic": [
            {
                "response_type": "text",
                "text": "Hello. Good evening"
            }
        ]
    },
    "user_id": "test user",
    "context": {
        "global": {
            "system": {
                "user_id": "test user",
                "turn_count": 11
            },
            "session_id": "sxxx"
        },
        "skills": {
            "actions skill": {
                "user_defined": {
                    "var": "anthony"
                },
                "system": {
                    "state": "nnn"
                }
            }
        }
    }
}

示例 1

本示例展示了如何在助手的每个回复末尾添加 y'all

在后消息 webhook 配置页面中,可指定以下值:

  • URL: https://your-webhook-url/
  • 秘密:无
  • 头名称:Content-Type
  • 头值:application/json

消息后网络钩子调用 IBM Cloud Functions 网络操作名称 add_southern_charm

add_southern_charm Web 操作中的 node.js 代码如下所示:

function main(params) {
  console.log(JSON.stringify(params))
  if (params.payload.output.generic[0].text !== '') {
      //Get the length of the input text
        var length = params.payload.output.generic[0].text.length;
        //create a substring that removes the last character from the input string, which is typically punctuation.
        var revision = params.payload.output.generic[0].text.substring(0,length-1);
        const response = {
            body : {
                payload : {
                    output : {
                        generic : [
                              {
                                  //Replace the input text with your shortened revision and append y'all to it.
                                "response_type": "text",
                                "text": revision + ', ' + 'y\'all.'
                              }
                        ],
                    },
                },
            },
        };
        return response;
  }
  else {
    return {
        body : params
    }
  }
}

示例 2

本例展示了如何将信息回复翻译成客户语言。 只有执行 例 2 中的步骤,定义一个将原始信息翻译成英文的预发信息 webhook,它才会起作用。

在 IBM Cloud Functions中定义一系列网络操作。 序列中的第一个操作是检查原始输入文本的语言,该语言存储在消息前 Webhook 代码中名为 original_input 的上下文变量中。 序列中的第二个操作将对话响应文本从英语转换为客户使用的原始语言。

在预消息 webhook 配置页面中,可指定以下值:

  • URL: https://your-webhook-url/
  • 秘密:无
  • 头名称:Content-Type
  • 头值:application/json

序列中第一个 Web 操作的 node.js 代码如下所示:

let rp = require("request-promise");

function main(params) {
console.log(JSON.stringify(params))

if (params.payload.output.generic[0].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': 'nnnn'
       },
  headers: {
    "Content-Type":"text/plain"
},
  body: [
          params.payload.context.skills['actions skill'].user_defined.original_input
  ],
  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 param
}
};

序列中的第二个 Web 操作如下所示:

let rp = require("request-promise");

function main(params) {
  console.log(JSON.stringify(params))
    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'
        },
    body: {
        text: [
            params.payload.output.generic[0].text
            ],
            target: params.payload.context.skills["actions skill"].user_defined.language
    },
    json: true
    };
      return rp(options)
      .then(res => {
          params.payload.context.skills["actions skill"].user_defined["original_output"] = params.payload.output.generic[0].text;
          params.payload.output.generic[0].text = res.translations[0].translation;
          return {
            body : params
          }
  })
  }
  return {
    body : params
  }
};

除去 Webhook

如果您决定不使用网络挂钩处理消息响应,请完成以下步骤:

  1. 对于要配置的助手,单击溢出菜单 图标,然后选择设置

  2. 单击 Webhooks > Post-message webhook

  3. 执行下列其中一个操作:

  • 要停止调用网络挂钩处理每条传入消息,请将 “消息后”网络挂钩开关设置为“禁用”。

  • 要更改要调用的网络钩子,请单击删除网络钩子