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

时间:2018-03-01 09:05:22

标签: chatbot facebook-messenger dialogflow

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

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

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

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

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

提前谢谢。

5 个答案:

答案 0 :(得分:3)

这是使用Struct protocols

构建的

为了转换你需要使用google proto buffer,google.protobuf 我用下面的代码来做这件事。

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

答案 1 :(得分:2)

编辑:显然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);

答案 2 :(得分:0)

有同样的问题,这无聊又痛苦,因为我们在服务器中通过网络钩子收到了这些无聊的k,v,这是因为 structJson 我使用NodeJS,是我来到的解决方案:

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 ...

答案 3 :(得分:0)

您现在可以使用pb-util将protobuf转换为Node中的JavaScript对象。根据{{​​3}},这是一个临时解决方案,直到它包含在客户端库中为止。

答案 4 :(得分:0)

我如何解码对话框流

我的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对象