Thread IDs
The zoom thread format, how a channel is told apart from a DM, and exactly when decoding fails.
Every thread the adapter hands you carries the Zoom conversation it came from, written into the ID:
zoom:{channelId}:{messageId}
channelId is a Zoom JID. messageId is the event timestamp for a
bot_notification, the mention’s message UUID for a top-level
team_chat.app_mention, or reply_main_message_id when the mention is inside a
thread. team_chat.app_mention sends a bare channel ID, so the adapter appends
@conference.xmpp.zoom.us before building the thread ID.
Decode a thread ID
Channel — the JID ends in @conference.xmpp.zoom.us
{
"channelId": "abc123@conference.xmpp.zoom.us",
"messageId": "20230814T120000Z-ab12cd34"
}Channel or direct message
The JID suffix is the only signal the adapter has, and it is enough:
| JID ends in | Treated as |
|---|---|
@conference.xmpp.zoom.us |
A channel |
| anything else | A direct message |
adapter.isDM(threadId) answers the same question for you.
Decoding
decodeThreadId(threadId) returns { channelId, messageId }.
zoom:abc@conference.xmpp.zoom.us:1750000000000→ both parts, as written.zoom:abc@conference.xmpp.zoom.us→messageIdis"". This is a channel-level ID, which is what you post a brand new message to.zoom::1750000000000→ throws aValidationError: the channel ID is empty.slack:C123→ throws aValidationError: the ID does not start withzoom:.
zoom: on its own does not throw — with nothing after the prefix there is no
second colon to split on, so it decodes to an empty channel ID and an empty
message ID. The Zoom API call made with it is what will fail.