Skip to content

slack-welcomer: add workflow-only moderation for #kubernetes-careers#78

Open
Champbreed wants to merge 3 commits into
kubernetes-sigs:mainfrom
Champbreed:feature/career-channel-moderation
Open

slack-welcomer: add workflow-only moderation for #kubernetes-careers#78
Champbreed wants to merge 3 commits into
kubernetes-sigs:mainfrom
Champbreed:feature/career-channel-moderation

Conversation

@Champbreed

Copy link
Copy Markdown

This PR adds message moderation to the slack-welcomer app so it can automatically remove direct posts in #kubernetes-careers and enforce the channel's workflow rules.

Changes

  • main.go: Added support for an admin token (adminToken) alongside the normal bot token so the app has permission to delete messages.
  • handler.go: Fixed JSON parsing to correctly extract the user ID for both team_join and message events, added logic to catch and delete unapproved direct posts while messaging the user, and included a back-off retry loop to handle Slack rate limits gracefully.

/sig contributor-experience
cc: @jberkus @mrbobbytables

@k8s-ci-robot k8s-ci-robot added the sig/contributor-experience Categorizes an issue or PR as relevant to SIG Contributor Experience. label Jun 15, 2026
@k8s-ci-robot k8s-ci-robot requested review from jberkus and jeefy June 15, 2026 00:11
@k8s-ci-robot

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Champbreed
Once this PR has been reviewed and has the lgtm label, please assign bentheelder for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jun 15, 2026

@BenTheElder BenTheElder left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, some first pass comments [keep in mind I haven't worked with the slack API in a while and I have leveraged AI here]

Is it intended that we block thread replies in addition to direct messages?

Comment thread slack-welcomer/handler.go Outdated
)

var guardedChannels = map[string]bool{
"C25QWBR71": true, // #kubernetes-careers

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably be configurable? I think there are other instances of this application (CNCF?)

May also make this testable against another instance.

Comment thread slack-welcomer/handler.go
switch e := err.(type) {
case slack.ErrRateLimit:
log.Printf("Slack is rate limiting us, trying again in %s...\n", e.Wait)
time.Sleep(e.Wait)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should maybe backoff with a maximum timeout. This can hang indefinitely currently (competing calls keep exhausting the rate limit)

Comment thread slack-welcomer/main.go Outdated
if err != nil {
log.Fatalf("Failed to load config from %s: %v", o.configPath, err)
}
adminToken, err := loadAdminToken(o.configPath)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this part of the main config instead of reading in configPath twice?

@BenTheElder

Copy link
Copy Markdown
Member

@kubernetes-sigs/slack-infra-admins

@Champbreed

Copy link
Copy Markdown
Author

Thanks for the review, @BenTheElder. I've updated the code so we only parse the config file once to cut out that double disk read, moved the guarded channels into a dynamic slice so other instances like CNCF can use it and we can test it locally, capped the deletion retry loop at 5 tries so the execution thread doesn't hang indefinitely under heavy rate-limiting, and added fast-failing validation on startup to stop the app from crashing silently later, all while keeping the broadcast-only behavior since blocking direct human thread replies is completely intentional for this workflow-driven channel unless we need to revisit this later. PTAL.

@Champbreed Champbreed requested a review from BenTheElder June 19, 2026 08:34
@BenTheElder

Copy link
Copy Markdown
Member

Sorry I just don't have much time at the moment and I'm going to be out for a bit. Please poke the slack admins chat to see if anyone else can help in the interim.

@BenTheElder

Copy link
Copy Markdown
Member

I think I need to step down from this repo. I'm over extended and this doesn't overlap with the other things I'm doing at all.

@Champbreed

Copy link
Copy Markdown
Author

@BenTheElder Thanks for your review.

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

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. sig/contributor-experience Categorizes an issue or PR as relevant to SIG Contributor Experience. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants