Skip to content

feat(slack, teams): rule channels invite people by email, and admins ask everyone to connect at once - #5195

Merged
simlarsen merged 2 commits into
masterfrom
claude/slack-onboarding-automation-a970fc
Oct 22, 2026
Merged

simlarsen merged 2 commits into
masterfrom
claude/slack-onboarding-automation-a970fc

Conversation

@simlarsen

Copy link
Copy Markdown
Contributor

Why

A customer bringing about 1,000 people into OneUptime asked whether Slack onboarding can be automated, since every user has to connect their own Slack account "for things to work".

An admin still can't connect somebody else's account. Only the person's own sign-in writes that link (WorkspaceUserAuthToken, held by WorkspaceUserAuthTokenWritersGuard), because the link makes the chat account act as that member, with their permissions. This PR makes everything around that sign-in hands-off.

What

Rule-created Slack channels invite people by their email address

  • The channels a notification rule creates (and their later invites: owners, paged on-call people, incident roles) used to invite only people with a connected account. Everyone else was missing from the incident's channel and named in its note.
  • WorkspaceNotificationRuleService.findWorkspaceUserIdsToInvite now tries the connected account first, then the Slack account with the person's OneUptime email address. This is the same lookup Add people on the record's card, paging from chat and on-call user groups already use.
  • The lookup is shared as SlackAccountByEmail, with one cache, so the card and the rules ask Slack once between them.
  • Guests, bots and deactivated accounts found by email are left out. Slack refuses a guest in a channel the app invites to, and that refusal would stop everyone else's invite.
  • The channel's "could not be added" note now names only the people found neither way, and its wording says so.
  • Microsoft Teams adds nobody to channels, and its on-call @mentions already find people by email, so nothing changes there.

"Ask everyone to connect", for Slack and Microsoft Teams

  • There is a new Members' Slack accounts / Members' Microsoft Teams accounts card on Project Settings > Workspace > Slack / Microsoft Teams, for project owners and admins. It shows how many members have connected, and an Ask everyone to connect button.
  • WorkspaceAskToConnect finds every member who has not connected and was not asked in the last 24 hours, by their email address:
    • Slack: users.lookupByEmail for up to 20 people, or users.list pages for more.
    • Teams: the rosters of the teams the app is installed in, matched on email or UPN.
  • The bot messages each one a Connect button that opens the member's own settings with ?connectAccount=true. The link carries no token and never expires, and it connects only the account of whoever signs in with it. The email address only decides whom to message.
  • A thousand messages take minutes inside the rate limits, so the run continues after the request answers. Each project and workspace has one run at a time, under a lock the server keeps extending. Progress is kept in the cache, and the card polls it. If the server dies partway through, the lock runs out, the card says the run stopped, and asking again continues with whoever wasn't asked yet.
  • When Slack is busy, it is retried with a longer wait each time. Messages go out about four a second.
  • Routes: GET/POST /workspace-ask-to-connect/<Slack | MicrosoftTeams>, for signed-in project owners and admins only. An API key is refused, because each message names the person who asked.
  • The Teams user-settings page now acts on ?connectAccount=true as Slack's already did.

Docs

The Slack and Microsoft Teams pages in all 17 languages:

  • a new "Asking everyone to connect" section
  • rule channels inviting by email
  • the troubleshooting entry
  • the data-use note

The new UI strings are extracted into every Dashboard locale as English placeholders, following the stage-2 process in the Locales README.

Tests

New:

  • WorkspaceChannelInviteByEmail.test.ts: both rule invite paths, guest/bot/deactivated, Slack refusals, cache, Teams.
  • WorkspaceAskToConnect.test.ts: Slack one-by-one and paged, rate limit, refusals, the 24-hour skip, lock, stopped runs, Teams rosters, the message's escaping, connect URLs.
  • WorkspaceAskToConnectAPI.test.ts: who may read and ask, workspace validation.
  • WorkspaceAskToConnect.test.ts (types): reading answers back.
  • AskToConnectCard.test.tsx: who sees it, confirm, POST, polling until done, refusal, everyone connected, Teams.

Updated: the channel note's wording in ChannelMembersNotAddedNotice.test.ts and QuietChannelsSlackEndToEnd.test.ts, and the docs translation test's lists.

Run locally:

  • the 37 existing suites that touch the invite and channel code
  • every Common guard suite
  • the App Dashboard guards
  • the docs translation and facts tests
  • the i18n check
  • tsc for Common, App and the Dashboard

Not verified

  • Not run against a real Slack workspace or Teams tenant, or in the running app. The UI is covered by the component test.

…ask everyone to connect at once

A customer bringing about a thousand people into OneUptime asked whether
Slack onboarding can be automated. Only a person's own sign-in connects
their account, and that stays; everything around it no longer waits on it.

- Rule-created Slack channels invite somebody who has not connected Slack
  by the Slack account with their OneUptime email address, as Add people,
  paging from chat and on-call user groups already do (SlackAccountByEmail,
  one cache between them). Guests, bots and deactivated accounts are left
  out; the channel's note names only whoever is found neither way.
- Project owners and admins ask every member who has not connected their
  Slack or Microsoft Teams account at once: a card on the project's Slack
  and Microsoft Teams settings says how many have connected, and one button
  has OneUptime's bot message each of the rest a one-click Connect button
  (WorkspaceAskToConnect, GET/POST /workspace-ask-to-connect/<type>).
  People are found by email: Slack's people, or the rosters of the teams
  the Microsoft Teams app is in. The run goes on after the request
  answers, one per project and workspace under a lock, and skips whoever
  was asked in the last day.
- The Microsoft Teams user settings page connects on ?connectAccount=true,
  as Slack's does.
- The Slack and Microsoft Teams pages say so, in all seventeen languages.
@simlarsen

Copy link
Copy Markdown
Contributor Author

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@simlarsen
simlarsen merged commit 476aa73 into master Oct 22, 2026
15 of 67 checks passed
@simlarsen
simlarsen deleted the claude/slack-onboarding-automation-a970fc branch October 22, 2026 16:05
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.

2 participants