0
votes

I am currently writing an integration into Actions on Google using PHP. I have generated a action.json file with my test endpoint as the fulfillment. I use ngrok to expose my local development machine publicly.

Unfortunately the simulator keeps insisting that the app isn't responding. In the access logs, and the ngrok Inspector I do see that a request came in, and it has been neatly answered with a JSON reply.

In an act of pure desperation I even upload a JSON response, directly taken from the Fulfillment documentation page to a server and set that as the fulfillment URL. The result is the same, same error.

I do not see a way to get a more detailed error message from Actions on Google, explaining why it does not work.

My action.json:

{
    "actions": [
        {
            "name": "MAIN",
            "intent": {
                "name": "actions.intent.MAIN"
            },
            "fulfillment": {
                "conversationName": "development4"
            }
        },
        {
            "name": "TEXT",
            "intent": {
                "name": "actions.intent.TEXT"
            },
            "fulfillment": {
                "conversationName": "development4"
            }
        }
    ],
    "conversations": {
        "development4": {
            "name": "development4",
            "url": "https:\/\/02c085c0.ngrok.io\/actionsongoogle\/process\/development4"
        }
    }
}

The json I response with:

{
    "expectUserResponse": false,
    "expectedInputs": [{
        "inputPrompt": {
            "richInitialPrompt": {
                "items": [{
                    "simpleResponse": {
                        "textToSpeech": "hello"
                    }
                }]
            }
        },
        "possibleIntents": [{
            "intent": ["actions.intent.TEXT"]
        }]
    }]
}

The result output in the Simulator then displays:

{
    "response": "my test app isn’t responding right now. Try again soon.\n",
    "audioResponse": "//NExAARq...",
    "debugInfo": {
        "sharedDebugInfo": [
            {
                "name": "ExecutionResponse",
                "debugInfo": "Failed to call your endpoint."
            }
        ]
    },
    "visualResponse": {}
}
2
I just noticed that the api version it used was v1, even though the docs state: If you created a project on or after May 17, 2017, your Assistant app will use the v2 API by default.. Adding the "fulfillment_api_version": 2 attribute to my conversation unfortunately did not help. - daangemist

2 Answers

0
votes

Two things to investigate:

  1. Check how long it is taking for the reply to be sent. Agents need to send a response back within about 5 seconds or the Assistant will time out and give the "not responding" message.

  2. Check what the reply code being issued is. If you think you're sending something back, but your server actually crashes before an HTTP 200 response code is sent back with the body, the Assistant never gets the response. I've also seen it where people are thinking they're sending a response - but no response is actually sent at all.

Testing with curl or wget to your ngrok URL (so it makes a full round trip) might be able to help diagnose both of these.

0
votes

The issue was in the returned JSON. I have set up the nodejs SDK and reply in the same way as the PHP cod will (a simple hello). The response generated by the NodeJS SDK is very different. Apparently the example that I used from the docs earlier is also invalid.

I advice anyone building their own implementation using Webhooks to first generate the desired response via de NodeJS sdk, the reference in the manual is not always clear (at least for me).

Response by NodeJS SDK:

{
    "expectUserResponse": false,
    "finalResponse": {
        "speechResponse": {
            "textToSpeech": "hello"
        }
    }
}

Implementation in SDK:

var express = require('express')
var bodyParser = require('body-parser')

var app = express()

// parse application/x-www-form-urlencoded 
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json 
app.use(bodyParser.json())

app.use(function (req, res) {
        let ActionsSdkApp = require('actions-on-google').ActionsSdkApp;
        const actionsApp = new ActionsSdkApp({request: req, response: res});
        //const inputPrompt = actionsApp.buildInputPrompt(false, 'hello')
  actionsApp.tell('hello');

})

app.listen(80);