Smooch: Как сделать постбэк-зависимый переход состояния?

Я пытаюсь перевести сценарий из одного состояния в другое на основе обратной загрузки Smooch; но получаю код ошибки H12.

Рассмотрим примерhttps://github.com/smooch/smooch-bot-example

Скажи, что я модифицирую скриптhttps://github.com/smooch/smooch-bot-example/blob/master/script.js следующее

start: {
    receive: (bot) => {
        return bot.say('Hi! I\'m Smooch Bot! Continue? %[Yes](postback:askName) %[No](postback:bye) );
    }
},
bye: {
    prompt: (bot) => bot.say('Pleasure meeting you'),
    receive: () => 'processing'
},

Предполагается, что состояние бота будет меняться в зависимости от полезной нагрузки обратной передачи.

Вопрос в том, как мне это сделать?

Мой подход был добавлен

stateMachine.setState(postback.action.payload)

в метод handlePostback из github.com/smooch/smooch-bot-example/blob/master/heroku/index.js

Однако это бросило код ошибки H12. Я также экспериментировал с

stateMachine.transition(postback.action,postback.action.payload)

но безрезультатно.

Ответы на вопрос(3)

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

https://github.com/smooch/smooch-bot-example/blob/30d2fc6/heroku/index.js#L115

Так что любая логика перехода, которую вы хотите, должна идти туда. Вы можете сделать это, создав stateMachine и вызвавreceiveMessage() на нем так же, как handleMessages ()уже работает, Например:

const stateMachine = new StateMachine({
    script,
    bot: createBot(req.body.appUser)
});

stateMachine.receiveMessage({
    text: 'whatever your script expects'
})

Кроме того, вы могли бы иметьhandlePostback вызов реализацииstateMachine.setState(state) а такжеstateMachine.prompt(state) независимо, если вы хотите, чтобы ваши постбэки вели себя не так, как обычные текстовые ответы.

 sera25 июл. 2016 г., 21:10
Спасибо вам за помощь. Позвольте мне понять это. Я добавил дополнительное состояние; но отсутствие состояний «да» или «нет» не имеет ничего общего с быстрым повторением и не ожиданием сообщения. Например, даже если вы выбрали «Нет» в первой обратной передаче, возникает аналогичная ошибка.
 Andrew Lavers25 июл. 2016 г., 19:27
Похоже, вы обрабатываете ответы обратной передачи, как если бы они были пользовательскими сообщениями, говорящими «да» или «нет», но в вашем script.js нет ничего, что обрабатывает эти ответы.
 sera25 июл. 2016 г., 20:29
Большое спасибо.stateMachine.setState (postback.action.payload) привело к ошибке неопределенного состояния [объект].stateMachine.prompt (postback.action.payload) приводит к переходам состояний. Однако, если вы попробуетеpostback-example1.herokuapp.comвы увидите, что состояние askName продолжает повторять запрос, не ожидая сообщения.
 Andrew Lavers25 июл. 2016 г., 19:31
Обратите внимание, что имя состояния в вашем script.js ("start", "bye", "askName" ..) не имеет ничего общего с ответом пользователя. Вы должны сами обработать сообщения или события обратной передачи и определить, как должно переходить состояние. Например, обработчик askName может перейти к финишу, разрешив строку «финиш» здесь:github.com/nbikar/smooch-bot-example/blob/master/script.js#L35 Вы также можете использовать stateMachine.setState, как я предложил в своем ответе.
 sera25 июл. 2016 г., 19:04
Спасибо за ответ. Как я уже упоминал в своем ОП, я ожидал, что это сработает. Не уверен, почему это не так. Я раздвоил пример смуч-ботаgithub.com/nbikar/smooch-bot-example и развернул егоpostback-example1.herokuapp.com , Бот не делает переходы между состояниями. Я сделал два измененияgithub.com/nbikar/smooch-bot-example/blob/master/script.js#L18 , github.com/nbikar/smooch-bot-example/blob/master/heroku/... , Заранее большое спасибо.
 Andrew Lavers25 июл. 2016 г., 20:32
Конечно, потому что вы не определили ни одно состояние с именем «да» или «нет». Комментарии переполнения стека - неподходящее место для отладки такого рода вещей, я остановлюсь здесь. Я уверен, что вы можете понять это самостоятельно.

вам сначала нужно будет вывести кнопки из подсказки бота (чтобы вы могли обрабатывать нажатие кнопок в приемнике), изменитеhandlePostback функция вindex.js, затем обработайте "ответ" пользователя в вашем методе получения - попробуйте это - изменитеscript.js вот так:

start: {
    prompt: (bot) => bot.say(`Hi! I'm Smooch Bot! Continue? %[Yes](postback:askName) %[No](postback:bye)`),
    receive: (bot, message) => {

      switch(message.text) {
        case 'Yes':
          return bot.say(`Ok, great!`)
            .then(() => 'hi')
          break;
        case 'No':
          return bot.say(`Ok, no prob!`)
            .then(() => 'bye')
          break;
        default:
          return bot.say(`hmm...`)
            .then(() => 'processing')
          break;          
      }
    }
},

hi: {
    prompt: (bot) => bot.say('Pleasure meeting you'),
    receive: () => 'processing'
},

bye: {
    prompt: (bot) => bot.say('Pleasure meeting you'),
    receive: () => 'processing'
},

Затем изменитеhandlePostback функция вindex.js так что он обрабатывает обратную передачу как обычное сообщение:

function handlePostback(req, res) {

    const postback = req.body.postbacks[0];

    if (!postback || !postback.action)
        res.end();

    const stateMachine = new StateMachine({
        script,
        bot: createBot(req.body.appUser)
    });

    const msg = postback;

    // if you want the payload instead just do msg.action.paylod
    msg.text = msg.action.text;

    stateMachine.receiveMessage(msg)
      .then(() => res.end())
      .catch((err) => {
        console.error('SmoochBot error:', err);
        res.end();
      });
}

Теперь, когда пользователь нажимает вашу кнопку, она будет перемещена в stateMachine и обработана как ответ.

чтоstate Вы получаете или устанавливаете с помощью функции, которая содержится в объекте, а не в строке ... Я исправил это с помощью этого кода внутриindex.js, заменяя существующиеhandlePostback функция вобниматься-личинка-пример GitHub репо:

function handlePostback(req, res) {

const stateMachine = new StateMachine({
    script,
    bot: createBot(req.body.appUser)
});

const postback = req.body.postbacks[0];
if (!postback || !postback.action) {
    res.end();
};

const smoochPayload = postback.action.payload;

// Change conversation state according to postback clicked
switch (smoochPayload) {
    case "POSTBACK-PAYLOAD":
        Promise.all([
            stateMachine.bot.releaseLock(),
            stateMachine.setState(smoochPayload), // set new state
            stateMachine.prompt(smoochPayload) // call state prompt() if any
        ]);
        res.end();
    break;

    default:
        stateMachine.bot.say("POSTBACK ISN'T RECOGNIZED") // for testing purposes
            .then(() => res.end());
};
}

Тогда внутриscript.js все, что вам нужно сделать, это определить состояния, соответствующие точным данным обратной передачи. Если у вас есть несколько обратных передач, которые должны перевести пользователя в другие состояния, просто добавьте их вcase список вроде так:

case "POSTBACK-PAYLOAD-1":
case "POSTBACK-PAYLOAD-2":
case "POSTBACK-PAYLOAD-3":
case "POSTBACK-PAYLOAD-4":
Promise.all([
        stateMachine.bot.releaseLock(),
        stateMachine.setState(smoochPayload), // set new state
        stateMachine.prompt(smoochPayload) // call state prompt() if any
    ]);
    res.end();
break;

Обратите внимание, что вы не должны писатьbreak; в конце каждогоcase если желаемый результат совпадает (здесь: установка состояния и запрос соответствующего сообщения).

Если вы хотите обрабатывать другие постбэки по-другому, вы можете добавить случаи послеbreak; заявление и делать другие вещи вместо этого.

Надеюсь это поможет!

 sera28 июл. 2016 г., 22:54
Да. Мой бот живет вm.me/waylobot, Это все еще бросает ошибку время от времени все же. Я перехожу на нативный бот FB Messenger, поэтому не трачу много времени на отладку Smooch.
 sera27 июл. 2016 г., 19:25
Я зачислил правильный ответ вам на мой репо, который реализует этоРабочий репозиторий github
 dstoiko27 июл. 2016 г., 19:24
Нет проблем! Сначала это немного нервирует, но я просто черпал вдохновение изhandleMessage функция для решения этого объекта против строковой проблемы ... Пожалуйста, подтвердите, если вы считаете, что это полезно ;-)
 sera27 июл. 2016 г., 19:01
Это супер полезно. Благодарю. Это намного лучше, чем мой хак.
 dstoiko27 июл. 2016 г., 19:45
Приятное прикосновение, ценю это.
 dstoiko28 июл. 2016 г., 16:28
@sera Ты проверил ответ, который я тебе дал? Похоже, что у меня не работает FB Messenger, но иногда он все еще глючит в версии веб-чата, все еще выбрасывая[object Object] ошибка в логах некоторых разговоров ...
 dstoiko29 июл. 2016 г., 11:23
Я также попробовал несколько вещей с родными ботами FB. Хотел бы поговорить об этом. Какой лучший способ связаться?

Ваш ответ на вопрос