chat.postMessage Retries Without Duplicate Writes
0 reputation · 04 Jan 2021, 14:00 UTC
0 reputation · 04 Jan 2021, 14:00 UTC
A background worker posts notifications to a Slack channel through the Web API and follows Slack's documented retry guidance: exponential backoff on 5xx and network timeouts, honoring Retry-After on 429 responses. The desired behavior is that a retry after an ambiguous failure — the request timed out but the server may have accepted the write — must not produce a second identical message.
Slack's documentation does not describe a universal idempotency key for Web API methods, and support appears to vary by endpoint. The Events API payload includes an event_id field that receivers typically use to deduplicate repeated deliveries, and client_msg_id appears in message-sending contexts such as the RTM API, but whether chat.postMessage accepts any client-supplied identifier the server uses to suppress duplicates is not settled here. This assumes current Web API behavior and should be verified against the method's documentation before implementation.
chat.postMessage honor a client-supplied deduplication identifier, and if so, what scope or time window applies?conversations.history the documented alternative, or does it carry its own consistency caveats?Retry-After retries and timeout retries differ in duplicate-write risk?34775 reputation · 04 Jan 2021, 22:23 UTC
Confirmed fact: Slack’s chat.postMessage Web API does not honor any client‑supplied deduplication identifier (e.g., client_msg_id or a custom field). The only identifiers returned are the server‑generated ts and optional thread_ts. Therefore a retry after a timeout or 5xx error can create a second identical message if the original request was already processed.
When a network timeout occurs, Slack may have already received and stored the message before the client’s timeout fired. Because the API offers no server‑side idempotency, a blind retry will cause a duplicate write. The same risk applies to retries after 5xx responses; 429 Retry-After retries share the risk if the original request succeeded before the rate‑limit response was sent.
chat.postMessage with exponential backoff for 5xx and network timeouts, and honor Retry-After on 429.conversations.history for the target channel, limiting results to the most recent messages (e.g., limit=100).text matches the notification you just attempted to send (or, if you include a unique marker in the text, match that marker). If a matching message is found, treat the original request as successful and skip the retry.chat.postMessage request using the same backoff schedule.Retry-After interval before retrying; the same history check can be applied after the wait if you suspect the original request may have succeeded.To guarantee that conversations.history will still contain the original message, you need to know your workspace’s message retention setting (default 30 days). If retention is shorter than the expected retry window, the history query could miss the message and cause a false‑positive retry. Please confirm the retention period for the channel or workspace before relying on this deduplication method.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.