From 2f3e3826a097015752a78d9e2504adc86b05fd5b Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 6 Apr 2026 10:35:30 -0700 Subject: [PATCH 1/4] feat(triggers): add Gong webhook triggers for call events --- apps/sim/blocks/blocks/gong.ts | 8 ++ apps/sim/lib/webhooks/providers/gong.ts | 21 ++++++ apps/sim/lib/webhooks/providers/registry.ts | 2 + apps/sim/triggers/gong/call_completed.ts | 68 +++++++++++++++++ apps/sim/triggers/gong/index.ts | 2 + apps/sim/triggers/gong/utils.ts | 84 +++++++++++++++++++++ apps/sim/triggers/gong/webhook.ts | 77 +++++++++++++++++++ apps/sim/triggers/registry.ts | 3 + 8 files changed, 265 insertions(+) create mode 100644 apps/sim/lib/webhooks/providers/gong.ts create mode 100644 apps/sim/triggers/gong/call_completed.ts create mode 100644 apps/sim/triggers/gong/index.ts create mode 100644 apps/sim/triggers/gong/utils.ts create mode 100644 apps/sim/triggers/gong/webhook.ts diff --git a/apps/sim/blocks/blocks/gong.ts b/apps/sim/blocks/blocks/gong.ts index 33adaf28742..0e84a8cc120 100644 --- a/apps/sim/blocks/blocks/gong.ts +++ b/apps/sim/blocks/blocks/gong.ts @@ -1,5 +1,6 @@ import { GongIcon } from '@/components/icons' import { AuthMode, type BlockConfig, IntegrationType } from '@/blocks/types' +import { getTrigger } from '@/triggers' import type { GongResponse } from '@/tools/gong/types' export const GongBlock: BlockConfig = { @@ -15,7 +16,10 @@ export const GongBlock: BlockConfig = { tags: ['meeting', 'sales-engagement', 'speech-to-text'], bgColor: '#8039DF', icon: GongIcon, + triggerAllowed: true, subBlocks: [ + ...getTrigger('gong_call_completed').subBlocks, + ...getTrigger('gong_webhook').subBlocks, { id: 'operation', title: 'Operation', @@ -568,4 +572,8 @@ Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes description: 'Gong API response data', }, }, + triggers: { + enabled: true, + available: ['gong_call_completed', 'gong_webhook'], + }, } diff --git a/apps/sim/lib/webhooks/providers/gong.ts b/apps/sim/lib/webhooks/providers/gong.ts new file mode 100644 index 00000000000..c8a44205101 --- /dev/null +++ b/apps/sim/lib/webhooks/providers/gong.ts @@ -0,0 +1,21 @@ +import type { FormatInputContext, FormatInputResult, WebhookProviderHandler } from '@/lib/webhooks/providers/types' + +export const gongHandler: WebhookProviderHandler = { + async formatInput({ body }: FormatInputContext): Promise { + const b = body as Record + const callData = b.callData as Record | undefined + const metaData = (callData?.metaData as Record) || {} + const content = callData?.content as Record | undefined + + return { + input: { + isTest: b.isTest ?? false, + callData, + metaData, + parties: (callData?.parties as unknown[]) || [], + context: (callData?.context as unknown[]) || [], + trackers: (content?.trackers as unknown[]) || [], + }, + } + }, +} diff --git a/apps/sim/lib/webhooks/providers/registry.ts b/apps/sim/lib/webhooks/providers/registry.ts index 00ae58a21b1..0b85f5f7de0 100644 --- a/apps/sim/lib/webhooks/providers/registry.ts +++ b/apps/sim/lib/webhooks/providers/registry.ts @@ -12,6 +12,7 @@ import { firefliesHandler } from '@/lib/webhooks/providers/fireflies' import { genericHandler } from '@/lib/webhooks/providers/generic' import { githubHandler } from '@/lib/webhooks/providers/github' import { gmailHandler } from '@/lib/webhooks/providers/gmail' +import { gongHandler } from '@/lib/webhooks/providers/gong' import { googleFormsHandler } from '@/lib/webhooks/providers/google-forms' import { grainHandler } from '@/lib/webhooks/providers/grain' import { hubspotHandler } from '@/lib/webhooks/providers/hubspot' @@ -47,6 +48,7 @@ const PROVIDER_HANDLERS: Record = { generic: genericHandler, gmail: gmailHandler, github: githubHandler, + gong: gongHandler, google_forms: googleFormsHandler, fathom: fathomHandler, grain: grainHandler, diff --git a/apps/sim/triggers/gong/call_completed.ts b/apps/sim/triggers/gong/call_completed.ts new file mode 100644 index 00000000000..b98e6bd5c22 --- /dev/null +++ b/apps/sim/triggers/gong/call_completed.ts @@ -0,0 +1,68 @@ +import { GongIcon } from '@/components/icons' +import type { TriggerConfig } from '@/triggers/types' +import { buildCallOutputs, gongSetupInstructions } from './utils' + +/** + * Gong Call Completed Trigger + * + * Secondary trigger - does NOT include the dropdown (the generic webhook trigger has it). + * Fires when a call matching the configured rule is processed in Gong. + */ +export const gongCallCompletedTrigger: TriggerConfig = { + id: 'gong_call_completed', + name: 'Gong Call Completed', + provider: 'gong', + description: 'Trigger workflow when a call is completed and processed in Gong', + version: '1.0.0', + icon: GongIcon, + + subBlocks: [ + { + id: 'webhookUrlDisplay', + title: 'Webhook URL', + type: 'short-input', + readOnly: true, + showCopyButton: true, + useWebhookUrl: true, + placeholder: 'Webhook URL will be generated', + mode: 'trigger', + condition: { + field: 'selectedTriggerId', + value: 'gong_call_completed', + }, + }, + { + id: 'triggerSave', + title: '', + type: 'trigger-save', + hideFromPreview: true, + mode: 'trigger', + triggerId: 'gong_call_completed', + condition: { + field: 'selectedTriggerId', + value: 'gong_call_completed', + }, + }, + { + id: 'triggerInstructions', + title: 'Setup Instructions', + hideFromPreview: true, + type: 'text', + defaultValue: gongSetupInstructions('Call Completed'), + mode: 'trigger', + condition: { + field: 'selectedTriggerId', + value: 'gong_call_completed', + }, + }, + ], + + outputs: buildCallOutputs(), + + webhook: { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + }, +} diff --git a/apps/sim/triggers/gong/index.ts b/apps/sim/triggers/gong/index.ts new file mode 100644 index 00000000000..e27d2ad6c2a --- /dev/null +++ b/apps/sim/triggers/gong/index.ts @@ -0,0 +1,2 @@ +export { gongCallCompletedTrigger } from './call_completed' +export { gongWebhookTrigger } from './webhook' diff --git a/apps/sim/triggers/gong/utils.ts b/apps/sim/triggers/gong/utils.ts new file mode 100644 index 00000000000..be842aca0b4 --- /dev/null +++ b/apps/sim/triggers/gong/utils.ts @@ -0,0 +1,84 @@ +import type { TriggerOutput } from '@/triggers/types' + +/** + * Shared trigger dropdown options for all Gong triggers + */ +export const gongTriggerOptions = [ + { label: 'Call Completed', id: 'gong_call_completed' }, + { label: 'General Webhook (All Events)', id: 'gong_webhook' }, +] + +/** + * Generate setup instructions for a specific Gong event type + */ +export function gongSetupInstructions(eventType: string): string { + const instructions = [ + 'Note: You need admin access to Gong to set up webhooks. See the Gong webhook documentation for details.', + 'Copy the Webhook URL above.', + 'In Gong, go to Admin center > Settings > Ecosystem > Automation rules.', + 'Click "+ Add Rule" to create a new automation rule.', + `Configure rule filters to match ${eventType} calls.`, + 'Under Actions, select "Fire webhook".', + 'Paste the Webhook URL into the destination field.', + 'Choose an authentication method (URL includes key or Signed JWT header).', + 'Save the rule and click "Save" above to activate your trigger.', + ] + + return instructions + .map( + (instruction, index) => + `
${index === 0 ? instruction : `${index}. ${instruction}`}
` + ) + .join('') +} + +/** + * Build output schema for call events. + * Gong webhooks deliver call data including metadata, participants, context, and content analysis. + */ +export function buildCallOutputs(): Record { + return { + isTest: { + type: 'boolean', + description: 'Whether this is a test webhook from the Gong UI', + }, + callData: { + type: 'json', + description: 'Full call data object', + }, + metaData: { + id: { type: 'string', description: 'Gong call ID' }, + url: { type: 'string', description: 'URL to the call in Gong' }, + title: { type: 'string', description: 'Call title' }, + scheduled: { type: 'string', description: 'Scheduled start time (ISO 8601)' }, + started: { type: 'string', description: 'Actual start time (ISO 8601)' }, + duration: { type: 'number', description: 'Call duration in seconds' }, + primaryUserId: { type: 'string', description: 'Primary Gong user ID' }, + direction: { type: 'string', description: 'Call direction (Conference, Call, etc.)' }, + system: { type: 'string', description: 'Meeting system (Zoom, Teams, etc.)' }, + scope: { type: 'string', description: 'Call scope (External or Internal)' }, + media: { type: 'string', description: 'Media type (Video or Audio)' }, + language: { type: 'string', description: 'Call language code' }, + }, + parties: { + type: 'array', + description: 'Array of call participants with name, email, title, and affiliation', + }, + context: { + type: 'array', + description: 'Array of CRM context objects (Salesforce opportunities, accounts, etc.)', + }, + trackers: { + type: 'array', + description: 'Array of tracked topics/keywords with counts', + }, + } as Record +} + +/** + * Build output schema for generic webhook events. + * Uses the same call output structure since Gong webhooks primarily deliver call data. + */ +export function buildGenericOutputs(): Record { + return buildCallOutputs() +} diff --git a/apps/sim/triggers/gong/webhook.ts b/apps/sim/triggers/gong/webhook.ts new file mode 100644 index 00000000000..164a81f2d23 --- /dev/null +++ b/apps/sim/triggers/gong/webhook.ts @@ -0,0 +1,77 @@ +import { GongIcon } from '@/components/icons' +import type { TriggerConfig } from '@/triggers/types' +import { buildGenericOutputs, gongSetupInstructions, gongTriggerOptions } from './utils' + +/** + * Gong Generic Webhook Trigger + * + * Primary trigger - includes the dropdown for selecting trigger type. + * Accepts all webhook events from Gong automation rules. + */ +export const gongWebhookTrigger: TriggerConfig = { + id: 'gong_webhook', + name: 'Gong Webhook', + provider: 'gong', + description: 'Generic webhook trigger for all Gong events', + version: '1.0.0', + icon: GongIcon, + + subBlocks: [ + { + id: 'selectedTriggerId', + title: 'Trigger Type', + type: 'dropdown', + mode: 'trigger', + options: gongTriggerOptions, + value: () => 'gong_webhook', + required: true, + }, + { + id: 'webhookUrlDisplay', + title: 'Webhook URL', + type: 'short-input', + readOnly: true, + showCopyButton: true, + useWebhookUrl: true, + placeholder: 'Webhook URL will be generated', + mode: 'trigger', + condition: { + field: 'selectedTriggerId', + value: 'gong_webhook', + }, + }, + { + id: 'triggerSave', + title: '', + type: 'trigger-save', + hideFromPreview: true, + mode: 'trigger', + triggerId: 'gong_webhook', + condition: { + field: 'selectedTriggerId', + value: 'gong_webhook', + }, + }, + { + id: 'triggerInstructions', + title: 'Setup Instructions', + hideFromPreview: true, + type: 'text', + defaultValue: gongSetupInstructions('All Events'), + mode: 'trigger', + condition: { + field: 'selectedTriggerId', + value: 'gong_webhook', + }, + }, + ], + + outputs: buildGenericOutputs(), + + webhook: { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + }, +} diff --git a/apps/sim/triggers/registry.ts b/apps/sim/triggers/registry.ts index 4390bfeefff..4662dda9d4b 100644 --- a/apps/sim/triggers/registry.ts +++ b/apps/sim/triggers/registry.ts @@ -89,6 +89,7 @@ import { githubWorkflowRunTrigger, } from '@/triggers/github' import { gmailPollingTrigger } from '@/triggers/gmail' +import { gongCallCompletedTrigger, gongWebhookTrigger } from '@/triggers/gong' import { googleFormsWebhookTrigger } from '@/triggers/googleforms' import { grainHighlightCreatedTrigger, @@ -254,6 +255,8 @@ export const TRIGGER_REGISTRY: TriggerRegistry = { fathom_new_meeting: fathomNewMeetingTrigger, fathom_webhook: fathomWebhookTrigger, gmail_poller: gmailPollingTrigger, + gong_call_completed: gongCallCompletedTrigger, + gong_webhook: gongWebhookTrigger, grain_webhook: grainWebhookTrigger, grain_item_added: grainItemAddedTrigger, grain_item_updated: grainItemUpdatedTrigger, From 9bb5bd0a3dbfa613120502a40621d2608fac52cf Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 6 Apr 2026 10:51:39 -0700 Subject: [PATCH 2/4] fix(triggers): reorder Gong trigger spread and dropdown options --- apps/sim/blocks/blocks/gong.ts | 4 ++-- apps/sim/triggers/gong/utils.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/sim/blocks/blocks/gong.ts b/apps/sim/blocks/blocks/gong.ts index 0e84a8cc120..e074b3e4279 100644 --- a/apps/sim/blocks/blocks/gong.ts +++ b/apps/sim/blocks/blocks/gong.ts @@ -18,8 +18,8 @@ export const GongBlock: BlockConfig = { icon: GongIcon, triggerAllowed: true, subBlocks: [ - ...getTrigger('gong_call_completed').subBlocks, ...getTrigger('gong_webhook').subBlocks, + ...getTrigger('gong_call_completed').subBlocks, { id: 'operation', title: 'Operation', @@ -574,6 +574,6 @@ Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes }, triggers: { enabled: true, - available: ['gong_call_completed', 'gong_webhook'], + available: ['gong_webhook', 'gong_call_completed'], }, } diff --git a/apps/sim/triggers/gong/utils.ts b/apps/sim/triggers/gong/utils.ts index be842aca0b4..a203478ba27 100644 --- a/apps/sim/triggers/gong/utils.ts +++ b/apps/sim/triggers/gong/utils.ts @@ -4,8 +4,8 @@ import type { TriggerOutput } from '@/triggers/types' * Shared trigger dropdown options for all Gong triggers */ export const gongTriggerOptions = [ - { label: 'Call Completed', id: 'gong_call_completed' }, { label: 'General Webhook (All Events)', id: 'gong_webhook' }, + { label: 'Call Completed', id: 'gong_call_completed' }, ] /** From 5a71158befa68487c2d30b1262ba722d7c419187 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 6 Apr 2026 10:59:56 -0700 Subject: [PATCH 3/4] fix(triggers): resolve Biome lint errors in Gong trigger files --- apps/sim/blocks/blocks/gong.ts | 2 +- apps/sim/lib/webhooks/providers/gong.ts | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/sim/blocks/blocks/gong.ts b/apps/sim/blocks/blocks/gong.ts index e074b3e4279..ef41be5d22f 100644 --- a/apps/sim/blocks/blocks/gong.ts +++ b/apps/sim/blocks/blocks/gong.ts @@ -1,7 +1,7 @@ import { GongIcon } from '@/components/icons' import { AuthMode, type BlockConfig, IntegrationType } from '@/blocks/types' -import { getTrigger } from '@/triggers' import type { GongResponse } from '@/tools/gong/types' +import { getTrigger } from '@/triggers' export const GongBlock: BlockConfig = { type: 'gong', diff --git a/apps/sim/lib/webhooks/providers/gong.ts b/apps/sim/lib/webhooks/providers/gong.ts index c8a44205101..c3272f5c4c1 100644 --- a/apps/sim/lib/webhooks/providers/gong.ts +++ b/apps/sim/lib/webhooks/providers/gong.ts @@ -1,4 +1,8 @@ -import type { FormatInputContext, FormatInputResult, WebhookProviderHandler } from '@/lib/webhooks/providers/types' +import type { + FormatInputContext, + FormatInputResult, + WebhookProviderHandler, +} from '@/lib/webhooks/providers/types' export const gongHandler: WebhookProviderHandler = { async formatInput({ body }: FormatInputContext): Promise { From a79bb4b5c948a3263ebf590d05aa7caf2029db29 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 6 Apr 2026 11:02:02 -0700 Subject: [PATCH 4/4] json --- .../(landing)/integrations/data/integrations.json | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/apps/sim/app/(landing)/integrations/data/integrations.json b/apps/sim/app/(landing)/integrations/data/integrations.json index 9db82b6d349..22f740d785c 100644 --- a/apps/sim/app/(landing)/integrations/data/integrations.json +++ b/apps/sim/app/(landing)/integrations/data/integrations.json @@ -4106,8 +4106,19 @@ } ], "operationCount": 18, - "triggers": [], - "triggerCount": 0, + "triggers": [ + { + "id": "gong_webhook", + "name": "Gong Webhook", + "description": "Generic webhook trigger for all Gong events" + }, + { + "id": "gong_call_completed", + "name": "Gong Call Completed", + "description": "Trigger workflow when a call is completed and processed in Gong" + } + ], + "triggerCount": 2, "authType": "none", "category": "tools", "integrationType": "sales-intelligence",