dialogflow / dialogflow-fulfillment-nodejs

Dialogflow agent fulfillment library supporting v1&v2, 8 platforms, and text, card, image, suggestion, custom responses
Apache License 2.0
597 stars 281 forks source link

How to response webhook without agent.add #271

Closed chik-taks closed 4 years ago

chik-taks commented 4 years ago

I faced a problem. I send a message with "LINE messenger", and call webhook to add a context parameter, I got a following Error.

Error: No responses defined for platform: LINE
    at V2Agent.sendResponses_ (/srv/node_modules/dialogflow-fulfillment/src/v2-agent.js:243:13)
    at WebhookClient.send_ (/srv/node_modules/dialogflow-fulfillment/src/dialogflow-fulfillment.js:505:17)
    at promise.then (/srv/node_modules/dialogflow-fulfillment/src/dialogflow-fulfillment.js:316:38)
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:229:7)

I look up this library code, and find that, when I use a webhook without response message, sendResponses_ method in v2-agent.js is called, and following code is executed.

    if (!responseJson) {
      throw new Error(`No responses defined for platform: ${requestSource}`);
    }

someone could you help me? my code like this

'use strict';

const functions = require('firebase-functions');
const { WebhookClient } = require('dialogflow-fulfillment');
const { Card, Suggestion, Image, Payload, Text } = require('dialogflow-fulfillment');

process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
  console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
  console.log('Dialogflow Request body: ' + JSON.stringify(request.body));

  const agent = new WebhookClient({ request, response });

  function first_intent(agent) {   
    const context_test = {
      "name": "test",
      "lifespan": 2,
      "parameters": {
        "test": "test"
      }
    };
    agent.context.set(context_test);
  }

  // Run the proper function handler based on the matched Dialogflow intent name
  let intentMap = new Map();
  intentMap.set('first_intent', first_intent);
  agent.handleRequest(intentMap);
});

thanks.

samuel9914 commented 4 years ago

so how to solve this issue?

chik-taks commented 4 years ago

No I cannot resolve this issue, so I add response text which defined in this server instead of Dialogflow Agent Intent. However, I kind of remember that Error is happen when you add two or more Dialoglow.Text Object (or maybe Custom Payload Object). so be careful to define responses if you defined multiple text message in Dialogflow Agent Intent.

DIALQGUE commented 2 years ago

Could you elaborate this for me? I try to make LINE messaging API too, and it worked yesterday when I just deploy it. But now it stuck with this error.

Below is my code, I try to use Intent to send the food name parameter back to Dialogflow since I have to wait for user's answer before I save the history record from it. How can I edit it to make it work?

const express = require('express');
const Foods = require('../../models/foods-model');
const router = express.Router();

const { WebhookClient } = require('dialogflow-fulfillment');

router.post('/', function (req, res) {
    const agent = new WebhookClient({
        request: req,
        response: res
    });

    let intentMap = new Map();

    intentMap.set('Recommend - condition - yes', (agent) => {
        return new Promise((resolve, reject) => {
            Foods.findOne({ 'tag.ingredient': agent.parameters.condition }).lean().exec((err, found) => {
                if (!found)
                    resolve('No requested food in system');
                else {
                    Foods.find({ 'tag.ingredient': agent.parameters.condition }).lean().exec((err, selectedFoods) => {
                        try {
                            var random = Math.floor(Math.random() * selectedFoods.length);
                            const food = selectedFoods[random];
                            resolve(`${food.name}`);
                        }
                        catch (err) {
                            reject(err);
                        }
                    });
                }
            })
        })
            .then((msg) => {
                agent.setContext({ name: 'response', lifespan: 1, parameters: { food: msg } });
            })
            .catch(err => {
                console.log(err);
            });
    });

    intentMap.set('Recommend - no condition', (agent) => {
        return new Promise((resolve, reject) => {
            Foods.find().lean().exec((err, foods) => {
                try {
                    var random = Math.floor(Math.random() * foods.length);
                    const food = foods[random];
                    console.log(`randomized food: ${food.name}`);
                    resolve(`${food.name}`);
                }
                catch (err) {
                    reject(err);
                }
            });
        })
            .then((msg) => {
                agent.setContext({ name: 'response', lifespan: 1, parameters: { food: msg } });
            })
            .catch(err => {
                console.log(err);
            });
    });

    intentMap.set('Recommend - accepted', (agent) => {
        const history = new userHistory({
            user_id: agent.originalRequest.payload.data.user.id,
            food: agent.getContext('response').parameters.food,
            date: Date.now(),
            accepted: true
        });

        history.save((err, saved) => {
            if (err)
                console.log(err);
            else
                console.log(`user history saved: ${saved}`);
        });
    });

    agent.handleRequest(intentMap);
});

module.exports = router;