Тело запроса публикации BotFramework не сохраняется в session.userData

Используя запрос POST, я отправляю информацию, отправленную пользователем, в API, который предоставляет информацию, специфичную для пользователя.

Теперь я хочу сохранить информацию, полученную запросом POST, как переменную, которую я могу использовать в других функциях/диалогах.

Я пробовал следующее:

  1. Сохраните тело запроса POST в переменной session.userData.xxx.
  2. Объявил глобальную переменную и использовал ее для хранения тела.
  3. Объявил переменную в почтовом запросе, в котором я сохранил тело

Версия кода, которую я сделал, выглядит следующим образом:

    var body2;

    bot.dialog('FunctionA', [
        function (session) {
            session.sendTyping();
            builder.Prompts.text(session, "Please key-in your App ID:");
    },
    function (session, results) {
        session.userData.AppID= results.response;
         var options = {
      url: 'APIXYZ.COM',
      headers: {
          'Content-Type' : 'application/json'               
            },
         body: JSON.stringify({"appID": session.userData.AppID})

        };

        request.post(options, function(error, response, body) {
          if (!error && response.statusCode == 200) {
            console.info(body); //logs okay
            session.userData.infoA = body;
        console.info(session.userData.infoA) //logs okay
        body2 = body;
            console.info (body2) // logs ok
        var bodyvar = body;
            console.info (bodyvar) //logs ok

          } else {
              console.info("Error: " + error);
              console.info("Status Code: " + response.statusCode);
          }
        });

        var msg = new builder.Message(session)

        .text("The body is:" + session.userData.infoA) //outputs "The body is undefined", if body2,bodyvar -> empty
        .suggestedActions(
            builder.SuggestedActions.create(
                session, [

                    builder.CardAction.imBack(session, "Ok", "Ok")
                    builder.CardAction.imBack(session, "No", "No")

                ]
            ));
    session.send(msg).endDialog();

    }]).triggerAction({ matches: /^ABC/i });

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

Спасибо!

Редактировать:

Я объявил body2 как переменную вне диалогового окна и блока запроса и использовал переменную в том же диалоговом окне сразу после запроса.

var msg = new builder.Message(session)

.text("The body contains: " + body2 + " .") 
        .suggestedActions(
            builder.SuggestedActions.create(
                session, [

                    builder.CardAction.imBack(session, "Ok", "Ok")
                    builder.CardAction.imBack(session, "No", "No")

                ]
            ));

Это выводит The body contains: undefined .

Я также пытался использовать его в другом диалоговом окне:

bot.dialog('Validation', function (session) {
    console.info(body2);
   session.send("The content is : " + body2 +" xx");
    if (body2== "ABC")
    {
        session.sendTyping();
        var msg = new builder.Message(session);
[.......]

Это приводит к подсказке "Oops. Something went wrong and we need to start over"

Вы пытаетесь получить доступ к body2 вне тела запроса? Пока он определен вне его, он должен работать нормально. Я только что проверил что-то очень похожее, и это сработало. Можете ли вы опубликовать весь свой код и указать, где вы хотите снова получить доступ к body2 (или соответствующей переменной)?

mdrichardson 27.02.2019 20:16

... под «определенным» я имел в виду «созданный экземпляр».

mdrichardson 28.02.2019 00:38

@mdrichardson Я обновил вопрос, чтобы учесть мои правки и дополнительный код, спасибо!

Add 28.02.2019 02:54
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
69
1

Ответы 1

Проблема в том, что ваш запрос post не выполняется до того, как вы выполните другие функции. Другими словами, вот что делает ваш код:

  1. Создает post запрос
  2. Выполняет код с неопределенным body2
  3. post запрос завершается, и тогда определяет body2 как body

Вы можете исправить это двумя способами:

Использовать асинхронный режим/ожидание

Это в основном заставляет весь ваш код ждать, пока request.post вернет данные, прежде чем продолжить. Если вы не знакомы, async/await — это более новый способ использования Promises или .then(). Это СУПЕР полезно, особенно при выполнении HTTP-запросов. Вы можете читать больше здесь.

Добавьте async

async function (session, results) {
    session.userData.AppID= results.response;
    var options = {
        url: 'APIXYZ.COM',
...

Добавьте await

await request.post(options, function(error, response, body) {
  if (!error && response.statusCode == 200) {
    console.info(body); //logs okay
    session.userData.infoA = body;

Инкапсулируйте код в функцию запроса

Поскольку request.post будет выполнять код после того, как у него есть error, response и body, вы можете включить любой код, который должен использовать возвращаемые данные, следующим образом:

request.post(options, function(error, response, body) {
    if (!error && response.statusCode == 200) {
        console.info(body); //logs okay
        body2 = body;
        console.info (body2) // logs ok
        var msg = new builder.Message(session)
            .text("The body is:" + body2)
            .suggestedActions(
                builder.SuggestedActions.create(
                    session, [

                        builder.CardAction.imBack(session, "Ok", "Ok"),
                        builder.CardAction.imBack(session, "No", "No")

                    ]
                ));
        session.send(msg).endDialog();
    } else {
        console.info("Error: " + error);
        console.info("Status Code: " + response.statusCode);
    }
});

Я рекомендую идти по маршруту async/await по двум причинам:

  1. Он очень полезен во многих, многих сценариях JavaScript, и его очень полезно знать.
  2. Если вы используете body2 в других диалогах, вам все равно придется использовать его. С помощью описанного выше метода «инкапсуляции» вы все еще можете ожидать ответа, пока запускается другой диалог, который требует body2

При всем при этом похоже, что вы используете V3 Bot Framework. Если это новый бот, я рекомендую создать его в V4 — у него новые функции, и мы его лучше поддерживаем.

Другие вопросы по теме