fix: Slack notification delivery now resolves a real channel (connection config, then the org's configured Slack automation channel) instead of an always-empty connect-time field that silently dropped every message; docs and UI corrected to match

This commit is contained in:
Matthew Meszaros
2026-06-11 12:40:31 +02:00
parent 3c040649c0
commit f209eca9ad
3 changed files with 28 additions and 3 deletions
+1 -1
View File
@@ -78,7 +78,7 @@ The settings page controls where enabled notifications are delivered. The channe
- **In-app**: the bell in the dashboard. Always on, controlled by the per-category toggles above.
- **Email**: delivery to your account email. Turn it on to also receive each enabled notification as an email with a link back into the app.
- **Slack**: posts each enabled notification to your workspace's connected Slack, on the channel you chose when connecting. Connect Slack from the [Integrations](/guides/integrations) tab first; until then the toggle saves but nothing is delivered.
- **Slack**: posts each enabled notification to your connected Slack, on the channel you have configured for Slack in the [Integrations](/guides/integrations) tab. Connect Slack and set up a channel there first; until a Slack channel is configured the toggle saves but nothing is delivered.
For richer, event-specific routing (custom messages, branching, multiple destinations), use [Automations](/guides/automations) instead: they can route events like replies, bookings, and record changes to outside tools with full control.
+26 -1
View File
@@ -1110,6 +1110,31 @@ func buildDisplayFields(provider models.IntegrationProvider, config map[string]a
return df
}
// slackChannelFor resolves the channel to post org notifications to. The
// OAuth connect flow doesn't capture a default channel, so we look (in order)
// at the connection's own config, then reuse whatever channel the org already
// configured for a Slack automation/event subscription. Empty when none.
func (s *service) slackChannelFor(ctx context.Context, orgID uuid.UUID, c models.IntegrationConnection) string {
if ch := configString(c.DisplayFields, "channel"); ch != "" {
return ch
}
if ch := configString(c.ConfigCapabilities, "channel"); ch != "" {
return ch
}
subs, err := s.repo.ListEventSubscriptions(ctx, orgID, c.ID)
if err != nil {
return ""
}
for _, sub := range subs {
if sub.Action == models.IntegrationActionSlackNotify {
if ch := configString(sub.Config, "channel"); ch != "" {
return ch
}
}
}
return ""
}
// NotifySlack posts a one-off message to the org's connected Slack workspace,
// on the default channel chosen at connect time. Used by the notification
// system's Slack delivery channel (distinct from event-subscription actions).
@@ -1123,7 +1148,7 @@ func (s *service) NotifySlack(ctx context.Context, orgID uuid.UUID, title, body
if c.Provider != models.IntegrationSlack || c.Status != models.IntegrationStatusConnected {
continue
}
channel := configString(c.DisplayFields, "channel")
channel := s.slackChannelFor(ctx, orgID, c)
if channel == "" {
continue
}
@@ -117,7 +117,7 @@ export default function NotificationsSettingsPage() {
<Row label="Email" description="Delivery to your account email.">
<Toggle on={channelOn("email")} onChange={(v) => setChannel("email", v)} />
</Row>
<Row label="Slack" description="Posts to your workspace's connected Slack. Connect it in the Integrations tab first.">
<Row label="Slack" description="Posts to your connected Slack, on the channel set up for Slack in the Integrations tab. Connect Slack and configure a channel there first.">
<Toggle on={channelOn("slack")} onChange={(v) => setChannel("slack", v)} />
</Row>
</Section>