繁体   English   中英

如何在 Dialogflow v2 中反序列化自定义负载响应?

[英]How to deserialize custom payload response in Dialogflow v2?

我正在使用 Dialogflow v2 和 Node.js 客户端 SDK 为 Messenger 开发自己的聊天机器人。 但是我在自定义有效负载方面遇到了问题。 当我使用 Dialogflow 提供的控制台时,我的响应如下所示:

{ "payload": { "facebook": { "attachment": { "payload": { ...

但是,当我从 JS 服务器获得响应时,自定义负载已被序列化。 这是我收到的对象:

{ facebook: { structValue: { fields: [Object] }, kind: 'structValue' } }

是否可以反序列化此对象以获得与我在 Dialogflow 中提供的相同的自定义有效负载结构?

提前谢谢你。

编辑:显然 Dialogflow 发布了他们自己的解决方案,其中包含 Node.js SDK 的示例: dialogflow-nodejs-client-v2/samples/structjson.js

作为 Vikas Jain 解决方案的替代方案,您可以编写自己的(递归)转换函数。

类似的东西:

processCustomPayloadMessage(object) {
  let outputMessage = Array.isArray(object) ? [] : {};
  Object.entries(object).forEach(([key, value]) => {
    if (value.kind == 'structValue') {
      outputMessage[key] = this.processCustomPayloadMessage(value.structValue.fields);
    } else if (value.kind == 'listValue') {
      outputMessage[key] = this.processCustomPayloadMessage(value.listValue.values);
    } else if (value.kind == 'stringValue') {
      outputMessage[key] = value.stringValue;
    } else if (value.kind == 'boolValue') {
      outputMessage[key] = value.boolValue;
    } else {
      outputMessage[key] = value;
    }
  });
  return outputMessage;
}

// call this method with your response message
this.processCustomPayloadMessage(message.payload.fields);

这是使用Struct 协议构建的

为了转换它,您需要使用 google proto 缓冲区,即google.protobuf我使用下面的代码来做到这一点。

import google.protobuf  as pf
pf.json_format.MessageToJson(response.query_result.fulfillment_messages[1].payload, including_default_value_fields=False)

有同样的问题,这是非常可怕和痛苦的,这些添加的 k,v 我们在我们的服务器中作为 webhooks 收到,这是非常糟糕和痛苦的,这是因为我使用NodeJS 的 structJson ,这是我找到的一个解决方案:

 const JSON_SIMPLE_VALUE_KINDS = new Set([ 'numberValue', 'stringValue', 'boolValue', ]); function valueProtoToJson(proto) { if (!proto || !proto.kind) { return null; } if (JSON_SIMPLE_VALUE_KINDS.has(proto.kind)) { return proto[proto.kind]; } else if (proto.kind === 'nullValue') { return null; } else if (proto.kind === 'listValue') { if (!proto.listValue || !proto.listValue.values) { console.warn('Invalid JSON list value proto: ', JSON.stringify(proto)); } return proto.listValue.values.map(valueProtoToJson); } else if (proto.kind === 'structValue') { return structProtoToJson(proto.structValue); } else { console.warn('Unsupported JSON value proto kind: ', proto.kind); return null; } } function structProtoToJson(proto) { if (!proto || !proto.fields) { return {}; } const json = {}; for (const k in proto.fields) { json[k] = valueProtoToJson(proto.fields[k]); } return json; } Once added, you apply this function to your result : var correctJSON = valueProtoToJson(Response_dialogflow.fulfillmentMessages[0].payload.fields.facebook)

您只需将valueProtoToJson函数应用于 Dialogflow 响应中的 dsired 元素,其中有效负载为:Response_dialogflow.fulfillmentMessages[0]... 或1 ...

您现在可以使用pb-util将 protobuf 转换为 node.js 中的 JavaScript 对象。 根据nodejs-dialogflow上的这个评论,这是一个临时解决方案,直到它被包含在客户端库中。

我如何解码对话流

从我的 API 到(dialogflow webhook 实现请求)的响应格式

const response = {
"status":200,
"messages":[{},{} ...]
}

我如何从我的 API 读取响应以发送聊天机器人或做某事..

var express = require('express');
var {value} = require('pb-util');
var router = express.Router();

...

const status = value.decode(data[0].queryResult.webhookPayload.fields.status);
const messages = value.decode(data[0].queryResult.webhookPayload.fields.messages);

pb-util将我的状态和消息转换为普通的 JSON 对象

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM