Post docs feedback and integration requests to Slack

Merged
AD
22d ago
+543-121

Problem

Since #6785 moved the docs components into reflex-site-shared, DocsFeedbackState.handle_submit has been a no-op (del form_data). Every "Send feedback" / "Was this helpful?" submission on the docs has been discarded without a toast.

Change

Feedback now posts to Slack through a bot token via chat.postMessage, following how flexgen posts feedback (flexgen/services/slack/_messaging.py).

  • New reflex_site_shared.backend.slack:
    • post_to_slack(text, channel) -> bool sends a bearer-authenticated chat.postMessage with unfurling off. Slack answers rejected posts (bot not in channel, unknown channel, missing token) with HTTP 200, so delivery is read from the ok field.
    • escape_slack_text escapes &, < and > in reader-written text, so a comment like <!channel> can't ping a channel or forge a link.
  • DocsFeedbackState.handle_submit validates the 10–500 character length, posts the contact, page URL, 👍/👎 and comment to SLACK_DOCS_FEEDBACK_CHANNEL, and shows a success or error toast.
  • The docs integration request form uses the same helper and posts to SLACK_INTEGRATION_REQUEST_CHANNEL. I removed the unused duplicate feedback handler in docs/app/.../feedback_state.py. It had posted each submission twice, and its contextlib.suppress(...) and httpx.Client() never suppressed anything.
  • REFLEX_DEV_WEB_GENERAL_FORM_FEEDBACK_WEBHOOK_URL is removed. It had no other users, and reflex-site-shared is an internal package.

Deployment

The internal-docs-backend-secrets Secret on each cluster needs these keys, and the bot must be invited to both channels:

  • SLACK_BOT_TOKEN
  • SLACK_DOCS_FEEDBACK_CHANNEL (a channel ID is preferable to a name)
  • SLACK_INTEGRATION_REQUEST_CHANNEL

The Secret comes from Vault on dev and is applied by hand on staging and prod. Until the keys are set, submissions show the error toast instead of disappearing.

Tests

  • tests/units/reflex_site_shared/test_docs_shell.py covers message content and escaping, the undelivered-post toast, and the length validation. These fail on main.
  • tests/units/reflex_site_shared/backend/test_slack.py covers the request sent, and treats a Slack ok: false, an HTTP 429 and a transport error as undelivered.