Session expiring in Dialogflow

Viewed 1329

I came to know that context expires in 15 minutes but is there any way to solve it manually i.e by storing the previous conversation in dB so can we handle that session expiring issue or else the whole conversation(output context) under that session ID will get clear and need to start from the first.

exports.fulfillmenttext = functions.https.onRequest((req,res) =>{ 
    const answer1 = req.body.Text;
    console.log("Text said by the user",answer1);
    const uid = answer1.substring(0,28);
    console.log("uid1 is",uid);
    const answer = answer1.substring(28);
    console.log("answer is",answer);
    const sessionId = uid;
    var count,questvalue;
    runSample();
    async function runSample(projectId = 'xxxxxxx') {
      const languageCode = 'en-US';
      const credentials = {
        client_email: 'xxxxxxxxxx',
        private_key: 'xxxxxxxxx'
      };
      //Instantiate a DialogFlow client.
      const dialogflow = require('dialogflow');
      const sessionClient = new dialogflow.SessionsClient({
        projectId,
        credentials,
      });
    // Define session path
      const sessionPath = sessionClient.sessionPath(projectId, sessionId);
      // The text query request.
      const request = {
        session: sessionPath,
        queryInput: {
          text: {
            text: answer,
            languageCode,
          },
        },
      };
      const responses =  await sessionClient.detectIntent(request);
      console.log('Detected intent');
      const result = responses[0].queryResult;
      let action = result.action; 
      console.log("action is"+action);
      console.log(`  Query: ${result.queryText}`);
      console.log(`  Response: ${result.fulfillmentText}`);
      if (result.intent) {
        const question = result.fulfillmentText;
        console.log("question is",question);
        const actionHandlers = {
            'early': () => {
                console.log('earlyaction1', action);
                let name1 = JSON.stringify(result.parameters.fields.Name.stringValue);
                name1 = name1.toString().replace(/"/g,"");
                var data1 = {
                    Name: name1
                };
                var setDoc1 = admin.firestore().collection('User').doc(uid).collection("Popop").doc(uid).collection('Answers').doc('Earlyyears').update(data1);

            },
            'family': () => {
                console.log('familyaction1', action);
                let mname1 = JSON.stringify(result.parameters.fields.M_Name.stringValue);
                let mname_string = mname1.toString().replace(/"/g,"");
                var data20 = {
                    MName: mname_string
                };
                var setDoc20 = admin.firestore().collection('User').doc(uid).collection("Popop").doc(uid).collection('Answers').doc('Family').update(data20);

            }

        };
        if (action === 'early') {
             console.log('1');
             actionHandlers[action]();
        }
        else if (action === 'family') {
            console.log('2');
            actionHandlers[action]();
        }

        res.status(200).send({"question":result.fulfillmentText,"action":action});


      } else {
          console.log(`  No intent matched.`);
          res.status(400).send({"action":"empty"});
      }
    }    
});
1 Answers

I stumbled upon this problem as well. My solution was to save the userID and save the contexts to Firestore.

UPDATE:

This is how I stored Dialogflow's contexts in Firestore:

function saveContexts(userId, contexts) {
let UID = userId;

//get all contexts + parameters

if (contexts === undefined) {
    console.log("contexts are undefined! returning");
    return false;
}
db.collection("user-contexts-prod").doc(UID).set({
    dateCreated: new Date(),
    contexts: JSON.stringify(contexts)
})
    .then(function () {
        console.log("success!");
        return true;
    })
    .catch(function (error) {
        console.log("error writing document..", error);
        return false;
    });
}

Retrieving user contexts:

async function getContexts(userId) {
    let UID = userId;
    let docRef = db.collection("user-contexts-prod").doc(UID);
    return docRef.get()
        .then(res => {
            if (res.exists) {
                let contexts = JSON.parse(res.data().contexts);
                console.log("<><> parsed contexts <><>: ");
                console.log(contexts);
                return contexts;
            } else {
                console.log(" UID DOES NOT EXIST!");
                return false;
            }
        })
}

You can set the contexts again by looping over them and using the contextClient to create new contexts. Or use this method to loop through the contexts and find the one you need:

contexts.forEach(function(context) {
                if (context.name === 'projects/{DIALOGFLOWPROJECTID}/agent/sessions/' + senderId + '/contexts/{CONTEXTNAME}') {
                    sessionData = context.parameters;
                    // all data that you saved in CONTEXTNAME is now available in the sessionData variable

                }
            });

Original answer:

Whenever a user started talking that didn't have any active contexts I check if I had the userID stored in my Database. If this user existed in my DB I retrieved the user information with all his data like this:

knownUser = await db.isKnownUser(senderId);
                if (knownUser) {
                    //knownUser
                    console.log("Known user");
                    let userData = db.getUserDataById(senderId)

                    //initialize contexts with data you need

                    payload = returningUser_useSameData();
                    messenger.send(payload, senderId);

                    dashbot.logBotMessage(payload.toString, sessionId, intentName);
                    break;

                } else {
                    //newUser
                    console.log("new user");

                    createContext('await_fillInTogether', '', sessionPath, sessionId, 1);
                    createContext('session', '', sessionPath, sessionId, 500);

                    payload = fillInTogetherNewUser();
                    messenger.send(payload, senderId);

                    dashbot.logBotMessage(payload.toString, sessionId, intentName);
                    break;
                }
Related