Skip to content

[slack] [bug] resolve structured streaming team context from interactive payloads#330

Open
mdnanocom wants to merge 1 commit intovercel:mainfrom
mdnanocom:slackfixrerivingrecipientteamidfromactionpayload
Open

[slack] [bug] resolve structured streaming team context from interactive payloads#330
mdnanocom wants to merge 1 commit intovercel:mainfrom
mdnanocom:slackfixrerivingrecipientteamidfromactionpayload

Conversation

@mdnanocom
Copy link
Copy Markdown

Fix Slack structured streaming when thread.post(stream) is called from an action-created thread.

Slack structured streaming needs a valid recipientTeamId. This change makes team context derivation more tolerant when building streaming options from currentMessage.raw by supporting:

  • team_id
  • team as a string
  • team.id

That covers both standard Slack message events and interactive block_actions payloads.

Why this fixes the bug

The failure only showed up for action-created threads.

For message-created threads, currentMessage.raw is typically a Slack message event, so the previous logic usually worked:

raw?.team_id ?? raw?.team

For action-created threads, currentMessage.raw is the full block_actions payload. In that payload shape, team is commonly an object instead of a string. That meant the previous logic could derive an object where Slack expects a workspace ID string, which breaks structured streaming.

Payload shape difference

Working path: message event

Slack message event payload example:

{
  "type": "event_callback",
  "team_id": "TEAM_ID",
  "event": {
    "type": "message",
    "user": "USER_ID",
    "text": "...",
    "team": "TEAM_ID",
    "thread_ts": "1234567890.123456",
    "channel": "CHANNEL_ID"
  },
  "authorizations": [
    {
      "team_id": "TEAM_ID"
    }
  ]
}

The raw message shape that matters to stream context effectively looks like:

{
  "type": "message",
  "user": "USER_ID",
  "team": "TEAM_ID",
  "thread_ts": "1234567890.123456",
  "channel": "CHANNEL_ID"
}

In this case, the previous derivation still returned a string team ID.

Failing path: block_actions

On the failing path, currentMessage.raw is the full block_actions payload, and team is an object:

{
  "type": "block_actions",
  "user": {
    "id": "USER_ID",
    "team_id": "TEAM_ID"
  },
  "container": {
    "message_ts": "1234567890.123456",
    "channel_id": "CHANNEL_ID",
    "thread_ts": "1234567890.123456"
  },
  "team": {
    "id": "TEAM_ID",
    "domain": "workspace-domain"
  },
  "channel": {
    "id": "CHANNEL_ID"
  },
  "message": {
    "type": "message",
    "team": "TEAM_ID",
    "thread_ts": "1234567890.123456"
  },
  "actions": [
    {
      "action_id": "action-id",
      "value": "action-value"
    }
  ]
}

The important mismatch is:

{
  "user": { "team_id": "TEAM_ID" },
  "team": { "id": "TEAM_ID", "domain": "..." },
  "message": { "team": "TEAM_ID" }
}

With the previous logic:

raw?.team_id ?? raw?.team

recipientTeamId could become:

raw.team
// => { id: "TEAM_ID", domain: "..." }

instead of "TEAM_ID"

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Apr 5, 2026

@mdnanocom is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant