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

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

这是我的工作流程:

  • 用户通过斜杠命令触发交互式消息

  • 用户单击该消息上的按钮

  • 弹出一个对话框,用户填写表单并进行验证

  • 在服务器端完成了一些事情

  • 第一条消息应该更新

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

  • User trigger an interactive message via a slash command

没什么好看的,我使用:

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

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

  • User click a button on that message

同样,我使用botkit发送的事件:

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

然后我创建一个对话框:

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

在这里,我发现在填充对话框后我发现更新初始消息的唯一方法是'm doing something really (really) dirty, and should not be done. But that' . callback_id 实际上包含一个对象,其中包含初始消息的 response_url (以及用于标识表单的内容) .

  • A dialog pops up, user fill the form and validate

  • Something is done on the server side

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

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

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

  • The first message should update

目前我使用:

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

originalMessage 包含第一条消息的 response_url . It does work . 第一条消息正被新消息取代 .

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

谢谢您的帮助 :)

回答(2)

2 years ago

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

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

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

我不知道它如何与Node和botkit完全兼容,因为那不是我使用的 .

为了充实这一点:

  • 有人点击了一个按钮,Slack POSTs关于该交互与你配置的"Request URL" .

  • 从Slack的有效负载中,获取"response_url"值 .

  • 当您在Slack API中调用dialog.open时,将此response_url作为"state"值传递 .

  • 提交对话框后,Slack再次POST到您的"Request URL" .

  • 从Slack的有效负载中,获取"state"值并将其用作response_url .

  • 利润!

2 years ago

仅当您在服务器上的某个位置保留原始消息对象以供将来参考时,此方法才有效 .

因此,在创建交互式对话框时将其存储在某处并添加引用 . 我用uuids .

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.'
       });
    }
});

Be careful 你没有在这里创建内存泄漏 . 你必须找到一种方法来清理 messageStore 随着时间的推移 .