Google上的API.ai操作-无法解析带有“ INVALID_ARGUMENT”错误的JSON响应字符串:“:找不到字段”。 [英] API.ai Actions on Google - Failed to parse JSON response string with 'INVALID_ARGUMENT' error: ": Cannot find field."

查看:118
本文介绍了Google上的API.ai操作-无法解析带有“ INVALID_ARGUMENT”错误的JSON响应字符串:“:找不到字段”。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此错误与我问



将express.js与Google动作客户端一起使用

 '使用严格'; 

const express = require(‘express’);
const bodyParser = require(’body-parser’);
const intentHandler = require(’../ intent_handler')

const app = express();
app.use(bodyParser.json());

const ApiAiAssistant = require( Googles上的操作)。

//在此处创建函数以处理请求
....
....
const DIRECTION_INTENT ='action_direction';

函数MyAssistant(req,res){
const assistant = new ApiAiAssistant({request:req,response:res});
assistant.handleRequest(responseHandler(assistant));
}


函数responseHandler(辅助){
// intent包含您在API的Actions区域中定义的intent名称。AI
让意图= assistant.getIntent();
切换(意图){
case WELCOME_INTENT:
...
休息;
情况WELCOME_FALLBACK_PERMISSION_INTENT:
...
休息时间;
case DIRECTION_INTENT:
console.log(>>>>>" DIRECTION_INTENT<<<<<<<<));
intentHandler.directionIntent(assantant);
休息时间;
}
}
app.post(’/’,函数(req,res){
MyAssistant(req,res);
});
app.listen(8080,function(){
console.log(‘正在监听8080端口的应用程序!’)
});


处理程序代码

 '使用严格'; 
const speech = require( ./ speech_template);

const direction = require( ./ directionModule);

const intent_handler = {

'welcomeIntent':函数(辅助){
.....
},

'welcomeFallbackPermissionIntent':函数(辅助){
.....

},

'directionIntent':函数(辅助){
console.log('方向意图');
direction.getDirectionWithSavedAddress(function(response){
assistant.ask(response);
});
}
};

module.exports = intent_handler;


方向提取---在此操作完成之前,Action Console上出现错误

 使用严格; 

const striptags = require(’striptags’);
const speech = require( ./ speech_template);

let googleMapsClient = require(’@ google / maps).createClient({
键:global.GOOGLE_DIRECTION_KEY
});

const directionModule = {
‘getDirectionWithSavedAddress’:函数(eventCallback){
let myAdd =< From Saved Data>
if(myAdd ===未定义){
console.log(错误......);
}
let destination =<来自保存的数据> ;;
this.getDirectionWithAddress(myAdd,destination,function(dir){
....
if(SUCCESS){
eventCallback(`< speak> $ {steps}< ; / speak>`);
} else {
eventCallback(`< speak> $ {speech.ERROR_DIRECTIONS}< / speak>`);
}
}) ;
},
‘getDirectionWithAddress’:函数(add1,add2,eventCallback){
let dir = {};
googleMapsClient.directions({
来源:add1,
目的地:add2,
模式:行驶,
出发时间:现在
},函数(错误,响应){
if(!err){
console.log(response.json.routes [0]);
....
... 。
....
} else {
console.log(`Error-> $ {err.toString()}`);
....
}
eventCallback(dir);
});
}
};

module.exports = directionModule;

更新
我正在通过WebStorm在本地运行代码,并且



Update2

错误请求400



  {
originalRequest :{{
source: google,
version: 2,
data:{
isInSandbox:true,
表面:{
capabilities:[
{
name: actions.capability.AUDIO_OUTPUT
}
]
},
inputs:[
{
rawInputs:[
{
query: re,
inputType: VOICE
}
],
arguments:[
{
rawText:得到我那里,
textValue:让我到那里,
名称:文本
}
],
意图:动作。 intent.TEXT
}
],
user:{
locale: en-US,
userId:< uID> ;
},
设备:{},
会话:{
conversationId:< cID>,
类型: ACTIVE,
conversationToken: [\ _actions_on_google_\,\ defaultwelcomeintent-followup\]
}
}
},
id:< ID>,
timestamp: 2017-09-12T17:08:10.321Z,
lang: en,
结果:{
源:代理,
resolvedQuery:带我去,
语音:,
操作: action_direction,
actionIncomplete:false,
参数:{},
上下文:[
{
名称: _ actions_on_google_ ,
parameters:{},
lifespan:99
},
{
name: google_assistant_input_type_voice,
parameters :{},
lifespan:0
},
{
name: actions_capability_audio_output,
parameters:{},
lifespan:0
},
{
name: defaultwelcomeintent-followup,
parameters:{},
lifespan:4
}
],
元数据:{
intentId:< iID>,
webhookUsed: true,
webhookForSlotFillingUsed: false ,
nluResponseTime:15,
intentName: DirectionIntent
},
fulfillment:{
speech:,
messages:[
{
type:0,
speech:
}
]
},
分数:1
},
status:{
code:200,
errorType:成功
},
sessionId:< sID>
}

这似乎在我的回调完成之前,我的网络钩子向发送空响应Google Actions。

为什么会这样以及如何解决????

解决方案

问题出在 directionIntent()函数的调用方式以及如何处理 getDirectionWithSavedAddress()函数。它期望 getDirectionWithSavedAddress() 返回一个函数,但不返回。相反, getDirectionWithSavedAddress()希望将其结果发送到回调



因此,在调用 getDirectionWithAddress()之后,函数结束,不返回任何内容。此内容将发送到 assistant.ask(),然后将其返回到Google的服务器。这是无效的回复,因此您会收到错误消息。



修复此问题应该很简单。您需要使用回调函数调用 getDirectionWithSavedAddress()。在此函数内,您应该调用 assistant.ask()并将其值发送给回调。



所以 directionIntent()可能类似于

 'directionIntent':function(assistant) {
console.log('direction intent');
direction.getDirectionWithSavedAddress(function(msg){
assistant.ask(msg);
});
}

已更新



这行没有意义:

  assistant.handleRequest(responseHandler(assistant)); 

assistant.handleRequest()函数是应该将意图映射名称传递给函数以调用以处理事件。您是在 responseHandler()函数中手动完成此操作,并且没有返回Map。由于您未返回地图,因此在尝试执行 handleRequest()时会失败,并生成错误操作错误:请求处理程序不能为空。



您可以通过调用 responseHandler(assistant)而不处理 handleRequest()来解决此问题。 。或者,您可以创建 handleRequest()期望的地图,并完全摆脱 responseHandler()


This error is similar to what I asked here, but this time it's with NodeJs client.

I am trying to find directions to a location. As soon as the intent is triggered on my webhook, I am calculating the directions using GoogleMapAPI. But before it can finish and send a response, I receive the error on my Actions Console.

I checked total response time and it is less than 2 seconds which is less than 5 seconds timeout by Google.

Where I am wrong???

My API.ai Intent

Using express.js with Action-on-Google Node Client

'use strict';

const express = require('express');
const bodyParser = require('body-parser');
const intentHandler = require('./intent_handler')

const app = express();
app.use(bodyParser.json());

const ApiAiAssistant = require('actions-on-google').ApiAiAssistant;

// Create functions to handle requests here
....
....
const DIRECTION_INTENT = 'action_direction';

function MyAssistant(req, res) {
    const assistant = new ApiAiAssistant({request: req, response: res});
    assistant.handleRequest(responseHandler(assistant));
}


function responseHandler (assistant) {
    // intent contains the name of the intent you defined in the Actions area of API.AI
    let intent = assistant.getIntent();
    switch (intent) {
        case WELCOME_INTENT:
            ...
            break;
        case WELCOME_FALLBACK_PERMISSION_INTENT:
            ...
            break;
        case DIRECTION_INTENT:
            console.log(">>>>>>>DIRECTION_INTENT<<<<<<<");
            intentHandler.directionIntent(assistant);
            break;
    }
}
app.post('/', function (req, res) {
   MyAssistant(req, res);
});
app.listen(8080, function () {
    console.log('app listening on port 8080!')
});


Handler Code

'use strict';
const speech = require("./speech_template");

const direction = require("./directionModule");

const intent_handler = {

    'welcomeIntent': function (assistant) {
        .....
    },

    'welcomeFallbackPermissionIntent': function (assistant) {
        .....

    },

    'directionIntent':function (assistant) {
        console.log('direction intent');
        direction.getDirectionWithSavedAddress(function (response) {
            assistant.ask(response);
        });
    }
};

module.exports = intent_handler;


Direction Extraction --- ERROR comes on Action Console before this get finished

'use strict';

const striptags = require('striptags');
const speech = require("./speech_template");

let googleMapsClient = require('@google/maps').createClient({
    key: global.GOOGLE_DIRECTION_KEY
});

const directionModule = {
    'getDirectionWithSavedAddress': function (eventCallback) {
        let myAdd = <From Saved Data>;
        if (myAdd === undefined) {
            console.log("error......");
        }
        let destination = <From Saved Data>;
        this.getDirectionWithAddress(myAdd, destination, function (dir) {
            ....
            if(SUCCESS){
                eventCallback(`<speak> ${steps} </speak>`);
            }else{
                eventCallback(`<speak> ${speech.ERROR_DIRECTIONS} </speak>`);
            }
        });
    },
    'getDirectionWithAddress': function (add1, add2, eventCallback) {
        let dir = {};
        googleMapsClient.directions({
            origin: add1,
            destination: add2,
            mode: "driving",
            departure_time: "now"
        }, function (err, response) {
            if (!err) {
                console.log(response.json.routes[0]);
                ....
                ....
                ....
            } else {
                console.log(`Error --> ${err.toString()}`);
                ....
            }
            eventCallback(dir);
        });
    }
};

module.exports = directionModule;

UPDATE I am running the code locally via WebStorm and exposing webhook via port forwarding using ngrok.

Update2
BAD REQUEST 400

{
    "originalRequest": {
        "source": "google",
        "version": "2",
        "data": {
            "isInSandbox": true,
            "surface": {
                "capabilities": [
                    {
                        "name": "actions.capability.AUDIO_OUTPUT"
                    }
                ]
            },
            "inputs": [
                {
                    "rawInputs": [
                        {
                            "query": "get me there",
                            "inputType": "VOICE"
                        }
                    ],
                    "arguments": [
                        {
                            "rawText": "get me there",
                            "textValue": "get me there",
                            "name": "text"
                        }
                    ],
                    "intent": "actions.intent.TEXT"
                }
            ],
            "user": {
                "locale": "en-US",
                "userId": "<uID>"
            },
            "device": {},
            "conversation": {
                "conversationId": "<cID>",
                "type": "ACTIVE",
                "conversationToken": "[\"_actions_on_google_\",\"defaultwelcomeintent-followup\"]"
            }
        }
    },
    "id": "<ID>",
    "timestamp": "2017-09-12T17:08:10.321Z",
    "lang": "en",
    "result": {
        "source": "agent",
        "resolvedQuery": "get me there",
        "speech": "",
        "action": "action_direction",
        "actionIncomplete": false,
        "parameters": {},
        "contexts": [
            {
                "name": "_actions_on_google_",
                "parameters": {},
                "lifespan": 99
            },
            {
                "name": "google_assistant_input_type_voice",
                "parameters": {},
                "lifespan": 0
            },
            {
                "name": "actions_capability_audio_output",
                "parameters": {},
                "lifespan": 0
            },
            {
                "name": "defaultwelcomeintent-followup",
                "parameters": {},
                "lifespan": 4
            }
        ],
        "metadata": {
            "intentId": "<iID>",
            "webhookUsed": "true",
            "webhookForSlotFillingUsed": "false",
            "nluResponseTime": 15,
            "intentName": "DirectionIntent"
        },
        "fulfillment": {
            "speech": "",
            "messages": [
                {
                    "type": 0,
                    "speech": ""
                }
            ]
        },
        "score": 1
    },
    "status": {
        "code": 200,
        "errorType": "success"
    },
    "sessionId": "<sID>"
}

This looks like before my callback is finished, my webhook is sending empty response to Google Actions.
Why is this happening and How to resolve it?????

解决方案

The problem lies in how your directionIntent() function calls, and handles the result of, your getDirectionWithSavedAddress() function. It expects getDirectionWithSavedAddress() returns a function, when it does not. Instead, getDirectionWithSavedAddress() expects to send its results to a callback.

So after it makes its call to getDirectionWithAddress(), the function ends, returning nothing. This "nothing" is sent to assistant.ask(), which returns that to Google's server. This is an invalid response, so you're getting the error.

Fixing this should be straightforward. You need to call getDirectionWithSavedAddress() with a callback function. Inside this function you should call assistant.ask() with the value sent to the callback.

So directionIntent() might look something like

    'directionIntent':function (assistant) {
      console.log('direction intent');
      direction.getDirectionWithSavedAddress( function( msg ){
        assistant.ask( msg );
      } );
    }

Updated

This line makes no sense:

assistant.handleRequest(responseHandler(assistant));

The assistant.handleRequest() function is supposed to be passed a Map of Intent names to functions to call to handle the event. You're doing this manually in the responseHandler() function and you're not returning a Map. Since you're not returning a Map, it fails when trying to do the handleRequest() and generates the error "Action Error: Request handler can NOT be empty".

You can fix this by just calling responseHandler(assistant) and not dealing with handleRequest() at all. Or you can create the map that handleRequest() is expecting and get rid of responseHandler() completely.

这篇关于Google上的API.ai操作-无法解析带有“ INVALID_ARGUMENT”错误的JSON响应字符串:“:找不到字段”。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆