首页 文章

Smooch:如何做回发依赖状态转换?

提问于
浏览
3

我试图基于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)

无济于事 .

3 回答

  • 0

    我在[object Object]而不是字符串中遇到了同样的问题 . 这是因为你使用函数获取或设置的 state 包含在一个对象中,而不是一个字符串......我用 index.js 中的代码修复了它,替换了smooch-bot-example GitHub repo中现有的 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; 语句之后添加案例并改为执行其他操作 .

    希望这可以帮助!

  • 4

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

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

    所以无论你想要什么过渡逻辑都应该进入那里 . 您可以通过创建stateMachine并以与handleMessages()already works相同的方式在其上调用 receiveMessage() 来完成此操作 . 例如:

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

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

  • 1

    如果你想根据回发推进对话'll have to first output the buttons from the bot'的提示(所以你可以在接收中处理按钮点击),修改 index.js 中的 handlePostback 函数,然后在你的接收方法中处理用户的"reply" - 试试这个 - 修改 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并像回复一样处理 .

相关问题