Skip to content

Commit a8f2709

Browse files
authored
improvement(gong): validate integration against API docs, fix pagination/wandConfig consistency (#5361)
* improvement(gong): tighten pagination optionality and add wandConfig to ID list fields - mark cursor output optional:true on aggregate_activity, interaction_stats, list_flows for consistency with list_calls - add wandConfig to comma-separated ID fields (callIds, primaryUserIds, userIds, scorecardIds, reviewedUserIds) matching repo convention for CSV inputs * fix(gong): request context data for get_extensive_calls contentSelector.context/contextTiming were never set on the /v2/calls/extensive request, so the documented context (CRM/external-system links) output was silently always empty even though the field is declared in the tool's outputs. * feat(gong): add data privacy erase and Engage flow prospect tools - gong_purge_email_address / gong_purge_phone_number: POST /v2/data-privacy/erase-data-for-*, the write-half pairing with the existing lookup_email/lookup_phone read tools - gong_assign_flow_prospects: POST /v2/flows/prospects/assign, enrolls CRM prospects into an Engage flow - gong_get_prospect_flows: POST /v2/flows/prospects, looks up which flows a prospect is in Field names verified against an OpenAPI-generator-produced client (cedricziel/gong-rs) whose serde rename attributes mirror Gong's published spec, since Gong's interactive Swagger docs require an authenticated session and can't be fetched directly. * fix(gong): require human-entered target for data-erase tools emailAddress/phoneNumber on the purge tools were user-or-llm, letting an agent autonomously pick the erasure target for an irreversible operation with no human confirmation. Match the user-only visibility already used for credentials.
1 parent 4988ba6 commit a8f2709

12 files changed

Lines changed: 568 additions & 8 deletions

apps/sim/blocks/blocks/gong.ts

Lines changed: 102 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,13 @@ export const GongBlock: BlockConfig<GongResponse> = {
4343
{ label: 'List Trackers', id: 'list_trackers' },
4444
{ label: 'List Workspaces', id: 'list_workspaces' },
4545
{ label: 'List Flows', id: 'list_flows' },
46+
{ label: 'Assign Flow Prospects', id: 'assign_flow_prospects' },
47+
{ label: 'Get Prospect Flows', id: 'get_prospect_flows' },
4648
{ label: 'Get Coaching', id: 'get_coaching' },
4749
{ label: 'Lookup Email', id: 'lookup_email' },
4850
{ label: 'Lookup Phone', id: 'lookup_phone' },
51+
{ label: 'Purge Email Address', id: 'purge_email_address' },
52+
{ label: 'Purge Phone Number', id: 'purge_phone_number' },
4953
],
5054
value: () => 'list_calls',
5155
},
@@ -239,6 +243,12 @@ Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes
239243
type: 'short-input',
240244
placeholder: 'Comma-separated call IDs (optional)',
241245
condition: { field: 'operation', value: ['get_call_transcript', 'get_extensive_calls'] },
246+
wandConfig: {
247+
enabled: true,
248+
prompt: `Generate a comma-separated list of Gong call IDs based on the user's description.
249+
Return ONLY the comma-separated list of IDs - no explanations, no extra text.`,
250+
placeholder: 'Describe the call IDs (e.g., "calls 123456 and 789012")...',
251+
},
242252
},
243253
{
244254
id: 'transcriptFromDateTime',
@@ -289,6 +299,12 @@ Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes
289299
placeholder: 'Comma-separated user IDs (optional)',
290300
condition: { field: 'operation', value: 'get_extensive_calls' },
291301
mode: 'advanced',
302+
wandConfig: {
303+
enabled: true,
304+
prompt: `Generate a comma-separated list of Gong user IDs based on the user's description.
305+
Return ONLY the comma-separated list of IDs - no explanations, no extra text.`,
306+
placeholder: 'Describe the user IDs...',
307+
},
292308
},
293309

294310
// List Users inputs
@@ -405,6 +421,12 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
405421
],
406422
},
407423
mode: 'advanced',
424+
wandConfig: {
425+
enabled: true,
426+
prompt: `Generate a comma-separated list of Gong user IDs based on the user's description.
427+
Return ONLY the comma-separated list of IDs - no explanations, no extra text.`,
428+
placeholder: 'Describe the user IDs...',
429+
},
408430
},
409431

410432
// Aggregate by Period inputs
@@ -499,6 +521,12 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
499521
placeholder: 'Comma-separated scorecard IDs (optional)',
500522
condition: { field: 'operation', value: 'answered_scorecards' },
501523
mode: 'advanced',
524+
wandConfig: {
525+
enabled: true,
526+
prompt: `Generate a comma-separated list of Gong scorecard IDs based on the user's description.
527+
Return ONLY the comma-separated list of IDs - no explanations, no extra text.`,
528+
placeholder: 'Describe the scorecard IDs...',
529+
},
502530
},
503531
{
504532
id: 'reviewedUserIds',
@@ -507,6 +535,12 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
507535
placeholder: 'Comma-separated user IDs (optional)',
508536
condition: { field: 'operation', value: 'answered_scorecards' },
509537
mode: 'advanced',
538+
wandConfig: {
539+
enabled: true,
540+
prompt: `Generate a comma-separated list of Gong user IDs based on the user's description.
541+
Return ONLY the comma-separated list of IDs - no explanations, no extra text.`,
542+
placeholder: 'Describe the reviewed user IDs...',
543+
},
510544
},
511545

512546
// Get Folder Content inputs
@@ -550,6 +584,38 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
550584
required: { field: 'operation', value: 'list_flows' },
551585
},
552586

587+
// Assign Flow Prospects / Get Prospect Flows inputs
588+
{
589+
id: 'flowId',
590+
title: 'Flow ID',
591+
type: 'short-input',
592+
placeholder: 'Enter the Gong Engage flow ID',
593+
condition: { field: 'operation', value: 'assign_flow_prospects' },
594+
required: { field: 'operation', value: 'assign_flow_prospects' },
595+
},
596+
{
597+
id: 'crmProspectsIds',
598+
title: 'CRM Prospect IDs',
599+
type: 'short-input',
600+
placeholder: 'Comma-separated CRM contact or lead IDs',
601+
condition: { field: 'operation', value: ['assign_flow_prospects', 'get_prospect_flows'] },
602+
required: { field: 'operation', value: ['assign_flow_prospects', 'get_prospect_flows'] },
603+
wandConfig: {
604+
enabled: true,
605+
prompt: `Generate a comma-separated list of CRM prospect IDs based on the user's description.
606+
Return ONLY the comma-separated list of IDs - no explanations, no extra text.`,
607+
placeholder: 'Describe the CRM prospect IDs...',
608+
},
609+
},
610+
{
611+
id: 'flowInstanceOwnerEmail',
612+
title: 'Flow Instance Owner Email',
613+
type: 'short-input',
614+
placeholder: 'user@example.com',
615+
condition: { field: 'operation', value: 'assign_flow_prospects' },
616+
required: { field: 'operation', value: 'assign_flow_prospects' },
617+
},
618+
553619
// Get Coaching inputs
554620
{
555621
id: 'managerId',
@@ -610,24 +676,24 @@ Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes
610676
},
611677
},
612678

613-
// Lookup Email inputs
679+
// Lookup Email / Purge Email Address inputs
614680
{
615681
id: 'emailAddress',
616682
title: 'Email Address',
617683
type: 'short-input',
618684
placeholder: 'user@example.com',
619-
condition: { field: 'operation', value: 'lookup_email' },
620-
required: { field: 'operation', value: 'lookup_email' },
685+
condition: { field: 'operation', value: ['lookup_email', 'purge_email_address'] },
686+
required: { field: 'operation', value: ['lookup_email', 'purge_email_address'] },
621687
},
622688

623-
// Lookup Phone inputs
689+
// Lookup Phone / Purge Phone Number inputs
624690
{
625691
id: 'phoneNumber',
626692
title: 'Phone Number',
627693
type: 'short-input',
628694
placeholder: '+1234567890',
629-
condition: { field: 'operation', value: 'lookup_phone' },
630-
required: { field: 'operation', value: 'lookup_phone' },
695+
condition: { field: 'operation', value: ['lookup_phone', 'purge_phone_number'] },
696+
required: { field: 'operation', value: ['lookup_phone', 'purge_phone_number'] },
631697
},
632698

633699
// Pagination cursor (shared)
@@ -692,9 +758,13 @@ Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes
692758
'gong_list_trackers',
693759
'gong_list_workspaces',
694760
'gong_list_flows',
761+
'gong_assign_flow_prospects',
762+
'gong_get_prospect_flows',
695763
'gong_get_coaching',
696764
'gong_lookup_email',
697765
'gong_lookup_phone',
766+
'gong_purge_email_address',
767+
'gong_purge_phone_number',
698768
],
699769
config: {
700770
tool: (params) => `gong_${params.operation}`,
@@ -763,8 +833,20 @@ Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes
763833
type: 'string',
764834
description: 'Email of a Gong user to retrieve personal and company flows',
765835
},
766-
emailAddress: { type: 'string', description: 'Email address to look up' },
767-
phoneNumber: { type: 'string', description: 'Phone number to look up' },
836+
flowId: { type: 'string', description: 'Gong Engage flow ID' },
837+
crmProspectsIds: { type: 'string', description: 'Comma-separated CRM prospect IDs' },
838+
flowInstanceOwnerEmail: {
839+
type: 'string',
840+
description: 'Email of the Gong user who owns the flow instance and its to-dos',
841+
},
842+
emailAddress: {
843+
type: 'string',
844+
description: 'Email address to look up or purge',
845+
},
846+
phoneNumber: {
847+
type: 'string',
848+
description: 'Phone number to look up or purge',
849+
},
768850
cursor: { type: 'string', description: 'Pagination cursor' },
769851
},
770852
outputs: {
@@ -883,6 +965,18 @@ Return ONLY the timestamp string in ISO 8601 format - no explanations, no quotes
883965
'Gong Engage flows: [{id, name, folderId, folderName, visibility, creationDate, exclusive}]',
884966
},
885967

968+
// assign_flow_prospects / get_prospect_flows
969+
prospectsAssigned: {
970+
type: 'json',
971+
description:
972+
'Prospects assigned to (or enrolled in) flows: [{flowId, flowName, crmProspectId, flowInstanceId, flowInstanceOwnerEmail, flowInstanceOwnerFullName, flowInstanceCreateDate, flowInstanceStatus, workspaceId, exclusive}]',
973+
},
974+
prospectsNotAssigned: {
975+
type: 'json',
976+
description:
977+
'Prospects that failed to be assigned to a flow: [{flowId, crmProspectId, errorCode, errorMessage}]',
978+
},
979+
886980
// get_coaching
887981
coachingData: {
888982
type: 'json',

apps/sim/tools/gong/aggregate_activity.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ export const aggregateActivityTool: ToolConfig<
197197
cursor: {
198198
type: 'string',
199199
description: 'Pagination cursor for the next page',
200+
optional: true,
200201
},
201202
},
202203
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import type {
2+
GongAssignFlowProspectsParams,
3+
GongAssignFlowProspectsResponse,
4+
} from '@/tools/gong/types'
5+
import { getGongErrorMessage, parseGongIdList } from '@/tools/gong/utils'
6+
import type { ToolConfig } from '@/tools/types'
7+
8+
export const assignFlowProspectsTool: ToolConfig<
9+
GongAssignFlowProspectsParams,
10+
GongAssignFlowProspectsResponse
11+
> = {
12+
id: 'gong_assign_flow_prospects',
13+
name: 'Gong Assign Flow Prospects',
14+
description: 'Assign up to 200 CRM prospects (contacts or leads) to a Gong Engage flow.',
15+
version: '1.0.0',
16+
17+
params: {
18+
accessKey: {
19+
type: 'string',
20+
required: true,
21+
visibility: 'user-only',
22+
description: 'Gong API Access Key',
23+
},
24+
accessKeySecret: {
25+
type: 'string',
26+
required: true,
27+
visibility: 'user-only',
28+
description: 'Gong API Access Key Secret',
29+
},
30+
flowId: {
31+
type: 'string',
32+
required: true,
33+
visibility: 'user-or-llm',
34+
description: 'The Gong Engage flow ID to assign the prospects to',
35+
},
36+
crmProspectsIds: {
37+
type: 'string',
38+
required: true,
39+
visibility: 'user-or-llm',
40+
description: 'Comma-separated list of CRM prospect IDs (contacts or leads) to assign',
41+
},
42+
flowInstanceOwnerEmail: {
43+
type: 'string',
44+
required: true,
45+
visibility: 'user-or-llm',
46+
description: 'Email of the Gong user who owns the flow instance and its to-dos',
47+
},
48+
},
49+
50+
request: {
51+
url: 'https://api.gong.io/v2/flows/prospects/assign',
52+
method: 'POST',
53+
headers: (params) => ({
54+
'Content-Type': 'application/json',
55+
Authorization: `Basic ${btoa(`${params.accessKey}:${params.accessKeySecret}`)}`,
56+
}),
57+
body: (params) => ({
58+
flowId: params.flowId.trim(),
59+
crmProspectsIds: parseGongIdList(params.crmProspectsIds) ?? [],
60+
flowInstanceOwnerEmail: params.flowInstanceOwnerEmail.trim(),
61+
}),
62+
},
63+
64+
transformResponse: async (response: Response) => {
65+
const data = await response.json()
66+
if (!response.ok) {
67+
throw new Error(getGongErrorMessage(data, 'Failed to assign prospects to flow'))
68+
}
69+
return {
70+
success: true,
71+
output: {
72+
requestId: data.requestId ?? null,
73+
prospectsAssigned: data.prospectsAssigned ?? [],
74+
prospectsNotAssigned: data.prospectsNotAssigned ?? [],
75+
},
76+
}
77+
},
78+
79+
outputs: {
80+
requestId: {
81+
type: 'string',
82+
description: 'A Gong request reference ID for troubleshooting purposes',
83+
optional: true,
84+
},
85+
prospectsAssigned: {
86+
type: 'array',
87+
description: 'Prospects successfully assigned to the flow',
88+
items: {
89+
type: 'object',
90+
properties: {
91+
flowId: { type: 'string', description: 'The flow ID' },
92+
flowName: { type: 'string', description: 'The flow name' },
93+
crmProspectId: { type: 'string', description: 'The CRM prospect ID' },
94+
flowInstanceId: { type: 'string', description: 'The created flow instance ID' },
95+
flowInstanceOwnerEmail: {
96+
type: 'string',
97+
description: 'Email of the flow instance owner',
98+
},
99+
flowInstanceOwnerFullName: {
100+
type: 'string',
101+
description: 'Full name of the flow instance owner',
102+
},
103+
flowInstanceCreateDate: {
104+
type: 'string',
105+
description: 'Creation time of the flow instance in ISO-8601 format',
106+
},
107+
flowInstanceStatus: { type: 'string', description: 'Status of the flow instance' },
108+
workspaceId: { type: 'string', description: 'Workspace ID' },
109+
exclusive: {
110+
type: 'boolean',
111+
description: 'Whether this prospect can be added to other flows',
112+
},
113+
},
114+
},
115+
},
116+
prospectsNotAssigned: {
117+
type: 'array',
118+
description: 'Prospects that failed to be assigned to the flow',
119+
items: {
120+
type: 'object',
121+
properties: {
122+
flowId: { type: 'string', description: 'The flow ID' },
123+
crmProspectId: { type: 'string', description: 'The CRM prospect ID' },
124+
errorCode: {
125+
type: 'string',
126+
description: 'Failure reason: InvalidArgument, InvalidState, or UnexpectedError',
127+
},
128+
errorMessage: { type: 'string', description: 'Human-readable failure message' },
129+
},
130+
},
131+
},
132+
},
133+
}

apps/sim/tools/gong/get_extensive_calls.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ export const getExtensiveCallsTool: ToolConfig<
8282
const body: Record<string, unknown> = {
8383
filter,
8484
contentSelector: {
85+
context: 'Extended',
86+
contextTiming: ['Now', 'TimeOfCall'],
8587
exposedFields: {
8688
parties: true,
8789
content: {

0 commit comments

Comments
 (0)