3

I'm having some issues to update an interactive message after responding to a slack dialog. I'm using botkit on a node.js server.

Here is my workflow:

  1. User trigger an interactive message via a slash command
  2. User click a button on that message
  3. A dialog pops up, user fill the form and validate
  4. Something is done on the server side
  5. The first message should update

Now, here is the logic I'm using:

  1. User trigger an interactive message via a slash command

Nothing fancy, I use:

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

Then I parse the command, and send the appropriate message, with the appropriate attachments (buttons)

  1. User click a button on that message

Same, I use the event sent by botkit:

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

Then I create a dialog:

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

Here I'm doing something really (really) dirty, and should not be done. But that's the only way I found to update the initial message after the dialog is filled. The callback_id actually contains an object, with the response_urlof the initial message (and something to identify the form).

  1. A dialog pops up, user fill the form and validate
  2. Something is done on the server side

Here, I use once more the event provided by botkit:

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

then I parse the message.submission.callback_id and detect the response_url. With this, I can create an object I call originalMessage.

  1. The first message should update

At the moment I use :

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

with originalMessagecontaining the response_url of the first message. It does work. The first message is being replaced by the new one.

But I'm really not happy with that solution, and was wondering if I was missing something somewhere. I've seen couple apps having that type of workflow, so there must be a way.

Thank you for your help :)

4

2 回答 2

2

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

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

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

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

为了进一步充实这一点:

  1. 有人单击一个按钮,然后 Slack 将有关该交互的信息发布到您配置的“请求 URL”。
  2. 从 Slack 的有效负载中,获取“response_url”值。
  3. 当您在 Slack API 中调用 dialog.open 时,将此 response_url 作为“状态”值传递。
  4. 提交对话框后,Slack 再次 POST 到您的“请求 URL”。
  5. 从 Slack 的有效负载中,获取“状态”值并将其用作 response_url。
  6. 利润!
于 2019-03-22T13:13:05.007 回答
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随着时间的推移。

于 2018-12-23T10:28:45.553 回答