响应松弛对话后更新机器人消息

时间:2017-10-08 10:00:30

标签: node.js slack botkit

我在回复松弛对话框后更新交互式消息时遇到了一些问题。我在node.js服务器上使用botkit。

这是我的工作流程:

  1. 用户通过斜杠命令触发交互式消息
  2. 用户点击该消息上的按钮
  3. 弹出一个对话框,用户填写表单并验证
  4. 在服务器端完成了一些事情
  5. 第一条消息应该更新
  6. 现在,这是我使用的逻辑:

    1. 用户通过斜杠命令触发交互式消息
    2. 没什么好看的,我用的是:

      controller.on('slash_command', function (bot, message)
      

      然后我解析命令,并使用适当的附件(按钮)发送相应的消息

      1. 用户点击该邮件的按钮
      2. 同样,我使用botkit发送的事件:

        controller.on('interactive_message_callback', function (bot, message)
        

        然后我创建一个对话框:

        var dialog = bot.createDialog(
                                'Which book?',
                                JSON.stringify(callback),
                                'Ok'
                            )
        

        在这里,我做了一些非常(非常)肮脏的事情,不应该这样做。但这是我在对话框填满后发现更新初始消息的唯一方法。 callback_id实际上包含一个对象,其中包含初始消息的response_url(以及用于标识表单的内容)。

        1. 弹出一个对话框,用户填写表单并验证
        2. 在服务器端完成了一些事情
        3. 在这里,我再次使用botkit提供的事件:

          controller.on('dialog_submission', function (bot, message)
          

          然后我解析message.submission.callback_id并检测response_url。有了这个,我可以创建一个我称之为originalMessage的对象。

          1. 第一条消息应该更新
          2. 目前我使用:

            bot.replyInteractive(originalMessage, 'DONE, everything is saved.');
            

            originalMessage包含第一封邮件的response_url确实有效。第一条消息正被新消息取代。

            但是我对这个解决方案真的不满意,并且想知道我是否遗漏了某些地方。我见过几个应用程序都有这种类型的工作流程,所以必须有办法。

            感谢您的帮助:)

2 个答案:

答案 0 :(得分:1)

我写信给Slack询问这种情况,并得到了Mark P的很好建议:

使用state对话框字段将原始response_url传递到对话框。然后,当您收到对话框数据时,可以使用state代替response_url

我刚刚尝试过,效果很好。无需在您自己的服务器上存储任何状态。

我不知道如何使用Node和botkit,因为那不是我用的。

再充实一点:

  1. 有人单击一个按钮,并将有关该交互的Slack POST发送到您配置的“请求URL”。
  2. 从Slack的有效负载中获取“ response_url”值。
  3. 当您在Slack API中调用dialog.open时,请将此response_url传递为“状态”值。
  4. 提交对话框后,Slack再次将其发布到您的“请求URL”。
  5. 从Slack的有效负载中获取“状态”值,并将其用作response_url。
  6. 利润!

答案 1 :(得分:0)

仅当您将原始消息对象保存在服务器上的某个地方以备将来参考时,此方法才有效。

因此,在创建交互式对话框时,将其存储在某个地方并添加引用。我使用uuid。

    let newId = uuid();
    messageStore[newId] = message;
    var dialog = bot.createDialog(
        'My Dialog',
        'idPrefix_' + newId,
        'Submit'
    ).addText('Sample Input', 'input', '');
    bot.replyWithDialog(message, dialog.asObject());

然后,一旦获得交互式对话框响应,请反汇编前缀和uuid,并从服务器内存中恢复原始消息对象。然后在那里使用“ replayInteractive”。

controller.on('dialog_submission', function handler(bot, message) {
    if (message.callback_id.indexOf('idPrefix') === 0) {
       let id = message.callback_id.substr('idPrefix_'.length);
       bot.dialogOk();
       let originalMessage = messageStore[id];
       bot.replyInteractive(originalMessage, {
            text: 'replacing the original message with this.'
       });
    }
});

请注意,不要在此处造成内存泄漏。您必须找到一种方法来逐步清理messageStore