Node.js Dialogflow V2并将请求正文中的参数传递给webhook

Node.js Dialogflow V2并将请求正文中的参数传递给webhook,node.js,google-cloud-functions,dialogflow-es,grpc,Node.js,Google Cloud Functions,Dialogflow Es,Grpc,我试图将参数传递给一个intent,并通过它的事件名调用intent 我知道parameters对象必须从Json转换为Struct,但由于某些原因,参数没有传递。我做错了什么 请注意我必须将谷歌提供的'structjson.js'复制并粘贴到与index.js相同的目录中,因为我要导出到Firebase函数,并且我必须在structjson.js中的某些函数中放置一些常量,以便导出这些函数以在我的index.js文件中使用 来自Dialogflow的预期响应:“您的用户ID是:0000000

我试图将参数传递给一个intent,并通过它的事件名调用intent

我知道parameters对象必须从Json转换为Struct,但由于某些原因,参数没有传递。我做错了什么

请注意我必须将谷歌提供的'structjson.js'复制并粘贴到与index.js相同的目录中,因为我要导出到Firebase函数,并且我必须在structjson.js中的某些函数中放置一些常量,以便导出这些函数以在我的index.js文件中使用

  • 来自Dialogflow的预期响应:“您的用户ID是:00000001”

  • 来自Dialogflow的实际响应:“您的用户ID是:${n_digit}”

请求对话框流代码

import * as functions from 'firebase-functions';
import * as dialogflow from 'dialogflow';
// // Start writing Firebase Functions
// // https://firebase.google.com/docs/functions/typescript
//
export const register = functions.https.onRequest((request, response) => {

    // Instantiates a session client
    const projectId = [MY_PROJECT_ID];
    const sessionId = '123456789';
    const languageCode = 'en-US';
    let config = {
            credentials: {
                private_key: [MY_PRIVATE_KEY],
                client_email: [MY_CLIENT_EMAIL]
            }
        }
    const sessionClient = new dialogflow.SessionsClient(config);

    // The path to identify the agent that owns the created intent.
    const sessionPath = sessionClient.sessionPath(projectId, sessionId);

    var structjson = require('./structjson')

    // The text query request.
    const req = {
    session: sessionPath,
    queryParams: {
        "resetContexts": true,
    },
    queryInput: {
      event: {
        name: 'init',
        parameters: structjson.jsonToStructProto({userID: '00000001'}),
        languageCode: languageCode,
      },
    },
    };

    sessionClient
    .detectIntent(req)
    .then((responses) => {
      const result = responses[0].queryResult;
      response.send(result.fulfillmentText);
    })
    .catch(err => {
      console.error('ERROR:', err);
    });
})
structjson.js

module.exports.jsonToStructProto = function jsonToStructProto(json) {
    var structjson = require('./structjson')
      const fields = {};
      for (const k in json) {
        fields[k] = structjson.jsonValueToProto(json[k]);
      }

      return {fields};
    }

    module.exports.jsonValueToProto = function jsonValueToProto(value) {
      const valueProto = {};
      const JSON_SIMPLE_TYPE_TO_PROTO_KIND_MAP = {
        [typeof 0]: 'numberValue',
        [typeof '']: 'stringValue',
        [typeof false]: 'boolValue',
      };

      if (value === null) {
        valueProto.kind = 'nullValue';
        valueProto.nullValue = 'NULL_VALUE';
      } else if (value instanceof Array) {
        valueProto.kind = 'listValue';
        valueProto.listValue = {values: value.map(jsonValueToProto)};
      } else if (typeof value === 'object') {
        valueProto.kind = 'structValue';
        valueProto.structValue = jsonToStructProto(value);
      } else if (typeof value in JSON_SIMPLE_TYPE_TO_PROTO_KIND_MAP) {
        const kind = JSON_SIMPLE_TYPE_TO_PROTO_KIND_MAP[typeof value];
        valueProto.kind = kind;
        valueProto[kind] = value;
      } else {
        console.warn('Unsupported value type ', typeof value);
      }
      return valueProto;
    }

    module.exports.structProtoToJson = function structProtoToJson(proto) {
      if (!proto || !proto.fields) {
        return {};
      }
      const json = {};
      for (const k in proto.fields) {
        json[k] = valueProtoToJson(proto.fields[k]);
      }
      return json;
    }

    module.exports.valueProtoToJson = function valueProtoToJson(proto) {

        const JSON_SIMPLE_VALUE_KINDS = new Set([
          'numberValue',
          'stringValue',
          'boolValue',
        ]);

      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;
      }
    }
Dialogflow webhook

function receiveParams (agent) {
    const parameter = request.body.queryResult.parameters;
     const n_digit = parameter.userID;
     agent.add('Your user ID is: ${n_digit}');
  }

  let intentMap = new Map();
  intentMap.set('init', receiveParams);  
  agent.handleRequest(intentMap);
});

提前谢谢你

您可以发送如下参数

{  
  "fulfillmentText":"This is a text response",
  "fulfillmentMessages":[  ],
  "source":"example.com",
  "payload":{  
    "google":{  },
    "facebook":{  },
    "slack":{  }
  },
  "outputContexts":[  
    {  
      "name":"<Context Name>",
      "lifespanCount":5,
      "parameters":{  
        "<param name>":"<param value>"
      }
    }
  ],
  "followupEventInput":{  }
}
{
“fulfillmentText”:“这是一个文本响应”,
“完成消息”:[],
“来源”:“example.com”,
“有效载荷”:{
“谷歌”:{},
“facebook”:{},
“松弛”:{}
},
“输出上下文”:[
{  
“名称”:“,
“生命计数”:5,
“参数”:{
"":""
}
}
],
“followupEventInput”:{}
}
使用可以保存参数,如

let param1 = [];
let param2 = {};
let ctx = {'name': '<context name>', 'lifespan': 5, 'parameters': {'param1':param1, 'param2': param2}};
agent.setContext(ctx);
让param1=[];
设param2={};
设ctx={'name':'','lifespan':5,'parameters':{'param1':param1,'param2':param2};
agent.setContext(ctx);
然后像这样访问这些参数

let params = agent.getContext("<context name>").parameters;
let param1 = params.param1;
let param2 = params.param2; 
let params=agent.getContext(“”).parameters;
设param1=params.param1;
设param2=params.param2;

查看我的。

我想指出,您必须在该参数中使用struct对象这一事实与gRPC无关。这只是API的定义方式。这里唯一真正特定于gRPC的是从普通JS对象到API使用的protobuf消息的自动转换。很好!已编辑,谢谢这是要将上下文参数从客户端服务器发送到代理吗?这是要保存参数以便在后续对话中使用。这可以从客户端和服务器访问,直到上下文激活。啊!我明白了,对不起,在这篇文章中,我应该给出更多的上下文。您发送的NodeJS库是针对代理端的(fulfillment webhook)。我只是尝试在从web服务器发送到Dialogflow代理的有效负载中插入参数。我没有错过什么,是吗?感谢您迄今为止的帮助和回复。您可以在JSON中插入参数,如上图所示:)现在我们可以使用
let params=agent.originalRequest.parameters根据太,发现这工作得很好。即使在请求中添加上下文参数,它也会在原始请求子项下弹出。谢谢你帮我做到这一点,@Abhinav Tyagi。