Skip to main content

Settings — Notifications

Audience: Support · QA · Sales · Engineering · Management · Where in app: Settings → Notifications (/settings/notifications) · Plan availability: All plans (no permission gate on this user screen)

This is the personal Notification Settings screen. It controls a per-user new-visitor notification sound, the user's mobile push preferences (user.push_preferences), and — on the desktop app only — whether the app launches when you sign in to your computer. It is not where the broad set of company event notifications (email transcripts, Slack, missed-call emails, reports email) are configured; those live elsewhere (see How channels relate and the Notifications module).

What it does

  • New Visitor Notification — toggles a sound that plays when a new visitor lands on the website. Saved on the user record (notification_tune).
  • Push preferences — category toggles + quiet hours for mobile push, saved on user.push_preferences (see Push notifications).
  • Launch on startup (desktop only) — toggles whether the Electron desktop app auto-starts at OS login. Saved at the OS level via Electron IPC, not in the database.
  • A collapsible Learn panel explains the feature and tips.

How it works

The view (settings/Notifications.vue) loads the current user and reads user.notification_tune. Each toggle saves immediately (no separate Save button):

New visitor sound

  • Toggling calls PUT /user/<id> with { notification_tune: <bool> }, then updates the app store with the returned user.
  • On failure it reverts the toggle and shows an error.
  • Backend default for notification_tune is true (UserModel).

Launch on startup (desktop)

  • Only rendered when running in the desktop app (isElectron()) and the platform reports support (launchAtLoginSupported).
  • On mount, launch-at-login-get IPC reads the current OS setting.
  • Toggling calls launch-at-login-set IPC; if the platform doesn't support it, the toggle is hidden and an error toast is shown.
  • This is a machine-local OS preference (macOS/Windows) — it is not stored on the user/company record and does not sync across devices.

Configuration & options

SettingScopePersisted toDefaultVisibility
New Visitor Notification (sound)Per useruser.notification_tune via PUT /user/<id>trueAlways
Push category toggles + quiet hoursPer useruser.push_preferences via GET/PUT /user/push-preferences (partial $set merge; the generic PUT /user/<id> clobbers the whole subdoc, which is why the dedicated endpoint exists — declared above /user/:_id)all on; quiet 21→7Always
Launch on startupPer machineOS (Electron app.setLoginItemSettings) via IPCOS-dependentDesktop app only, where supported

Push notifications (FCM)

Server-side push gating is centralized in NotificationHelper.sendNotification (backend/app/helpers/NotificationHelper.js); delivery via FcmService to UserDeviceModel tokens (stale tokens are forgotten on FCM error).

  • Per-user preferencesuser.push_preferences (UserModel): category toggles leads, live_calls, funnel_returns, agent_k, morning_nudge, other (all default true); leads_24_7 (default false) exempts tier-1 lead pushes from quiet hours; quiet_hours_start / quiet_hours_end (hours 0–23, user-local timezone, defaults 21 / 7). The 21/7 defaults must match NotificationHelper._pushDecision's fallbacks — change both together.
  • RulesNotificationHelper.PUSH_RULES maps notification type → { tier, group }: tier 1 always pushes (cap-exempt, quiet-hours gated), tier 2 capped at DAILY_PUSH_CAP = 3/user/day (overflow lands in the in-app feed), tier 3 scheduled digests. Unmapped types default to tier 2, group other. Per-entity collapse: one push per lead/session/contact per 15 min (DEDUP_TTL_SECONDS = 900), regardless of event types.
  • Dispatch endpointPOST /internal/knox/notifications/dispatch (KnoxNotificationsController@dispatch, internalKnoxRoutes.js, x-api-key via the shared apiKeyAuth) lets other services fan out pushes; a caller-supplied dedup_key collapses repeat fires within 15 min via Redis SETNX.
  • Trigger sitesChatController, GoHighLevelController, UserSessionController, DailyBriefEmailJob, AgentKTrickleJob, NoxFunnelInterceptService; ms-communication live-call events arrive via the dispatch endpoint.
  • Testbackend/test/notification-push-gating.spec.js covers the gating matrix. Super-admins have a live tester at /admin/push-test (dry run, skip-dedupe, pipeline trace).

How channels relate

The broader notification system (in-app bell, desktop toast, push/FCM, email, Slack, webhooks) is company-configured and event-driven — it is not controlled from this screen. Per the data model and the Notifications module:

ChannelBacked by
In-appNotification bell/drawer (NotificationModel)
Desktop toastNative OS notification (desktop app)
PushFirebase Cloud Messaging (mobile + desktop)
EmailSMTP via MailService
SlackSlackService to a chosen channel
WebhookOutbound HTTP when enabled and subscribed

Company-level event toggles live on company.notifications.* (e.g. chat_transcript, call, missed_call, reports_email, daily_recap_email, slack_new_visitor, slack_hot_lead) and are managed on the Organization Notifications screen (/settings/organization/notifications, gated by settings.organization), not here.

Company-vs-user precedence

Per the notifications knowledge base, user-level preferences only fire if the company-level toggle allows it — the company toggle is the outer gate, the user preference the inner one. The new-visitor sound (notification_tune) is a personal client-side sound and is independent of the company event toggles. Per-user push gating is fully defined by user.push_preferences + NotificationHelper.PUSH_RULES (see Push notifications).

Behaviors & edge cases

  • Immediate save, optimistic UI: the sound toggle updates instantly and rolls back on API error (with a toast).
  • No permission gate: the route has no permission meta — any signed-in user can set their own sound.
  • Desktop-only startup toggle: hidden entirely in the browser, and also hidden if the OS doesn't support login items.
  • Web vs desktop notification delivery differs (toasts/ringtone/dock count are desktop-only); see the Notifications module for desktop specifics.
  • Don't confuse screens: "Settings → Notifications" (this page) is personal and minimal; "Settings → Organization → Notifications" is the company event configuration.

Plan & limits

Available on all plans with no permission gate on this personal screen. The company event channels it relates to (Slack, email templates, reports email) may depend on integrations being connected and on plan tier — verify with the Notifications module and pricing.

Technical implementation

  • View: frontend/src/views/settings/Notifications.vue
  • Route: name settings-notifications, path /settings/notifications, meta { title: 'Notification Settings' } (no permission) — frontend/src/router/index.js
  • User field: notification_tune (backend/app/models/UserModel.js, default true), updated via PUT /user/<id>
  • Desktop IPC: launch-at-login-get / launch-at-login-set (@/utils/platform → Electron main process)
  • Company-side config (separate screen): frontend/src/views/settings/organization/Notifications.vue, company.notifications.*, delivered by NotificationHelper / MailService / SlackService. See services/backend.