Skip to content

Users get emails#452

Merged
cleptric merged 9 commits into
mainfrom
user-email-api
Jul 14, 2026
Merged

Users get emails#452
cleptric merged 9 commits into
mainfrom
user-email-api

Conversation

@HazAT

@HazAT HazAT commented Jul 10, 2026

Copy link
Copy Markdown
Member

We only know people by Slack ID, which means nothing to any other system. This adds emails to users: synced from Slack (on user creation + the nightly sync, which doubles as the backfill), and exposed in /api/users so you can match potato people to actual people.

Together with #449 you can now pull your potato history into another system and know who's who. 🥔✉️

⚠️ Needs the users:read.email scope added to the Slack app, otherwise Slack keeps emails to itself.

HazAT added 3 commits July 10, 2026 13:13
Add a nullable slack_email column to the users table, plus the
corresponding entity property and email validation rule.

The column is nullable because email is only available from Slack's
users.info API when the app has the users:read.email OAuth scope, and
existing rows need a backfill. Population happens in a follow-up
change to keep the schema migration independently deployable.

slack_email is added to the entity's _hidden list so it does not leak
into the JSON output of existing endpoints that serialize user
entities (leaderboard, user list, profile). Exposing it deliberately
where needed is a follow-up change.
Populate the slack_email column from Slack's users.info response in
both places users are synced:

- UserService::getOrCreateUser() for newly created users
- UpdateUsersCommand (nightly cron) for existing users, which also
  serves as the backfill once the users:read.email OAuth scope is
  granted — no separate backfill command needed

Email falls back to null when Slack doesn't return one (bot users, or
missing users:read.email scope), matching the nullable column.

Note: requires adding the users:read.email scope to the Slack app for
profile.email to be included in users.info responses.
Unhide slack_email specifically in GET /api/users so authenticated
consumers (session or Bearer API token) get a user id to email mapping
in a single call. This lets external systems correlate GibPotato user
ids with people in other tools.

The field stays hidden everywhere else user entities are serialized
(leaderboard, profile, messages containments) via the entity's _hidden
list — the unhide is scoped to this one endpoint.
@HazAT HazAT requested a review from a team as a code owner July 10, 2026 11:14
@HazAT HazAT changed the title Tell external systems who's who Users get emails Jul 10, 2026
@HazAT HazAT changed the base branch from user-email-sync to main July 10, 2026 11:15
HazAT and others added 4 commits July 10, 2026 13:18
Fixes the phpcs violation flagged by php-ci on the arrow function in
UsersController::list().
Comment thread src/Command/UpdateUsersCommand.php Outdated

@cleptric cleptric 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.

Can be merged once the slack app was re-installed, which adds the new required users:read.email scope.

Comment thread src/Model/Entity/User.php
@cleptric cleptric merged commit bf2a0d2 into main Jul 14, 2026
17 checks passed
@cleptric cleptric deleted the user-email-api branch July 14, 2026 21:30
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