block_id 什么时候需要更新?

When does a block_id need to be updated?

我正在尝试了解模式中唯一 block_ids 的要求。具体来说,this instruction 在输入块的字段文档中:

block_id should be unique for each message and each iteration of a message. If a message is updated, use a new block_id.

好的,这似乎意味着如果我发送一个 views.update 调用来更新模式以响应某些交互,我需要用一个新的唯一值更新所有 block_ids。这很烦人,尤其是那些相同的 block_ids 是错误响应的键,但无论如何。

除了这似乎与this note in the "using modals" update docs (and identical notes in the views.update docs and the views reference直接矛盾):

Data entered or selected in input blocks can be preserved while updating views. The new view object that you use with views.update should contain the same input blocks and elements with identical block_id and action_id values.

所以我不需要在更新视图时更改block_id?那么第一个注释是什么意思——我什么时候需要一个新的 block_id?还是那里的“消息”有一些特定的意义 - 而不是“视图”或“表面”可能 - 我没有得到?

(我想这里有个子问题是,block_ids的唯一性范围到底是什么?我们已经有了action_ids的区别,只需要在一个视图内是唯一的和 external_ids,这在“团队的所有观点”中必须是唯一的;block_id 是第三类吗?)

注意:此答案基于我构建和 运行安装 Simple Poll Slack 应用程序的经验。我不完全确定 Slack 认可的“最正确”方法是什么,但我对在实践中有效的方法有很好的了解。


这里的简短回答是 block_ids 在大多数情况下不需要是唯一的。我们的大多数 block_ids 都不是独一无二的。例如,我们有一个 modal/view,用户可以在其中设置定期轮询。此块的 block_id 是 set_up_recurring_poll。 block_id 不是唯一的没有问题。

所以这是我们的默认方法:为 block_ids 选择非唯一的、人类可读的名称。正如您所提到的,当 Slack 通过 block_actions/view_submission 有效载荷发送时,这些也是最容易解析的。

实际上,Slack 使用 block_id 作为在 interactive/input 块中维护状态的一种方式。具体来说block_id唯一性是用来决定是update/replace你之前指定的区块用新区块还是保留现有区块。本质上是一种缓存形式。

说的有点抽象,我举两个例子:

  • 更新具有 plain_text_input 方块的表面
  • 正在更新具有 static_select 菜单的界面

更新具有 plain_text_input 方块的表面

  1. 假设您的应用程序打开了一个包含 plain_text_input 块的视图。
  2. 用户在此块中输入内容,例如“Hello World”
  3. 然后用户单击视图中的按钮,您的应用决定使用 views.update 更新视图,但在视图中保留相同的 plain_text_input

如果在对 views.update 的调用中,您的应用保持 block_id 与您的应用在第 1 步中使用的 block_id 相同 ,那么用户输入的“Hello World”仍然存在。

如果在对 views.update 的这次调用中,您的应用使用了与步骤 1 中使用的应用不同的 block_id,则“Hello World”用户输入的内容消失了,用户将看到一个空的输入字段。

所以在这种情况下,如果您的意图是清除 plain_text_input,则使用不同的 block_id。如果您的目的是维护用户输入,则使用相同的 block_id.

更新具有 static_select 菜单的界面

  1. 假设您的应用发布了一条包含 static_select 菜单的消息
  2. 用户选择了 static_select 菜单中的选项之一
  3. 然后您的应用会更新基础消息(使用 chat.update)。之前消息和更新消息之间的唯一变化是您的应用向 static_select 菜单
  4. 添加了另一个选项

在这种情况下,如果包含 static_select 菜单的块在更新的消息中具有 相同的 block_id,则新选项 不会在 static_select 菜单中显示 。 Slack 看到 block_id 和之前一样,决定不更新区块的实际内容。

所以在这种情况下,如果您希望在 static_select 菜单中添加另一个选项,那么您需要 使用新的方块 ID。

当我们 运行 遇到这种情况时,我们倾向于将随机生成的后缀附加到我们现有的、人类可读的块 ID 上。因此,我们不使用 my-static-select-menu,而是使用 my-static-select-menu&5jRMA 作为我们的 block_id。然后稍后当我们解析 block_id 时,我们只查看 &

之前的值

我推荐并且对我们有用的总体方法:

默认使用非唯一的、人类可读的 block_ids。如果你碰巧 运行 遇到这种情况,Slack 正在根据 id 缓存块内容,这会阻止你做某事,然后添加一个在 运行 时间生成的随机后缀到块 ID,这将破坏 Slack 的缓存。

what exactly is the scope of uniqueness for block_ids?

在我的心智模型中,block_ids 只需要在任何给定 block_id 存在的直接相邻块(即 blocks: [] 的数组)的上下文中是唯一的。或者换句话说,对于它们所属的表面实例(消息、视图、应用程序主页),它们需要是唯一的

所以您不能在完全相同的消息、视图或app_home页面中两次使用相同的block_id – 但完全可以例如,使用相同的非唯一块 ID 为消息中的“升级”按钮供电。即使同一条消息被多次发布


最后一个想法:对于此类问题和类似问题,您可能还会发现向开发人员发送便条很有用@slack.com – 他们的客户成功团队中有几个人致力于回答技术问题像这样的问题。他们过去曾帮助过我!