Skip to content

feat(slack): Add a fake Slack workspace for the devserver - #130455

Draft
trevor-e wants to merge 12 commits into
masterfrom
telkins/fake-slack-devserver
Draft

trevor-e wants to merge 12 commits into
masterfrom
telkins/fake-slack-devserver

Conversation

@trevor-e

@trevor-e trevor-e commented Nov 9, 2026 •

Copy link
Copy Markdown
Member

Testing Slack notifications locally needs a real Slack app and workspace. With SENTRY_USE_FAKE_SLACK = True in your Sentry config, the devserver now starts a fake Slack Web API on port 8099 and sends Sentry's Slack API calls to it. Everything Sentry posts shows up in a Slack-like viewer at http://localhost:8099, and sentry django fake_slack_setup connects an organization to the fake workspace.

Production behavior is unchanged. SlackSdkClient and the install-time WebClient now pass a new SENTRY_SLACK_API_BASE_URL setting as base_url. It stays empty, so they keep using https://slack.com/api/, unless SENTRY_USE_FAKE_SLACK is on, in which case initialize_app points it at the fake. That way shells and taskworkers are redirected too, not just devserver processes. The server and viewer live in fixtures/integrations/fake_slack/, which both the SaaS and self-hosted images strip, so only the settings, the devserver hook and the setup command ship. The fake only records what Sentry sends: it validates nothing and doesn't send button clicks, @mentions or modal submissions back to Sentry yet. The viewer says so: clicking a button or menu shows a notice, and a banner lists any Slack methods Sentry called that Fake Slack doesn't simulate.

Issue alerts built by Sentry's real Slack message builder, as they appear in the viewer:

Fake Slack, #alerts channel

Opening a thread shows the repeat alert Sentry posted as a reply:

Fake Slack, issue alert thread

When Sentry calls Slack methods that Fake Slack doesn't simulate, the banner lists them and links to the related message:

Fake Slack, unsupported-call banner

Testing Slack notifications locally needs a real Slack app and workspace. With
SENTRY_USE_FAKE_SLACK on, the devserver starts a fake Slack Web API on port 8099 and
sends Sentry's Slack API calls to it. Messages show up in a Slack-like viewer at
http://localhost:8099. Run `sentry django fake_slack_setup` once to connect an
organization to the fake workspace.

Production behavior is unchanged. The new SENTRY_SLACK_API_BASE_URL setting stays empty
unless the flag is on, and while it's empty the Slack client uses https://slack.com/api/.

The fake only records what Sentry sends. It validates nothing, and it doesn't send
interactions such as button clicks back to Sentry yet.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Sentry checks a channel exists by scheduling a message and deleting it. Fake Slack
posted scheduled messages as visible ones and ignored the delete, so every channel check
left a message in the viewer. Scheduled messages are now kept apart and removed on delete.
Trim comments, fold the request handler factory into make_server, and merge the
unsimulated-method check into the existing flow test.
The viewer decoded & before < and >, so a literal "<" in a message rendered
as "<". Decode in the right order, and pull markdown links out before escaping instead of
partially unescaping their URLs.
@mchen-sentry mchen-sentry added the Trigger: getsentry tests Once code is reviewed: apply label to PR to trigger getsentry tests label Nov 9, 2026
A button's style went into its class attribute unescaped, so a crafted message could inject
markup into the viewer. Escape it, along with message timestamps and channel IDs.
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Nov 9, 2026
Clicking a button or menu in the viewer now explains that Fake Slack doesn't support it,
instead of doing nothing. Slack methods Sentry calls that Fake Slack doesn't simulate are
recorded and listed in a viewer banner, linked to the related message when there is one.
The setup command always printed http://localhost:8099, which is wrong on a remote dev box.
It now uses $FAKE_SLACK_PUBLIC_URL when set, the same default the server uses for links.
Nothing in Sentry follows Fake Slack's message links, so FAKE_SLACK_PUBLIC_URL only changed
the setup command's hint. Remove it and --public-url, and have the hint name the port instead.
Both production images ship everything under src/, including testutils, and strip only tests/
and fixtures/. Move Fake Slack's server and viewer to fixtures/integrations/fake_slack/, next to
the other integration mocks, so it stays out of production. The setup command keeps its own copy
of the workspace ID, and its test checks that it matches the server's.
…e-slack-devserver

# Conflicts:
#	src/sentry/runner/commands/devserver.py

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b029538. Configure here.

A thread root showed up in both the channel and the open thread with the same element ID,
so links scrolled to the channel copy. Thread-pane copies now get their own ID, and the
viewer scrolls to that copy when a thread is open.

This branch was successfully deployed

1 active (outdated) deployment
Preview — b029538f Deployed Nov 12, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components Trigger: getsentry tests Once code is reviewed: apply label to PR to trigger getsentry tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants