Search code examples
actions-on-googledialogflow-esgoogle-assist-api

How can I push a message to a Dialogflow session?


I'm using Dialogflow API V2beta1 to build a Messenger + Google Assistant bot.

According to their docs, I can dispatch an event to trigger an intent. I'm able to successfully trigger the event, and the (200) response is logged in Firebase Functions, but the message is never pushed into the chat itself.

How can I ensure the response is pushed into to the current session?

// requries...
const app = express();
const sessionClient = new dialogflow.SessionsClient();

app.post('/detect', (req, res) => {
    console.log('handler');

    res.header('Content-Type', 'application/json');
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    res.header('Access-Control-Allow-Origin', 'my-domain');

    const bdy = JSON.parse(req.body);

    const sessionPath = sessionClient.sessionPath(projectId, bdy.session);

    const request = {
        session: sessionPath,
        queryParams: {
            session: sessionPath,
            contexts: [{
                name: `${sessionPath}/contexts/mycontext`,
                lifespan: 5,
                parameters: structjson.jsonToStructProto({ 'Model': bdy.model })
            }],
        },
        queryInput: {
            event: {
                name: 'my_event',
                parameters: structjson.jsonToStructProto(
                {
                    Model: bdy.model,
                }),
                languageCode: languageCode,
            },
        }
    };

    // Send request and log result
    console.log('md request: ', request);

    // here is where the intent is detected, and my handler for that successfully invoked
    sessionClient
        .detectIntent(request)
        .then(responses => {
            console.log('event response ', JSON.stringify(responses));
            const result = responses[0].queryResult;

            if (result.intent) {
                res.send(responses);
            } else {
                console.log(`  No intent matched.`);
                res.send({ text: 'not match' })
            }
        })
        .catch(err => {
            console.error('ERROR:', err);
            res.send(err);
        });

});

exports.myHandler = functions.https.onRequest(app);

And here's my response, with some params obfuscated:

[{
    "responseId": "c87b3c74-5c74-478b-8a5a-a0b90f059787",
    "queryResult": {
        "fulfillmentMessages": [{
            "platform": "PLATFORM_UNSPECIFIED",
            "text": {
                "text": ["You you have a BMW X1.\n        Next, I just need to know what computer you have"]
            },
            "message": "text"
        }],
        "outputContexts": [{
            "name": "projects/<my-project>/agent/sessions/<my-session>/contexts/<my-context>",
            "lifespanCount": 5,
            "parameters": {
                "fields": {
                    "Model.original": {
                        "stringValue": "",
                        "kind": "stringValue"
                    },
                    "Model": {
                        "stringValue": "BMW X1",
                        "kind": "stringValue"
                    }
                }
            }
        }],
        "queryText": "my_event",
        "speechRecognitionConfidence": 0,
        "action": "",
        "parameters": {
            "fields": {
                "Model": {
                    "stringValue": "",
                    "kind": "stringValue"
                }
            }
        },
        "allRequiredParamsPresent": true,
        "fulfillmentText": "You you have a BMW X1.\n        Next, I just need to know what computer you have",
        "webhookSource": "",
        "webhookPayload": null,
        "intent": {
            "inputContextNames": [],
            "events": [],
            "trainingPhrases": [],
            "outputContexts": [],
            "parameters": [],
            "messages": [],
            "defaultResponsePlatforms": [],
            "followupIntentInfo": [],
            "name": "projects/<my-project>/agent/intents/<intent-id>",
            "displayName": "my_event",
            "priority": 0,
            "isFallback": false,
            "webhookState": "WEBHOOK_STATE_UNSPECIFIED",
            "action": "",
            "resetContexts": false,
            "rootFollowupIntentName": "",
            "parentFollowupIntentName": "",
            "mlDisabled": false
        },
        "intentDetectionConfidence": 1,
        "diagnosticInfo": {
            "fields": {
                "webhook_latency_ms": {
                    "numberValue": 6065,
                    "kind": "numberValue"
                }
            }
        },
        "languageCode": "en-us"
    },
    "webhookStatus": {
        "details": [],
        "code": 0,
        "message": "Webhook execution successful"
    }
}]

Solution

  • Credit to Nick Felker's in the comments.

    Answer: You can't push messages into Assistant conversations. Instead, lead the user back into the conversation using push notifications and "I'm back"-like responses.