Integrations

Ticket integrations

Connect Momentum to your ticket system for bi-directional sync. Currently shipping: Freshdesk. Zendesk is next on the roadmap (Phase 34).

Connecting Freshdesk

  1. In Freshdesk, go to Profile → API Key. Copy the key.
  2. In Momentum, go to Settings → Integrations → Add integration. Pick Freshdesk.
  3. Enter your subdomain (yourcompany.freshdesk.com) and the API key. Momentum runs a test call before saving.
  4. On save, you'll see a one-time modal with the webhook URL + secret to paste into Freshdesk. This is your only chance to see the secret — copy it now.
  5. In Freshdesk, go to Admin → Automations → Webhooks and configure:
    • URL: the Momentum webhook URL (/api/webhooks/freshdesk/{integrationId})
    • Custom header: X-Momentum-Webhook-Secret: {your secret}
    • Triggers: ticket created, updated, status changed

Importing tickets

From the Cases page, the "Import from Freshdesk" button opens a two-tab modal:

  • By ticket IDs — paste a list of Freshdesk ticket IDs to import specific tickets.
  • By filter — pick a status, updatedSince, and limit. Momentum pages through matching tickets and imports them.

Imports are idempotent. The composite unique index cases_external_link_uq (workspace_id, external_provider, external_ticket_id) prevents duplicate cases even if you re-run the same import.

Customers are auto-linked by email or domain; new customer rows are created with externalId = "freshdesk:{email}" when no match exists.

Bi-directional sync

After a case is linked to a Freshdesk ticket, changes flow both ways:

  • Inbound — webhook events from Freshdesk update the Momentum case (status, priority, assignee, comments).
  • Outbound — edits in Momentum push back to Freshdesk. Comments can optionally push as private notes (off by default).

Loop prevention

Two layers of loop prevention keep bi-directional sync from echoing itself:

  1. Source tagging. The shared updateCase() helper takes an explicit source argument ("user" | "import" | "webhook" | "reconciler"). Only user-initiated changes trigger outbound push.
  2. 10-second dedup. Before any outbound push, Momentum checks ticket_sync_log for a matching inbound event within the last 10 seconds. Matches are dropped.

The reconciler

A reconciler runs every 10 minutes inside Hocuspocus. For each linked case, it fetches the Freshdesk ticket and reconciles state divergences. It is a safety net for dropped webhooks — not a primary sync path.

The reconciler only reconciles; it never creates new cases. Imports are always explicit.

Security

  • Credentials — stored AES-256-GCM encrypted at rest using the ENCRYPTION_KEY env var (64-char hex).
  • Webhook verification — incoming webhooks are verified with crypto.timingSafeEqual against the per-integration secret.
  • Dedup by event ID — Freshdesk webhooks are deduped by their event ID; replays are no-ops.

Coming soon

  • Zendesk (Phase 34) — OAuth, bi-directional sync, feature parity with Freshdesk.
  • Cross-integration unified inbox — tickets from multiple systems in one Momentum view.