feat(async): Add daily task to archive stale Slack channels#206
Open
rgibert wants to merge 6 commits into
Open
feat(async): Add daily task to archive stale Slack channels#206rgibert wants to merge 6 commits into
rgibert wants to merge 6 commits into
Conversation
Add a django-q2 scheduled task that runs daily to find bot-created Slack channels where the workspace retention policy has deleted all message history. For each stale channel, posts an archival notice and archives the channel. Changes: - Add archive_channel() method and limit param to get_channel_history on SlackService - Add archive_stale_channels task with per-channel error isolation - Self-disables the schedule if Slack client is unavailable - Add is_archived to get_channel_info return dict - Data migration to register the schedule Co-Authored-By: Claude <noreply@anthropic.com> Agent transcript: https://claudescope.sentry.dev/share/SeyXSRtESuCIjsSjmOGgO3MM_MZHcZftkU8Td81uFP8
Three bugs fixed: 1. get_channel_history(limit=1) swallowed exceptions and returned [], which the task treated as "no messages" and archived active channels. Now exceptions propagate and the per-channel handler skips the channel. 2. The archival notice was posted before calling archive_channel. If archiving failed, the notice remained in the channel misleading users. Now the notice timestamp is captured and the message is deleted on failed archive. 3. A failed archive after a successful notice post would permanently prevent future archiving -- the bot's own notice became "history" causing the channel to be skipped on every subsequent run. Fixed by deleting the notice on failure (issue 2 fix). Also adds SlackService.delete_message() wrapping chat_delete. Co-Authored-By: Claude <noreply@anthropic.com> Agent transcript: https://claudescope.sentry.dev/share/Sq3ianFbApEXKqxUP2-TSgUOWGcOaf_XYnSDxYWDsKo
Add a 2-second delay between channels to stay under Slack's Tier 3 rate limit (~50 req/min). Without this, workspaces with >25 incident channels would routinely hit rate limits on every daily run. Also skip archiving when post_message fails (returns None) instead of archiving the channel with no warning to users. Co-Authored-By: Claude <noreply@anthropic.com> Agent transcript: https://claudescope.sentry.dev/share/tRJBNFSwD_KABR2S1OuvR2T7oKVr_Hwgtfk-OUCIRyw
Two issues fixed: 1. If delete_message failed after a failed archive, the bot's own notice remained as the only message in the channel, causing every future run to skip it permanently. Now the history check uses limit=5 and filters out bot messages (by bot_id), so leftover bot notices don't prevent future archival attempts. 2. If archive_channel raised a non-SlackApiError (e.g. ConnectionError), the exception hit the outer handler which never called delete_message. Restructured so the archive attempt has its own try/except that always reaches the notice cleanup on any failure mode. Co-Authored-By: Claude <noreply@anthropic.com> Agent transcript: https://claudescope.sentry.dev/share/niq15OUwbdrxpEKAdaoIszEmbWDRe369PsqC1_qlA9Q
The previous bot_id filter ignored messages from any bot, which could skip messages from other integrations that legitimately indicate channel activity. Now uses auth_test to resolve the bot's own identity and only filters messages matching that specific bot_id. Messages from other bots are treated as real activity. Also adds a cached bot_id property to SlackService backed by auth_test, called once per task run. Co-Authored-By: Claude <noreply@anthropic.com> Agent transcript: https://claudescope.sentry.dev/share/l1u4EK0km7aDME7RkCQJB5vxCzc3c61oPc4oOSn7rws
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 04dfff0. Configure here.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Add a django-q2 scheduled task that runs daily to find bot-created Slack channels where the workspace retention policy has deleted all message history. For each stale channel, posts an archival notice and archives the channel.
The task queries ExternalLink records (type=SLACK) to find channels Firetower created, checks each via conversations_info and conversations_history(limit=1), and archives any channel with zero remaining messages. Per-channel errors are isolated so one failure doesn't abort the run. If the Slack client is unavailable (no bot token), the task disables its own schedule.
SlackService changes: added archive_channel(), a limit parameter to get_channel_history (avoids paginating all messages when we only need to check existence), and is_archived to get_channel_info.
Resolves RELENG-20
Agent transcript: https://claudescope.sentry.dev/share/onjkTdIu9bD3cgBvGExA2meMCtHFG8S8cpHdLO1DEk8