Skip to content

feat(fathom): add Fathom AI Notetaker integration#3531

Merged
waleedlatif1 merged 27 commits intostagingfrom
waleedlatif1/fathom-integration
Mar 12, 2026
Merged

feat(fathom): add Fathom AI Notetaker integration#3531
waleedlatif1 merged 27 commits intostagingfrom
waleedlatif1/fathom-integration

Conversation

@waleedlatif1
Copy link
Collaborator

Summary

  • Add 5 tools: list meetings, get summary, get transcript, list team members, list teams
  • Add block with operation dropdown, conditional subBlocks, pagination, and all API filters
  • Add 2 webhook triggers (new meeting, generic) with automatic lifecycle management
  • Wire webhook create/delete in provider-subscriptions.ts
  • Add docs page and icon

Type of Change

  • New feature

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

waleedlatif1 and others added 22 commits February 16, 2026 00:36
…stash, algolia tools; isolated-vm robustness improvements, tables backend (#3271)

* feat(tools): advanced fields for youtube, vercel; added cloudflare and dataverse tools (#3257)

* refactor(vercel): mark optional fields as advanced mode

Move optional/power-user fields behind the advanced toggle:
- List Deployments: project filter, target, state
- Create Deployment: project ID override, redeploy from, target
- List Projects: search
- Create/Update Project: framework, build/output/install commands
- Env Vars: variable type
- Webhooks: project IDs filter
- Checks: path, details URL
- Team Members: role filter
- All operations: team ID scope

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style(youtube): mark optional params as advanced mode

Hide pagination, sort order, and filter fields behind the advanced
toggle for a cleaner default UX across all YouTube operations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* added advanced fields for vercel and youtube, added cloudflare and dataverse block

* addded desc for dataverse

* add more tools

* ack comment

* more

* ops

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(tables): added tables (#2867)

* updates

* required

* trashy table viewer

* updates

* updates

* filtering ui

* updates

* updates

* updates

* one input mode

* format

* fix lints

* improved errors

* updates

* updates

* chages

* doc strings

* breaking down file

* update comments with ai

* updates

* comments

* changes

* revert

* updates

* dedupe

* updates

* updates

* updates

* refactoring

* renames & refactors

* refactoring

* updates

* undo

* update db

* wand

* updates

* fix comments

* fixes

* simplify comments

* u[dates

* renames

* better comments

* validation

* updates

* updates

* updates

* fix sorting

* fix appearnce

* updating prompt to make it user sort

* rm

* updates

* rename

* comments

* clean comments

* simplicifcaiton

* updates

* updates

* refactor

* reduced type confusion

* undo

* rename

* undo changes

* undo

* simplify

* updates

* updates

* revert

* updates

* db updates

* type fix

* fix

* fix error handling

* updates

* docs

* docs

* updates

* rename

* dedupe

* revert

* uncook

* updates

* fix

* fix

* fix

* fix

* prepare merge

* readd migrations

* add back missed code

* migrate enrichment logic to general abstraction

* address bugbot concerns

* adhere to size limits for tables

* remove conflicting migration

* add back migrations

* fix tables auth

* fix permissive auth

* fix lint

* reran migrations

* migrate to use tanstack query for all server state

* update table-selector

* update names

* added tables to permission groups, updated subblock types

---------

Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>
Co-authored-by: waleed <walif6@gmail.com>

* fix(snapshot): changed insert to upsert when concurrent identical child workflows are running (#3259)

* fix(snapshot): changed insert to upsert when concurrent identical child workflows are running

* fixed ci tests failing

* fix(workflows): disallow duplicate workflow names at the same folder level (#3260)

* feat(tools): added redis, upstash, algolia, and revenuecat (#3261)

* feat(tools): added redis, upstash, algolia, and revenuecat

* ack comment

* feat(models): add gemini-3.1-pro-preview and update gemini-3-pro thinking levels (#3263)

* fix(audit-log): lazily resolve actor name/email when missing (#3262)

* fix(blocks): move type coercions from tools.config.tool to tools.config.params (#3264)

* fix(blocks): move type coercions from tools.config.tool to tools.config.params

Number() coercions in tools.config.tool ran at serialization time before
variable resolution, destroying dynamic references like <block.result.count>
by converting them to NaN/null. Moved all coercions to tools.config.params
which runs at execution time after variables are resolved.

Fixed in 15 blocks: exa, arxiv, sentry, incidentio, wikipedia, ahrefs,
posthog, elasticsearch, dropbox, hunter, lemlist, spotify, youtube, grafana,
parallel. Also added mode: 'advanced' to optional exa fields.

Closes #3258

* fix(blocks): address PR review — move remaining param mutations from tool() to params()

- Moved field mappings from tool() to params() in grafana, posthog,
  lemlist, spotify, dropbox (same dynamic reference bug)
- Fixed parallel.ts excerpts/full_content boolean logic
- Fixed parallel.ts search_queries empty case (must set undefined)
- Fixed elasticsearch.ts timeout not included when already ends with 's'
- Restored dropbox.ts tool() switch for proper default fallback

* fix(blocks): restore field renames to tool() for serialization-time validation

Field renames (e.g. personalApiKey→apiKey) must be in tool() because
validateRequiredFieldsBeforeExecution calls selectToolId()→tool() then
checks renamed field names on params. Only type coercions (Number(),
boolean) stay in params() to avoid destroying dynamic variable references.

* improvement(resolver): resovled empty sentinel to not pass through unexecuted valid refs to text inputs (#3266)

* fix(blocks): add required constraint for serviceDeskId in JSM block (#3268)

* fix(blocks): add required constraint for serviceDeskId in JSM block

* fix(blocks): rename custom field values to request field values in JSM create request

* fix(trigger): add isolated-vm support to trigger.dev container builds (#3269)

Scheduled workflow executions running in trigger.dev containers were
failing to spawn isolated-vm workers because the native module wasn't
available in the container. This caused loop condition evaluation to
silently fail and exit after one iteration.

- Add isolated-vm to build.external and additionalPackages in trigger config
- Include isolated-vm-worker.cjs via additionalFiles for child process spawning
- Add fallback path resolution for worker file in trigger.dev environment

* fix(tables): hide tables from sidebar and block registry (#3270)

* fix(tables): hide tables from sidebar and block registry

* fix(trigger): add isolated-vm support to trigger.dev container builds (#3269)

Scheduled workflow executions running in trigger.dev containers were
failing to spawn isolated-vm workers because the native module wasn't
available in the container. This caused loop condition evaluation to
silently fail and exit after one iteration.

- Add isolated-vm to build.external and additionalPackages in trigger config
- Include isolated-vm-worker.cjs via additionalFiles for child process spawning
- Add fallback path resolution for worker file in trigger.dev environment

* lint

* fix(trigger): update node version to align with main app (#3272)

* fix(build): fix corrupted sticky disk cache on blacksmith (#3273)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Lakee Sivaraya <71339072+lakeesiv@users.noreply.github.com>
Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>
Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com>
… fixes, removed retired models, hex integration
…ogle tasks and bigquery integrations, workflow lock
@vercel
Copy link

vercel bot commented Mar 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Mar 12, 2026 5:53pm

Request Review

@cursor
Copy link

cursor bot commented Mar 12, 2026

PR Summary

Medium Risk
Adds a new third-party integration that makes authenticated requests to Fathom APIs and creates/deletes external webhook subscriptions; failures or misconfig could impact webhook lifecycle and data returned to workflows.

Overview
Adds a new Fathom integration across the app: a fathom block with an operation selector (list meetings, fetch summary/transcript, list members/teams) backed by 5 new Fathom tool implementations and shared response types.

Introduces two Fathom webhook triggers (fathom_new_meeting, fathom_webhook) and wires automatic external webhook subscription create/delete into provider-subscriptions.ts (including input validation and user-friendly errors).

Updates docs to include a new fathom tool page, adds FathomIcon, and registers the new block/tools/triggers in the relevant registries and docs icon mapping.

Written by Cursor Bugbot for commit 2d394ca. Configure here.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 12, 2026

Greptile Summary

This PR adds a full Fathom AI Notetaker integration to Sim, including 5 tools (list meetings, get summary, get transcript, list team members, list teams), 2 webhook triggers (new meeting content, generic), automatic webhook lifecycle management, a block with operation dropdown and conditional subBlocks, an icon, and a docs page. The implementation follows the established patterns for provider integrations in the codebase (e.g., Grain, Circleback) and incorporates several fixes from prior review rounds.

Key observations:

  • The toBool helper in createFathomWebhookSubscription only guards against undefined but not null; if providerConfig fields are ever serialised as null (e.g., from a database round-trip), include_summary would silently default to false instead of the intended true
  • Neither the fathom_new_meeting nor fathom_webhook trigger verifies the authenticity of incoming POST payloads — if Fathom offers a webhook signing secret, it should be used; even if not currently available, a comment tracking this gap would be valuable
  • The include-flag tool parameters (includeSummary, etc.) are typed as string and compared with === 'true', but callers (including LLMs) may pass the boolean true, which would silently skip the filter with no error

Confidence Score: 3/5

  • Mostly safe to merge with minor logic and security concerns that should be addressed before production use
  • The core tool and block implementation is solid and follows established codebase patterns. Previous review rounds addressed the most critical bugs (response.ok checks, null recording_id, crm_matches mapping, include flag defaults). The remaining issues are an edge-case null-handling bug in toBool that could silently suppress the include_summary default, a missing webhook signature check that creates a spoofing surface, and a string/boolean type mismatch in include-flag params that can silently no-op LLM-provided values.
  • apps/sim/lib/webhooks/provider-subscriptions.ts (toBool null handling), apps/sim/triggers/fathom/webhook.ts and new_meeting.ts (missing signature verification)

Important Files Changed

Filename Overview
apps/sim/lib/webhooks/provider-subscriptions.ts Adds createFathomWebhookSubscription and deleteFathomWebhook; the toBool helper does not guard against null, which can coerce the include_summary default from true to false in edge cases.
apps/sim/triggers/fathom/webhook.ts Defines the generic Fathom webhook trigger with correct subBlock structure; lacks incoming payload signature verification, which could allow spoofed requests to trigger workflows.
apps/sim/triggers/fathom/new_meeting.ts Defines the "new meeting content" Fathom trigger; mirrors webhook.ts structure correctly but shares the same missing signature-verification concern.
apps/sim/tools/fathom/list_meetings.ts Implements list-meetings tool with correct response.ok guard, null-safe transforms, and crm_matches mapping; include-flag params are string typed but callers passing boolean true would silently skip the filter.
apps/sim/blocks/blocks/fathom.ts Block config with operation dropdown, conditional subBlocks, and trigger integration; well structured with correct tool routing.
apps/sim/triggers/fathom/utils.ts Shared output schema and setup instruction helpers; crm_matches and all webhook payload fields are included.

Sequence Diagram

sequenceDiagram
    participant User as User (UI)
    participant Sim as Sim Backend
    participant FathomAPI as Fathom API
    participant Webhook as Sim Webhook Endpoint

    Note over User,FathomAPI: Webhook Registration Flow
    User->>Sim: Save trigger config (apiKey, triggeredFor, include flags)
    Sim->>Sim: createFathomWebhookSubscription()
    Sim->>FathomAPI: POST /external/v1/webhooks<br/>{destination_url, triggered_for, include_*}
    FathomAPI-->>Sim: {id: "fathom-webhook-id"}
    Sim->>Sim: Store externalId in webhookData

    Note over FathomAPI,Webhook: Incoming Event Flow
    FathomAPI->>Webhook: POST /api/webhooks/trigger/{path}<br/>Meeting payload
    Webhook->>Sim: Process trigger (no signature check)
    Sim->>User: Execute workflow with meeting data

    Note over User,FathomAPI: Tool Usage Flow
    User->>Sim: List Meetings / Get Summary / Get Transcript
    Sim->>FathomAPI: GET /external/v1/meetings<br/>or /recordings/{id}/summary<br/>or /recordings/{id}/transcript
    FathomAPI-->>Sim: Meeting data / Summary / Transcript
    Sim-->>User: Transformed response

    Note over Sim,FathomAPI: Webhook Deletion Flow
    User->>Sim: Remove trigger
    Sim->>Sim: deleteFathomWebhook()<br/>validateAlphanumericId(externalId)
    Sim->>FathomAPI: DELETE /external/v1/webhooks/{externalId}
    FathomAPI-->>Sim: 204 No Content
Loading

Comments Outside Diff (3)

  1. apps/sim/lib/webhooks/provider-subscriptions.ts, line 1401-1413 (link)

    toBool silently coerces null to false instead of falling back

    The toBool helper only guards === undefined, but database-stored JSON can deserialise missing fields as null. When that happens:

    toBool(null, true)  // returns false — not the intended fallback!

    This means include_summary would be sent as false even though the intended default is true, potentially surprising users who never touched the toggle. The guard should cover both null and undefined:

  2. apps/sim/triggers/fathom/webhook.ts, line 122-128 (link)

    No incoming webhook signature verification

    Neither fathom_webhook nor fathom_new_meeting verifies that an incoming POST actually originates from Fathom. Any party who discovers the webhook URL (e.g., from a log or a shared URL) can send a crafted payload and trigger a workflow with arbitrary data.

    If the Fathom API offers a signing secret or HMAC header when creating a webhook, the destination_url call in createFathomWebhookSubscription should request one and this trigger config should validate it (similar to how other providers in the codebase validate X-Hub-Signature / X-Webhook-Signature).

    Even if Fathom does not yet expose a signing mechanism, it is worth adding a comment here to track this gap so future maintainers do not overlook it.

    The same concern applies to apps/sim/triggers/fathom/new_meeting.ts lines 122-128.

  3. apps/sim/tools/fathom/list_meetings.ts, line 17-40 (link)

    Include-flag params typed as string but downstream comparisons expect booleans

    includeSummary, includeTranscript, includeActionItems, and includeCrmMatches are declared with type: 'string' in the tool params, and the URL builder correctly compares them with === 'true'. However, the FathomListMeetingsParams interface in types.ts types these as string | undefined, while the block subBlocks return the string ids 'true' / 'false' from the dropdown.

    This means an LLM or external caller that passes boolean true instead of the string 'true' would silently get no filter applied (the === 'true' check would fail). Documenting the expected string format explicitly in the description field (e.g. "Pass 'true' or 'false' as a string") would prevent silent mismatch.

Last reviewed commit: 2d394ca

- Add response.ok checks to all 5 tool transformResponse functions
- Fix include_summary default to respect explicit false (check undefined)
- Add externalId validation before URL interpolation in webhook deletion
@waleedlatif1
Copy link
Collaborator Author

@greptile review

@waleedlatif1 waleedlatif1 changed the base branch from staging to main March 12, 2026 08:41
- Remove redundant 204 status check in deleteFathomWebhook (204 is ok)
- Use consistent undefined-guard pattern for all include flags
- Add .catch() fallback on webhook creation JSON parse
- Change recording_id default from 0 to null to avoid misleading sentinel
@waleedlatif1
Copy link
Collaborator Author

@cursor review

@waleedlatif1
Copy link
Collaborator Author

@greptile review

…ix action_items type

- Add crm_matches pass-through in list_meetings transform (was silently dropped)
- Fix action_items type to match API schema (description, user_generated, completed, etc.)
- Add crm_matches type with contacts, companies, deals, error fields
@waleedlatif1 waleedlatif1 changed the base branch from main to staging March 12, 2026 08:48
@waleedlatif1
Copy link
Collaborator Author

@greptile

@waleedlatif1
Copy link
Collaborator Author

@cursor review

1 similar comment
@waleedlatif1
Copy link
Collaborator Author

@cursor review

@waleedlatif1
Copy link
Collaborator Author

@greptile review

- Add type: 'object' to recorded_by and default_summary trigger outputs
- Use val === true || val === 'true' pattern for include flag coercion
  to safely handle both boolean and string values from providerConfig
@waleedlatif1
Copy link
Collaborator Author

@cursor review

@waleedlatif1
Copy link
Collaborator Author

@greptile review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

2 issues from previous reviews remain unresolved.

Fix All in Cursor

Comment @cursor review or bugbot run to trigger another review on this PR

@waleedlatif1 waleedlatif1 merged commit 97f78c6 into staging Mar 12, 2026
12 checks passed
@waleedlatif1 waleedlatif1 deleted the waleedlatif1/fathom-integration branch March 12, 2026 18:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants