dialogflow-es - Dialogflow 中的 session 过期

标签 dialogflow-es

我知道上下文会在 15 分钟后过期,但是有没有办法手动解决它,即通过将之前的对话存储在 dB 中,这样我们可以处理该 session 过期问题,或者处理该 session 下的整个对话(输出上下文) ID会变得清晰,需要从头开始。

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"});
      }
    }    
});

最佳答案

我也偶然发现了这个问题。我的解决方案是保存用户 ID 并将上下文保存到 Firestore。

更新:

这就是我在 Firestore 中存储 Dialogflow 上下文的方式:

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;
    });
}

检索用户上下文:

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;
            }
        })
}

您可以通过循环并使用 contextClient 创建新上下文来再次设置上下文。或者使用此方法循环遍历上下文并找到您需要的:

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

                }
            });

原答案:

每当一个没有任何事件上下文的用户开始说话时,我都会检查数据库中是否存储了用户 ID。如果该用户存在于我的数据库中,我会检索用户信息及其所有数据,如下所示:

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;
                }

关于dialogflow-es - Dialogflow 中的 session 过期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56641625/

相关文章:

dialogflow-es - 带有 SSML 的 Google 操作因 "having HTML tags"被拒绝

google-cloud-functions - 类型错误 : handler is not a function using Firebase and DialogFlow with Google Actions

node.js - 使用 request-promise-native : unable to parse response 实现 Dialogflow

dialogflow-es - Dialogflow 帐户链接 - 谷歌主页

javascript - Calendar.events.lists 回调参数不会被调用

dialogflow-es - Google 操作未在测试中显示卡片

node.js - 在我的在线服务器上部署我的Messenger chatBot

javascript - Dialogflow Webhook(Webhook 调用失败。错误 : 500 Internal Server Error)

node.js - 向用户请求参数或触发履行事件

actions-on-google - 如何从我的 webhook 触发 `action.intent.INTENT_NAME` 意图?