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

Update a bot message after responding to a slack dialog

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

这是我的工作流程:

  1. 用户通过斜杠命令触发交互式消息
  2. 用户单击该消息上的按钮
  3. 弹出对话框,用户填写表格并验证
  4. 在服务器端做了一些事情
  5. 第一条消息应该更新

现在,这是我使用的逻辑:

  1. 用户通过斜杠命令触发交互消息

没什么特别的,我用:

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

然后我解析命令,并发送带有适当附件(按钮)的适当消息

  1. 用户单击该消息上的按钮

同上,我用的是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. 服务器端做了一些事情

这里我再次使用botkit提供的事件:

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

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

的对象
  1. 第一条消息应该更新

目前我使用:

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

originalMessage 包含第一条消息的 response_url确实有效。第一条消息正在被新消息替换。

但我对这个解决方案真的不满意,想知道我是否遗漏了什么地方。我见过几个具有这种工作流程的应用程序,所以一定有办法。

感谢您的帮助:)

这仅在您将原始消息对象保存在服务器上的某个位置以供将来参考时才有效。

所以在创建交互式对话框时将其存储在某处并添加引用。我用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

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

使用 state 对话框字段将原始 response_url 传递给对话框。然后当你收到对话数据时,你可以使用 state 而不是 response_url.

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

我不知道它如何与 Node 和 botkit 一起工作,因为那不是我使用的。

为了充实一点:

  1. 有人点击一个按钮,Slack 将关于该交互的帖子发送到您配置的 "Request URL"。
  2. 从 Slack 的负载中,获取 "response_url" 值。
  3. 当您在 Slack API 中调用 dialog.open 时,将此 response_url 作为 "state" 值传递。
  4. 提交对话框后,Slack 再次 POST 到您的 "Request URL"。
  5. 从 Slack 的负载中,获取 "state" 值并将其用作 response_url。
  6. 盈利!