dialogflow / dialogflow-fulfillment-nodejs

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

Dialogflow looses the context's variables #309

Open EugeniaCasFrag opened 4 years ago

EugeniaCasFrag commented 4 years ago

I am creating a chatbot using Dialogflow and firebase. Right now I have a context called "contextvariable", this context is created in the welcome intent and has the following parameters by default: agent.context.set({ 'name':'contextvariable', 'lifespan': 100, 'parameters':{ 'userID':userID, 'currentQ':'', 'currentQuestionID':'', 'GA':[], 'GB':[], 'GC':[], 'GD':[], 'notDone' : [] } }); I use this context to save variables that I need all throughout the session and that are private to each user that is interacting with the chatbot. The context works great along the workflow, updating the parameters when needed be etc...however, it gets to a point where the context looses the value of some parameters. Let me explain in more detail.

Up to the intent function called "getQuestion" the context is great. Function getQuestion:

`function getQuestion(groupID,questionID){ let group; if(groupID=="QGroupA"){ agent.setContext({name: "QGroupA", lifespan:1}); }else if(groupID=="QGroupB"){ agent.setContext({name: "QGroupB", lifespan:1}); }else if(groupID=="QGroupC"){ agent.setContext({name: "QGroupC", lifespan:1}); }else{ agent.setContext({name: "QGroupD", lifespan:1}); } return db.collection(groupID).doc(questionID).get().then(function(doc){ console.log(doc.data()); let info = doc.data(); console.log(info.text); let currQ = info.text; updateContext("currentQ",currQ);

    let visual = Math.floor(Math.random() * 2);
    console.log(visual);
    if(visual == 1){
      var pl_tl = {
          "telegram": {
            "text": currQ,
            "reply_markup": {
              "inline_keyboard": [
                [
                  {
                    "text": "Never",
                    "callback_data": "Never"
                  },
                  {
                    "text": "Rarely",
                    "callback_data": "Rarely"
                  },
                  {
                    "text": "Sometimes",
                    "callback_data": "Sometimes"
                  },
                  {
                    "text": "Quite Frequently",
                    "callback_data": "Quite Frequently"
                  },
                  {
                    "text": "Nearly Always",
                    "callback_data": "Nearly Always"
                  }
                ]
              ]
            }
          }};

          agent.add(new Payload(agent.TELEGRAM, pl_tl, { sendAsMessage: true, rawPayload: true }));
    }else{
      agent.add(currQ);
      agent.add(new Suggestion('Never'));
      agent.add(new Suggestion('Rarely'));
      agent.add(new Suggestion('Sometimes'));
      agent.add(new Suggestion('Quite Frequently'));
      agent.add(new Suggestion('Nearly always'));
    }
  console.log(My context after all the changes is: +JSON.stringify(agent.context.get("contextvariable")));

}).catch((err) => {
    console.error(Error in getQuestion creating file: +err);
});

}`

The context after this function is: {"name":"contextvariable", "lifespan":99, "parameters": {"userID":"358599997", "currentQ":"Do you feel that because of the time you spend with your relative that you don't have enough time for yourself?", "currentQuestionID":"3", "GA":[1,3,4,5,6], "GB":[], "GC":[], "GD":[], "notDone":[1,2,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19,20,21,22]} }

The following intent, called "AskQuestionGroupA" is the one detected after that function writes a message to the user and the user responds. The intent's setup is as follows: image1 image2 As you can see in the image, the intent has no parameters that can be confused with the parameters of the context "contextvariable", however, the context recieved by the function mapped to this intent has the following parameter values: This is the mapping of the intent to the function: intentMap.set('AskQuestionGroupA',getAnswerQuestionA);

This is the function 'getAnswerQuestionA': `function getAnswerQuestionA(){ console.log('I am in getAnswerQuestion with this context:' +JSON.stringify(agent.context.get('contextvariable')));

 let answerOfUser= request.body.queryResult.queryText;
 console.log(`respuesta a pregunta->`+agent.context.get('contextvariable').parameters.currentQ);
 agent.add(`Su respuesta ha sido `+answerOfUser);
 if(answerOfUser==`Never`){
   console.log(`Estoy en getAnswerQuestion con never`);
   return updateAnswers(0);
 }else if(answerOfUser==`Rarely`){
   return updateAnswers(1);
 }else if(answerOfUser==`Sometimes`){
   return updateAnswers(2);
 }else if(answerOfUser==`Quite Frequently`){
   return updateAnswers(3);
 }else if(answerOfUser==`Nearly Always`){
   return updateAnswers(4);
 }

}`

This is the context recieved: {"name":"contextvariable", "lifespan":98, "parameters":{ "userID":"358599997", "currentQ":"", "currentQuestionID":"", "GA":[1,3,4,5,6], "GB":[], "GC":[], "GD":[], "notDone":[1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19,20,21,22]}}

If you look closely, not only the parameters currentQ and currentQuestionID have changed but also the parameter notDone.

I have checked other post and all say that usually this happens when you have names that can be confused with the names of the parameters of the context, but as you can see, this is not a problem for me...

Can anyone imagine why this is happening????

fosteman commented 3 years ago

Hm. Thanks for sharing @EugeniaCasFrag . I am having somewhat of a similar problem. Here's the legacy code And here's what I am doing: I am collecting a sequence of numbers and use my context to hold on (and accumulate the sequence)

agent.context.set({
                name: 'collecting-sequence',
                parameters: {
                    new_sequence: '',
                    existing_sequence: existing_sequence.concat(new_sequence.split(' '))
                },
                lifespan: 5
            })
agent.setFollowupEvent('continue-collecting')

But, as it happens, continue-collecting event does not pick up the updated context, and I receive it blank all the time.

EugeniaCasFrag commented 3 years ago

I ended up creating a function. As you can see, instead of creating all the parameters of the context directly, use a json, i found that dialogflow made less errors. ` function updateContext(field, value){

let contextVariables = agent.context.get('contextvariable');
contextVariables.parameters[field] = value;
console.log(`Estos son los parametros de contexto despues del cambio-->`+JSON.stringify(contextVariables.parameters) );
let sessionContext = {    
  'name':'contextvariable',
  'lifespan': 100,
  'parameters':contextVariables.parameters
};
agent.context.set(sessionContext);  

} `