Глобальная переменная вебхука

Я создал веб-хук node.js для своего бота-мессенджера в Facebook. Бот встроен в диалоговый поток, а база данных подключена к firebase. Мой вопрос, когда функция вызывается в веб-перехватчике для входа в систему, после входа в систему я получаю идентификатор пользователя из базы данных, который я хочу сохранить где-то в коде, чтобы информация об идентификаторе пользователя была доступна на протяжении всего пользовательского сеанса. Я храню его в глобальной переменной. Однако это прекрасно работает, если бот использует только один пользователь. Если другой пользователь одновременно использует бота, эта информация об идентификаторе пользователя передается между пользователями, поскольку она хранится в глобальной переменной. Как мне это решить? Пожалуйста помоги.

var loggedIn = true;
        for (i = 0; i < contexts.length; i++) {
            console.log("Inside contexts for loop");
            //Check for login details context. 
            if (contexts[i].name == "logindetails") {
                if (contexts[0].parameters.loggedIn == "true") {
                    //set this true if found.
                    loggedIn = true;
                }
            }
        }
        if (loggedIn) {
            showUserAccountOptions(sender);
        }   //else start the login flow and once logged in create the 'logindetails' contexts and set the loggedIn parameter as true.
        else {
            //Login 
            login(email, password);

            //Post the logindetails contexts 
            console.log("Not found");
            let url = "https://api.dialogflow.com/v1/contexts?sessionId=" + response.sessionId;
            console.log("URL", url);
            var con = {
                method: 'POST',
                url: url,
                qs: { access_token: '****' },
                headers: {
                    'content-type': 'application/json',
                    'Authorization': 'Bearer' + ' ****'
                },
                body:
                    [
                        {
                            "lifespan": 25,
                            "name": "logindetails",
                            "parameters": {
                                "loggedIn": "true"
                            }
                        }
                    ],
                json: true
            };

            request(con, function (error, response, body) {
                console.log("Inside api request");
                if (error) {
                    console.log("Inside Error", error);
                }
                else{
                    //show user options
                    showUserAccountOptions(sender);
                }

            });

        }

Отправка обновлений контекстов в диалоговый поток:

    let apirespone = let apirespone = {
                "contexts": [
                    {
                      "name": "logindetails",
                      "parameters": {},
                      "lifespan": 5
                    }
                  ]
                }
                    sendToApiAi(sender,apirespone);

function sendToApiAi(sender, text) {

    sendTypingOn(sender);
    let apiaiRequest = apiAiService.textRequest(text, {
        sessionId: sessionIds.get(sender)
    });

    apiaiRequest.on('response', (response) => {
        if (isDefined(response.result)) {
            handleApiAiResponse(sender, response);
        }
    });



    apiaiRequest.on('error', (error) => console.error(error));
    apiaiRequest.end();
}

person Karthik Venkatesh    schedule 05.04.2018    source источник
comment
Я немного опоздал, но вы также можете сохранить его в своем приложении веб-перехватчика, в объекте app.data. Он делает то же самое, что и контекст Dialogflow.   -  person Rémi C.    schedule 12.04.2018


Ответы (1)


Хороший звонок! Вам определенно нельзя сохранять его в глобальной переменной.

К счастью, Dialogflow предлагает для этого хорошее решение.

В своем веб-перехватчике вы можете сохранить идентификатор пользователя и любую другую информацию о сеансе как часть параметра Context. . Вы можете установить это как исходящий контекст в своем коде выполнения с длительным сроком действия и/или повторно сохранять этот контекст каждый раз, когда вызывается ваш веб-перехватчик. Вы не предоставляете ничего о коде, который в настоящее время используете в своем веб-перехватчике, но вы можете увидеть документацию о том, как Context может быть частью вашего ответ JSON или с помощью библиотек.

Чтобы было ясно, вы можете вернуть контекст как часть JSON в ответе. Вам не нужно делать вызов REST, чтобы установить его. Контексты живут столько же, сколько их время жизни, поэтому, как только вы их установили, они будут жить для вызовов «пожизненно» во время сеанса, или вы можете устанавливать новые (или обновлять их время жизни) каждый раз как часть JSON, который вы возвращаете.

При следующем вызове вам будут переданы все контексты, которые в настоящее время действительны. Вы можете найти тот, который хранит состояние, которое вы ранее сохранили, и получить значения из параметров.

Обновите, чтобы ответить на ваш код

Вам не нужен вызов REST, который вы делаете.

Вы можете вернуть и обновить контекст в своем JSON. Вы этого не показываете, но я предполагаю, что вы создаете ответ, и добавление контекста может выглядеть примерно так:

{
  "displayText": "Show something",
  "contextOut":[
    "name": "logindetails",
    "lifespan": 25,
    "parameters": {
      "loggedIn": "true"
    }
  ]
}

На более позднем этапе беседы вы можете повторно отправить это в своем ответе, чтобы обновить информацию. Вы можете сделать это следующим образом:

В вашем цикле, где вы получаете информацию, вы можете сохранить весь контекст:

        var logindetails;
        if (contexts[i].name == "logindetails") {
            logindetails = contexts[i];
            if (logindetails.parameters.loggedIn == "true") {
                //set this true if found.
                loggedIn = true;
            }
        }

Затем вы можете изменить все, что хотите, в logindetails, и когда вы создаете ответ, сделайте что-то вроде этого:

{
  "displayText": "Show something",
  "contextOut":[
    loginDetails
  ]
}
person Prisoner    schedule 05.04.2018
comment
Спасибо, что ответили. Скажем, например, я загрузил пользовательские данные из базы данных firebase и хочу сохранить эту информацию где-нибудь вместо того, чтобы снова и снова вызывать базу данных. Когда я попытался сохранить это в глобальной переменной, информация распространяется среди всех пользователей, которые обращаются к боту, чего я не хочу. Как я могу этого добиться? - person Karthik Venkatesh; 06.04.2018
comment
Есть ли способ редактировать параметры контекста через веб-перехватчик, а также как избежать сброса параметров при срабатывании намерения? Пожалуйста, дайте мне знать. - person Karthik Venkatesh; 06.04.2018
comment
Я обновил свой ответ, но не могу больше помочь в специфике, поскольку вы не предоставили много деталей (например, код). Я не уверен, что вы подразумеваете под избеганием сброса параметров. - person Prisoner; 06.04.2018
comment
Спасибо. Это очень помогло. Все, что я пытался сделать, это сохранить информацию о пользователе после входа в систему и сохранить состояние входа в систему как истинное во время сеансов. Я использовал пост-запрос /contexts, чтобы опубликовать новый контекст с параметрами информации о пользователе после входа в систему. Пожалуйста, дайте мне знать, есть ли другой лучший способ сделать это. В настоящее время диалоговый поток позволяет только публиковать, получать и удалять запросы, но не может обновляться между разговорами. - person Karthik Venkatesh; 06.04.2018
comment
ОЙ! Вам не нужно использовать конечную точку /context REST. Ответ обновлен, чтобы уточнить. (Вот почему я говорил, что наблюдение за тем, как вы сделали свой код, поможет.) - person Prisoner; 06.04.2018
comment
Я добавил код к вопросу. Я выполняю этот код, когда срабатывает намерение входа в систему. Я проверяю, присутствует ли контекст logindetails. Если нет, я завершаю процесс входа в систему и отправляю в него данные для входа с параметрами. Если да, я продолжаю с другими вариантами. Теперь, если я хочу изменить значения параметров в контексте logindetails, я должен удалить контекст и отправить его обратно, поскольку конечная точка /context не предоставляет параметр обновления. Вы упомянули об отправке контекстов/параметров JSON из веб-перехватчика. Не могли бы вы рассказать мне, как этого добиться? - person Karthik Venkatesh; 07.04.2018
comment
Можно ли редактировать/обновлять параметры исходящих контекстов? Если это так, пожалуйста, дайте мне знать, как этого добиться? - person Karthik Venkatesh; 07.04.2018
comment
Еще раз спасибо за обновление. Я не устанавливаю какой-либо выходной контекст в диалоговом потоке. Вместо этого я публикую новый контекст с информацией для входа после входа пользователя в систему. Теперь, если я хочу обновить параметры в созданном мной контексте, как мне это сделать? - person Karthik Venkatesh; 07.04.2018
comment
Пожалуйста, проверьте Отправка обновлений контекстов в диалоговый поток: раздел вопроса. Это правильный способ отправки контекстов в диалоговый поток? Я получаю сообщение о том, что свойство запроса запроса Json недопустимо с кодом 400. Пожалуйста, помогите. - person Karthik Venkatesh; 07.04.2018
comment
Если вы решили проблему, публикация другого ответа с объяснением того, что вы сделали, может помочь другим с той же проблемой. - person Prisoner; 07.04.2018