Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions apps/sim/blocks/blocks/gong.ts
Original file line number Diff line number Diff line change
@@ -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<GongResponse> = {
Expand All @@ -15,7 +16,10 @@ export const GongBlock: BlockConfig<GongResponse> = {
tags: ['meeting', 'sales-engagement', 'speech-to-text'],
bgColor: '#8039DF',
icon: GongIcon,
triggerAllowed: true,
subBlocks: [
...getTrigger('gong_call_completed').subBlocks,
...getTrigger('gong_webhook').subBlocks,
Comment thread
waleedlatif1 marked this conversation as resolved.
{
id: 'operation',
title: 'Operation',
Expand Down Expand Up @@ -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'],
},
}
21 changes: 21 additions & 0 deletions apps/sim/lib/webhooks/providers/gong.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { FormatInputContext, FormatInputResult, WebhookProviderHandler } from '@/lib/webhooks/providers/types'

export const gongHandler: WebhookProviderHandler = {
async formatInput({ body }: FormatInputContext): Promise<FormatInputResult> {
const b = body as Record<string, unknown>
const callData = b.callData as Record<string, unknown> | undefined
const metaData = (callData?.metaData as Record<string, unknown>) || {}
const content = callData?.content as Record<string, unknown> | undefined

return {
input: {
isTest: b.isTest ?? false,
callData,
metaData,
parties: (callData?.parties as unknown[]) || [],
context: (callData?.context as unknown[]) || [],
trackers: (content?.trackers as unknown[]) || [],
Comment thread
waleedlatif1 marked this conversation as resolved.
},
}
},
}
Comment thread
waleedlatif1 marked this conversation as resolved.
2 changes: 2 additions & 0 deletions apps/sim/lib/webhooks/providers/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -47,6 +48,7 @@ const PROVIDER_HANDLERS: Record<string, WebhookProviderHandler> = {
generic: genericHandler,
gmail: gmailHandler,
github: githubHandler,
gong: gongHandler,
google_forms: googleFormsHandler,
fathom: fathomHandler,
grain: grainHandler,
Expand Down
68 changes: 68 additions & 0 deletions apps/sim/triggers/gong/call_completed.ts
Original file line number Diff line number Diff line change
@@ -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',
},
},
Comment thread
waleedlatif1 marked this conversation as resolved.
{
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',
},
},
}
2 changes: 2 additions & 0 deletions apps/sim/triggers/gong/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { gongCallCompletedTrigger } from './call_completed'
export { gongWebhookTrigger } from './webhook'
84 changes: 84 additions & 0 deletions apps/sim/triggers/gong/utils.ts
Original file line number Diff line number Diff line change
@@ -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 = [
'<strong>Note:</strong> You need admin access to Gong to set up webhooks. See the <a href="https://help.gong.io/docs/create-a-webhook-rule" target="_blank" rel="noopener noreferrer">Gong webhook documentation</a> for details.',
'Copy the <strong>Webhook URL</strong> above.',
'In Gong, go to <strong>Admin center > Settings > Ecosystem > Automation rules</strong>.',
'Click <strong>"+ Add Rule"</strong> to create a new automation rule.',
`Configure rule filters to match <strong>${eventType}</strong> calls.`,
'Under Actions, select <strong>"Fire webhook"</strong>.',
'Paste the Webhook URL into the destination field.',
'Choose an authentication method (URL includes key or Signed JWT header).',
'Save the rule and click <strong>"Save"</strong> above to activate your trigger.',
]

return instructions
.map(
(instruction, index) =>
`<div class="mb-3">${index === 0 ? instruction : `<strong>${index}.</strong> ${instruction}`}</div>`
)
.join('')
}

/**
* Build output schema for call events.
* Gong webhooks deliver call data including metadata, participants, context, and content analysis.
*/
export function buildCallOutputs(): Record<string, TriggerOutput> {
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<string, TriggerOutput>
}

/**
* Build output schema for generic webhook events.
* Uses the same call output structure since Gong webhooks primarily deliver call data.
*/
export function buildGenericOutputs(): Record<string, TriggerOutput> {
return buildCallOutputs()
}
Comment thread
waleedlatif1 marked this conversation as resolved.
77 changes: 77 additions & 0 deletions apps/sim/triggers/gong/webhook.ts
Original file line number Diff line number Diff line change
@@ -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,
},
Comment thread
waleedlatif1 marked this conversation as resolved.
{
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',
},
},
}
3 changes: 3 additions & 0 deletions apps/sim/triggers/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
Loading