Skip to content

Commit 69284ae

Browse files
committed
fix(webhook): strip extraneous fields from trigger processing (#2686)
1 parent c7440cb commit 69284ae

File tree

4 files changed

+59
-127
lines changed

4 files changed

+59
-127
lines changed

apps/sim/executor/execution/block-executor.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,22 @@ export class BlockExecutor {
331331
}
332332
return filtered
333333
}
334+
335+
const isTrigger =
336+
block.metadata?.category === 'triggers' ||
337+
block.config?.params?.triggerMode === true ||
338+
block.metadata?.id === BlockType.STARTER
339+
340+
if (isTrigger) {
341+
const filtered: NormalizedBlockOutput = {}
342+
const internalKeys = ['webhook', 'workflowId', 'input']
343+
for (const [key, value] of Object.entries(output)) {
344+
if (internalKeys.includes(key)) continue
345+
filtered[key] = value
346+
}
347+
return filtered
348+
}
349+
334350
return output
335351
}
336352

apps/sim/executor/handlers/trigger/trigger-handler.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,6 @@ describe('TriggerBlockHandler', () => {
205205

206206
const result = await handler.execute(mockContext, scheduleBlock, {})
207207

208-
// Schedule triggers typically don't have input data, just trigger the workflow
209208
expect(result).toEqual({})
210209
})
211210

apps/sim/executor/handlers/trigger/trigger-handler.ts

Lines changed: 3 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,7 @@ export class TriggerBlockHandler implements BlockHandler {
3131

3232
const existingState = ctx.blockStates.get(block.id)
3333
if (existingState?.output && Object.keys(existingState.output).length > 0) {
34-
const existingOutput = existingState.output as any
35-
const existingProvider = existingOutput?.webhook?.data?.provider
36-
37-
return existingOutput
34+
return existingState.output
3835
}
3936

4037
const starterBlock = ctx.workflow?.blocks?.find((b) => b.metadata?.id === 'starter')
@@ -44,88 +41,8 @@ export class TriggerBlockHandler implements BlockHandler {
4441
const starterOutput = starterState.output
4542

4643
if (starterOutput.webhook?.data) {
47-
const webhookData = starterOutput.webhook?.data || {}
48-
const provider = webhookData.provider
49-
50-
if (provider === 'github') {
51-
const payloadSource = webhookData.payload || {}
52-
return {
53-
...payloadSource,
54-
webhook: starterOutput.webhook,
55-
}
56-
}
57-
58-
if (provider === 'microsoft-teams') {
59-
const providerData = (starterOutput as any)[provider] || webhookData[provider] || {}
60-
const payloadSource = providerData?.message?.raw || webhookData.payload || {}
61-
return {
62-
...payloadSource,
63-
[provider]: providerData,
64-
webhook: starterOutput.webhook,
65-
}
66-
}
67-
68-
if (provider === 'airtable') {
69-
return starterOutput
70-
}
71-
72-
const result: any = {
73-
input: starterOutput.input,
74-
}
75-
76-
for (const [key, value] of Object.entries(starterOutput)) {
77-
if (key !== 'webhook' && key !== provider) {
78-
result[key] = value
79-
}
80-
}
81-
82-
if (provider && starterOutput[provider]) {
83-
const providerData = starterOutput[provider]
84-
85-
for (const [key, value] of Object.entries(providerData)) {
86-
if (typeof value === 'object' && value !== null) {
87-
if (!result[key]) {
88-
result[key] = value
89-
}
90-
}
91-
}
92-
93-
result[provider] = providerData
94-
} else if (provider && webhookData[provider]) {
95-
const providerData = webhookData[provider]
96-
97-
for (const [key, value] of Object.entries(providerData)) {
98-
if (typeof value === 'object' && value !== null) {
99-
if (!result[key]) {
100-
result[key] = value
101-
}
102-
}
103-
}
104-
105-
result[provider] = providerData
106-
} else if (
107-
provider &&
108-
(provider === 'gmail' || provider === 'outlook') &&
109-
webhookData.payload?.email
110-
) {
111-
const emailData = webhookData.payload.email
112-
113-
for (const [key, value] of Object.entries(emailData)) {
114-
if (!result[key]) {
115-
result[key] = value
116-
}
117-
}
118-
119-
result.email = emailData
120-
121-
if (webhookData.payload.timestamp) {
122-
result.timestamp = webhookData.payload.timestamp
123-
}
124-
}
125-
126-
if (starterOutput.webhook) result.webhook = starterOutput.webhook
127-
128-
return result
44+
const { webhook, workflowId, ...cleanOutput } = starterOutput
45+
return cleanOutput
12946
}
13047

13148
return starterOutput

apps/sim/lib/webhooks/utils.server.ts

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,6 @@ export async function formatWebhookInput(
749749
}
750750
}
751751

752-
// Fallback for unknown Telegram update types
753752
logger.warn('Unknown Telegram update type', {
754753
updateId: body.update_id,
755754
bodyKeys: Object.keys(body || {}),
@@ -778,7 +777,6 @@ export async function formatWebhookInput(
778777

779778
if (foundWebhook.provider === 'twilio_voice') {
780779
return {
781-
// Root-level properties matching trigger outputs for easy access
782780
callSid: body.CallSid,
783781
accountSid: body.AccountSid,
784782
from: body.From,
@@ -792,8 +790,6 @@ export async function formatWebhookInput(
792790
speechResult: body.SpeechResult,
793791
recordingUrl: body.RecordingUrl,
794792
recordingSid: body.RecordingSid,
795-
796-
// Additional fields from Twilio payload
797793
called: body.Called,
798794
caller: body.Caller,
799795
toCity: body.ToCity,
@@ -830,14 +826,48 @@ export async function formatWebhookInput(
830826

831827
if (foundWebhook.provider === 'gmail') {
832828
if (body && typeof body === 'object' && 'email' in body) {
833-
return body
829+
const email = body.email as Record<string, any>
830+
const timestamp = body.timestamp
831+
return {
832+
...email,
833+
email,
834+
...(timestamp !== undefined && { timestamp }),
835+
webhook: {
836+
data: {
837+
provider: 'gmail',
838+
path: foundWebhook.path,
839+
providerConfig: foundWebhook.providerConfig,
840+
payload: body,
841+
headers: Object.fromEntries(request.headers.entries()),
842+
method: request.method,
843+
},
844+
},
845+
workflowId: foundWorkflow.id,
846+
}
834847
}
835848
return body
836849
}
837850

838851
if (foundWebhook.provider === 'outlook') {
839852
if (body && typeof body === 'object' && 'email' in body) {
840-
return body
853+
const email = body.email as Record<string, any>
854+
const timestamp = body.timestamp
855+
return {
856+
...email,
857+
email,
858+
...(timestamp !== undefined && { timestamp }),
859+
webhook: {
860+
data: {
861+
provider: 'outlook',
862+
path: foundWebhook.path,
863+
providerConfig: foundWebhook.providerConfig,
864+
payload: body,
865+
headers: Object.fromEntries(request.headers.entries()),
866+
method: request.method,
867+
},
868+
},
869+
workflowId: foundWorkflow.id,
870+
}
841871
}
842872
return body
843873
}
@@ -926,19 +956,16 @@ export async function formatWebhookInput(
926956
}
927957

928958
if (foundWebhook.provider === 'microsoft-teams') {
929-
// Check if this is a Microsoft Graph change notification
930959
if (body?.value && Array.isArray(body.value) && body.value.length > 0) {
931960
return await formatTeamsGraphNotification(body, foundWebhook, foundWorkflow, request)
932961
}
933962

934-
// Microsoft Teams outgoing webhook - Teams sending data to us
935963
const messageText = body?.text || ''
936964
const messageId = body?.id || ''
937965
const timestamp = body?.timestamp || body?.localTimestamp || ''
938966
const from = body?.from || {}
939967
const conversation = body?.conversation || {}
940968

941-
// Construct the message object
942969
const messageObj = {
943970
raw: {
944971
attachments: body?.attachments || [],
@@ -951,14 +978,12 @@ export async function formatWebhookInput(
951978
},
952979
}
953980

954-
// Construct the from object
955981
const fromObj = {
956982
id: from.id || '',
957983
name: from.name || '',
958984
aadObjectId: from.aadObjectId || '',
959985
}
960986

961-
// Construct the conversation object
962987
const conversationObj = {
963988
id: conversation.id || '',
964989
name: conversation.name || '',
@@ -968,13 +993,11 @@ export async function formatWebhookInput(
968993
conversationType: conversation.conversationType || '',
969994
}
970995

971-
// Construct the activity object
972996
const activityObj = body || {}
973997

974998
return {
975-
input: messageText, // Primary workflow input - the message text
999+
input: messageText,
9761000

977-
// Top-level properties for direct access with <microsoftteams.from.name> syntax
9781001
from: fromObj,
9791002
message: messageObj,
9801003
activity: activityObj,
@@ -995,11 +1018,9 @@ export async function formatWebhookInput(
9951018
}
9961019

9971020
if (foundWebhook.provider === 'slack') {
998-
// Slack input formatting logic - check for valid event
9991021
const event = body?.event
10001022

10011023
if (event && body?.type === 'event_callback') {
1002-
// Extract event text with fallbacks for different event types
10031024
let input = ''
10041025

10051026
if (event.text) {
@@ -1010,26 +1031,22 @@ export async function formatWebhookInput(
10101031
input = 'Slack event received'
10111032
}
10121033

1013-
// Create the event object for easier access
10141034
const eventObj = {
10151035
event_type: event.type || '',
10161036
channel: event.channel || '',
1017-
channel_name: '', // Could be resolved via additional API calls if needed
1037+
channel_name: '',
10181038
user: event.user || '',
1019-
user_name: '', // Could be resolved via additional API calls if needed
1039+
user_name: '',
10201040
text: event.text || '',
10211041
timestamp: event.ts || event.event_ts || '',
10221042
team_id: body.team_id || event.team || '',
10231043
event_id: body.event_id || '',
10241044
}
10251045

10261046
return {
1027-
input, // Primary workflow input - the event content
1047+
input,
10281048

1029-
// // // Top-level properties for backward compatibility with <blockName.event> syntax
10301049
event: eventObj,
1031-
1032-
// Keep the nested structure for the new slack.event.text syntax
10331050
slack: {
10341051
event: eventObj,
10351052
},
@@ -1047,7 +1064,6 @@ export async function formatWebhookInput(
10471064
}
10481065
}
10491066

1050-
// Fallback for unknown Slack event types
10511067
logger.warn('Unknown Slack event type', {
10521068
type: body?.type,
10531069
hasEvent: !!body?.event,
@@ -1283,9 +1299,7 @@ export async function formatWebhookInput(
12831299
}
12841300

12851301
return {
1286-
// Expose raw GitHub payload at the root
12871302
...body,
1288-
// Include webhook metadata alongside
12891303
webhook: {
12901304
data: {
12911305
provider: 'github',
@@ -1364,10 +1378,7 @@ export async function formatWebhookInput(
13641378
}
13651379

13661380
if (foundWebhook.provider === 'linear') {
1367-
// Linear webhook payload structure:
1368-
// { action, type, webhookId, webhookTimestamp, organizationId, createdAt, actor, data, updatedFrom? }
13691381
return {
1370-
// Extract top-level fields from Linear payload
13711382
action: body.action || '',
13721383
type: body.type || '',
13731384
webhookId: body.webhookId || '',
@@ -1377,8 +1388,6 @@ export async function formatWebhookInput(
13771388
actor: body.actor || null,
13781389
data: body.data || null,
13791390
updatedFrom: body.updatedFrom || null,
1380-
1381-
// Keep webhook metadata
13821391
webhook: {
13831392
data: {
13841393
provider: 'linear',
@@ -1393,7 +1402,6 @@ export async function formatWebhookInput(
13931402
}
13941403
}
13951404

1396-
// Jira webhook format
13971405
if (foundWebhook.provider === 'jira') {
13981406
const { extractIssueData, extractCommentData, extractWorklogData } = await import(
13991407
'@/triggers/jira/utils'
@@ -1445,7 +1453,6 @@ export async function formatWebhookInput(
14451453
}
14461454

14471455
if (foundWebhook.provider === 'calendly') {
1448-
// Calendly webhook payload format matches the trigger outputs
14491456
return {
14501457
event: body.event,
14511458
created_at: body.created_at,
@@ -1466,9 +1473,7 @@ export async function formatWebhookInput(
14661473
}
14671474

14681475
if (foundWebhook.provider === 'circleback') {
1469-
// Circleback webhook payload - meeting notes, action items, transcript
14701476
return {
1471-
// Top-level fields from Circleback payload
14721477
id: body.id,
14731478
name: body.name,
14741479
createdAt: body.createdAt,
@@ -1482,10 +1487,7 @@ export async function formatWebhookInput(
14821487
actionItems: body.actionItems || [],
14831488
transcript: body.transcript || [],
14841489
insights: body.insights || {},
1485-
1486-
// Full meeting object for convenience
14871490
meeting: body,
1488-
14891491
webhook: {
14901492
data: {
14911493
provider: 'circleback',
@@ -1501,9 +1503,7 @@ export async function formatWebhookInput(
15011503
}
15021504

15031505
if (foundWebhook.provider === 'grain') {
1504-
// Grain webhook payload structure: { type, user_id, data: {...} }
15051506
return {
1506-
// Top-level fields from Grain payload
15071507
type: body.type,
15081508
user_id: body.user_id,
15091509
data: body.data || {},

0 commit comments

Comments
 (0)