【问题标题】:Smooch: How to do postback dependent state transition?Smooch:如何进行回发依赖状态转换?
【发布时间】:2016-07-25 02:37:39
【问题描述】:

我正在尝试根据 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)

到github.com/smooch/smooch-bot-example/blob/master/heroku/index.js的handlePostback方法

但是,这引发了错误代码 H12。我也尝试过

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

无济于事。

【问题讨论】:

    标签: javascript chatbot smooch


    【解决方案1】:

    我在 [object Object] 而不是字符串时遇到了同样的问题。这是因为您使用函数获取或设置的 state 包含在对象中,而不是字符串中...我在 index.js 中使用此代码修复了它,替换了 smooch-bot-example GitHub 中现有的 handlePostback 函数回购:

    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;
    

    注意,如果你想要的结果相同,则不要在每个case的末尾写break;(这里:设置状态并提示相应的消息)。

    如果您想以不同的方式处理其他回发,您可以在break; 语句之后添加案例并执行其他操作。

    希望这会有所帮助!

    【讨论】:

    • 这非常有用。谢谢。这比我的 hack 好多了。
    • 没问题!一开始有点令人不安,但我只是从 handleMessage 函数中获得灵感来解决这个对象与字符串的问题......如果你认为它有用,请点赞 ;-)
    • 我已将正确答案记入我的回购协议中,该回购协议实现了这个Working github repo
    • 手感不错,欣赏。
    • @sera 你测试过我给你的答案了吗?我的似乎没有在 FB Messenger 上工作,并且有时在网络聊天版本上仍然存在错误,仍然在某些对话的日志中抛出 [object Object] 错误......
    【解决方案2】:

    回发不会自动将您的对话从一种状态转换到另一种状态,您必须自己编写该逻辑。幸运的是,您使用的 smooch-bot-example 已经在这里定义了一个回发处理程序:

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

    所以无论你想要什么转换逻辑都应该放在那里。您可以通过创建 stateMachine 并在其上调用 receiveMessage() 来做到这一点,方法与 handleMessages() already works 相同。例如:

    const stateMachine = new StateMachine({
        script,
        bot: createBot(req.body.appUser)
    });
    
    stateMachine.receiveMessage({
        text: 'whatever your script expects'
    })
    

    或者,如果您想让您的回发行为不同于常规文本响应,您可以让您的 handlePostback 实现独立调用 stateMachine.setState(state)stateMachine.prompt(state)

    【讨论】:

    【解决方案3】:

    如果您想基于回发推进对话,您必须首先从机器人的提示中输出按钮(以便您可以处理接收中的按钮单击),修改 index.js 中的 handlePostback 函数,然后在您的接收方法中处理用户的“回复” - 试试这个 - 像这样修改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'
    },
    

    然后修改index.js 中的handlePostback 函数,使其将回发视为普通消息:

    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 并像回复一样处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-16
      • 2018-01-08
      相关资源
      最近更新 更多