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

在处理消息之前进行调用

每当客户提交输入时,预消息网络挂钩都会调用外部服务或应用程序。 外部服务可以先于助手处理信息。

如果您希望在助手处理每条新消息之前触发网络挂钩,请为助手添加一条预消息网络挂钩。

如果您使用的是自定义通道,则预发消息网络钩子仅适用于v2"/message 应用程序接口(无状态和有状态)。 有关更多信息,请参阅 API 参考。 所有内置通道集成都使用此 API。

您可以在以下用例中使用预发消息网络钩子:

  • 将客户的输入翻译成助理使用的语言。

  • 检查并删除任何个人身份信息,例如客户可能提交的电子邮件地址或社会保险号。

您可以将此网络挂钩与消息后网络挂钩配合使用。 例如,消息后的网络挂钩可以执行一些操作,例如将响应翻译回客户的语言,或者添加因隐私原因而被删除的信息。 有关更多信息,请参阅 在处理消息后进行调用

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

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

定义 Webhook

您可以定义一个 Webhook URL,用于预处理每一条传入信息。

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

  • 调用必须是 POST HTTP 请求。

  • 请求主体必须是 JSON 对象 (Content-Type: application/json)。

  • 呼叫必须在 30 秒或更短时间内返回。

如果外部服务仅支持 GET 请求,或需要在运行时动态指定 URL 参数,则可考虑创建一个中间服务,接受带有 JSON 有效负载(包含任何运行时值)的 POST 请求。 然后,中间服务可以向目标服务发出请求,将这些值作为 URL 参数传递,然后将响应返回给对话框。

请勿在部署了助手并与客户进行交互的生产环境中设置和测试 Webhook。

过程

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

  1. 在助手中,转至 环境 并打开要在其中配置 Webhook 的环境。

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

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

    要获得经典体验,请完成以下步骤:

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

    • 单击 Webhooks > Pre-message webhook

  4. 预消息 Webhook 开关设置为 已启用

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

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

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

    有关更多信息,请参阅“为预处理配置 webhook 错误处理”。

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

    例如,您可以编写 Cloud Functions Web 操作,以检查消息是否使用非英语语言,并将其发送到 Language Translator 服务以将其转换为英语。 指定网络操作的 URL,如本例所示:

    https://us-south.functions.cloud.ibm.com/api/v1/web/my_org_dev/default/translateToEnglish.json
    

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

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

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

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

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

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

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

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

仅为经典体验添加一个秘密

要获得经典体验,请在密文字段中添加私人密钥,以便与外部服务的身份验证请求一起传递:

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

  • 最多使用 1 024 个字符。

  • 不要使用上下文变量。

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

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

有关如何使用此字段的更多信息,请参阅 仅适用于经典体验的 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 响应时出错 网络钩子的 HTTP 响应体不是有效的 /message 体。
422 Webhook 响应了 [500] 状态码 您调用的外部服务存在问题。 代码失败或外部服务器拒绝了请求。
500 处理器异常: [connections to all backends failing] 在 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
}

请求主体

了解预消息网络钩子请求体的格式非常有用,这样您的外部代码就可以处理它。

有效内容包含 /message (有状态或无状态) v2 API 请求的请求主体。 事件名称 "message_received 表示该请求由预消息 Webhook 生成。 有关消息请求主体的更多信息,请参阅 API 参考

{
  "payload" : { Copy of request body sent to /message }
  "event": {
      "name": "message_received"
   }
}

跳过助理处理,只为经典体验

对于经典体验,信息前网络钩子的增强功能允许 watsonx Assistant 跳过信息处理,直接返回来自网络钩子的响应。 该功能可通过在网络钩子 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 调用名为 "check_language 的IBM Cloud FunctionsWeb 操作。

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 表示西班牙语的语言代码,因此 Webhook 有效并识别提交的文本是西班牙语短语。

示例 2

此示例显示如何检查入局消息的语言,如果它不是英语,请在将其提交给助手之前将其翻译为英语。

在IBM Cloud Functions中定义一系列网络操作。 序列中的第一个操作将检查传入文本的语言。 序列中的第二个操作将文本从其原始语言转换为英语。

在预消息 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
}
};

序列中的第二个 Web 操作将文本发送到 Watson Language Translator 服务,以将输入文本从先前 Web 操作中标识的语言转换为英语。 然后,会将转换后的字符串 (而不是原始文本) 发送到助手。

序列中第二个操作的 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 是英语一样。 事实上,当您检查助手的“分析”页面并打开 对话时,日志显示用户输入为 Good morning

您可以添加一个信息后 webhook,在显示信息之前将信息回复翻译成客户的语言。 有关更多信息,请参阅 示例 2

示例 3

本例展示了如何编写网络钩子响应,让 watsonx Assistant 跳过处理消息,直接返回网络钩子的响应。

Webhook 配置

在预消息网络挂钩配置页面中,指定以下值:

对于经典体验来说,“秘密”字段没有任何价值。

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

如果您决定不使用网络挂钩对客户输入进行预处理,请完成以下步骤:

  1. 在助手中,转至 环境 并打开要除去 Webhook 的环境。

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

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

    要获得经典体验,请完成以下步骤:

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

    • 单击 Webhooks > Pre-message webhook

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

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

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