Skip to content

Commit 1395108

Browse files
Adam GoughAdam Gough
authored andcommitted
test
1 parent 6d26684 commit 1395108

2 files changed

Lines changed: 151 additions & 97 deletions

File tree

apps/sim/executor/resolver/resolver.ts

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,25 @@ function resolveFromWebhookPayload(container: any, property: string): any {
2323
return undefined
2424
}
2525

26+
// Global fallback: scan any block state's webhook payload for the property (e.g., when referencing
27+
// a GitHub field from a non-trigger block). This allows <github1.sender> to resolve even if the
28+
// referenced block doesn't carry the webhook metadata on its own output.
29+
function resolveFromAnyWebhookPayload(context: ExecutionContext | undefined, property: string): any {
30+
try {
31+
if (!context) return undefined
32+
for (const state of context.blockStates.values()) {
33+
const payload = (state as any)?.output?.webhook?.data?.payload
34+
if (payload && typeof payload === 'object' && Object.prototype.hasOwnProperty.call(payload, property)) {
35+
return payload[property]
36+
}
37+
}
38+
} catch (_) {
39+
// ignore
40+
}
41+
return undefined
42+
}
43+
44+
2645
/**
2746
* Helper function to resolve property access
2847
*/
@@ -49,13 +68,44 @@ export class InputResolver {
4968
// Create maps for efficient lookups
5069
this.blockById = new Map(workflow.blocks.map((block) => [block.id, block]))
5170

52-
// Initialize the normalized name map
53-
this.blockByNormalizedName = new Map(
54-
workflow.blocks.map((block) => [
55-
block.metadata?.name ? this.normalizeBlockName(block.metadata.name) : block.id,
56-
block,
57-
])
58-
)
71+
// Initialize the normalized name map with trigger-preference for duplicate names
72+
this.blockByNormalizedName = new Map()
73+
const isTriggerDef = (b: SerializedBlock | undefined) =>
74+
!!b && (b.metadata?.category === 'triggers' || b.config?.params?.triggerMode === true)
75+
76+
for (const block of workflow.blocks) {
77+
const key = block.metadata?.name ? this.normalizeBlockName(block.metadata.name) : block.id
78+
const existing = this.blockByNormalizedName.get(key)
79+
if (!existing) {
80+
this.blockByNormalizedName.set(key, block)
81+
} else {
82+
// Prefer trigger blocks when duplicate names exist
83+
if (!isTriggerDef(existing) && isTriggerDef(block)) {
84+
this.blockByNormalizedName.set(key, block)
85+
}
86+
}
87+
}
88+
89+
// Add provider-index aliases for trigger blocks to ensure intuitive references like <github1>
90+
// regardless of the block's display name (e.g., "GitHub Webhook 1"). Only applies to triggers.
91+
const providerToBlocks: Record<string, SerializedBlock[]> = {}
92+
for (const block of workflow.blocks) {
93+
if (!isTriggerDef(block)) continue
94+
const typeId = (block.metadata?.id || '').toLowerCase()
95+
// Detect GitHub triggers by id containing 'github' (covers 'github_webhook')
96+
if (typeId.includes('github')) {
97+
providerToBlocks.github = providerToBlocks.github || []
98+
providerToBlocks.github.push(block)
99+
}
100+
}
101+
102+
// Register aliases like 'github1', 'github2', ...
103+
if (providerToBlocks.github && providerToBlocks.github.length > 0) {
104+
providerToBlocks.github.forEach((b, idx) => {
105+
const alias = `github${idx + 1}`
106+
this.blockByNormalizedName.set(alias, b)
107+
})
108+
}
59109

60110
// Add special handling for the starter block - allow referencing it as "start"
61111
const starterBlock = workflow.blocks.find((block) => block.metadata?.id === 'starter')
@@ -573,11 +623,13 @@ export class InputResolver {
573623

574624
replacementValue = arrayValue[index]
575625
} else {
576-
// Regular property access with webhook metadata fallback only
626+
// Regular property access with webhook metadata fallback; then global webhook payload fallback
577627
let nextValue = resolvePropertyAccess(replacementValue, part)
578628
if (nextValue === undefined) {
579-
// Fallback to webhook metadata payload if present
580629
nextValue = resolveFromWebhookPayload(replacementValue, part)
630+
if (nextValue === undefined) {
631+
nextValue = resolveFromAnyWebhookPayload(context, part)
632+
}
581633
}
582634
replacementValue = nextValue
583635
}
@@ -781,11 +833,13 @@ export class InputResolver {
781833

782834
replacementValue = arrayValue[index]
783835
} else {
784-
// Regular property access with webhook metadata fallback only
836+
// Regular property access with webhook metadata fallback; then global webhook payload fallback
785837
let nextValue = resolvePropertyAccess(replacementValue, part)
786838
if (nextValue === undefined) {
787-
// Fallback to webhook metadata payload if present
788839
nextValue = resolveFromWebhookPayload(replacementValue, part)
840+
if (nextValue === undefined) {
841+
nextValue = resolveFromAnyWebhookPayload(context, part)
842+
}
789843
}
790844
replacementValue = nextValue
791845
}

apps/sim/lib/webhooks/utils.ts

Lines changed: 86 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -519,92 +519,92 @@ export function formatWebhookInput(
519519
}
520520

521521
if (foundWebhook.provider === 'github') {
522-
// // GitHub webhook input formatting logic
523-
// const eventType = request.headers.get('x-github-event') || 'unknown'
524-
// const delivery = request.headers.get('x-github-delivery') || ''
525-
526-
// // Extract common GitHub properties
527-
// const repository = body?.repository || {}
528-
// const sender = body?.sender || {}
529-
// const action = body?.action || ''
530-
531-
// // Build GitHub-specific variables based on the trigger config outputs
532-
// const githubData = {
533-
// // Event metadata
534-
// event_type: eventType,
535-
// action: action,
536-
// delivery_id: delivery,
537-
538-
// // Repository information (avoid 'repository' to prevent conflict with the object)
539-
// repository_full_name: repository.full_name || '',
540-
// repository_name: repository.name || '',
541-
// repository_owner: repository.owner?.login || '',
542-
// repository_id: repository.id || '',
543-
// repository_url: repository.html_url || '',
544-
545-
// // Sender information (avoid 'sender' to prevent conflict with the object)
546-
// sender_login: sender.login || '',
547-
// sender_id: sender.id || '',
548-
// sender_type: sender.type || '',
549-
// sender_url: sender.html_url || '',
550-
551-
// // Event-specific data
552-
// ...(body?.ref && {
553-
// ref: body.ref,
554-
// branch: body.ref?.replace('refs/heads/', '') || '',
555-
// }),
556-
// ...(body?.before && { before: body.before }),
557-
// ...(body?.after && { after: body.after }),
558-
// ...(body?.commits && {
559-
// commits: JSON.stringify(body.commits),
560-
// commit_count: body.commits.length || 0,
561-
// }),
562-
// ...(body?.head_commit && {
563-
// commit_message: body.head_commit.message || '',
564-
// commit_author: body.head_commit.author?.name || '',
565-
// commit_sha: body.head_commit.id || '',
566-
// commit_url: body.head_commit.url || '',
567-
// }),
568-
// ...(body?.pull_request && {
569-
// pull_request: JSON.stringify(body.pull_request),
570-
// pr_number: body.pull_request.number || '',
571-
// pr_title: body.pull_request.title || '',
572-
// pr_state: body.pull_request.state || '',
573-
// pr_url: body.pull_request.html_url || '',
574-
// }),
575-
// ...(body?.issue && {
576-
// issue: JSON.stringify(body.issue),
577-
// issue_number: body.issue.number || '',
578-
// issue_title: body.issue.title || '',
579-
// issue_state: body.issue.state || '',
580-
// issue_url: body.issue.html_url || '',
581-
// }),
582-
// ...(body?.comment && {
583-
// comment: JSON.stringify(body.comment),
584-
// comment_body: body.comment.body || '',
585-
// comment_url: body.comment.html_url || '',
586-
// }),
587-
// }
588-
589-
// // Set input based on event type for workflow processing
590-
// let input = ''
591-
// switch (eventType) {
592-
// case 'push':
593-
// input = `Push to ${githubData.branch || githubData.ref}: ${githubData.commit_message || 'No commit message'}`
594-
// break
595-
// case 'pull_request':
596-
// input = `${action} pull request: ${githubData.pr_title || 'No title'}`
597-
// break
598-
// case 'issues':
599-
// input = `${action} issue: ${githubData.issue_title || 'No title'}`
600-
// break
601-
// case 'issue_comment':
602-
// case 'pull_request_review_comment':
603-
// input = `Comment ${action}: ${githubData.comment_body?.slice(0, 100) || 'No comment body'}${(githubData.comment_body?.length || 0) > 100 ? '...' : ''}`
604-
// break
605-
// default:
606-
// input = `GitHub ${eventType} event${action ? ` (${action})` : ''}`
607-
// }
522+
// GitHub webhook input formatting logic
523+
const eventType = request.headers.get('x-github-event') || 'unknown'
524+
const delivery = request.headers.get('x-github-delivery') || ''
525+
526+
// Extract common GitHub properties
527+
const repository = body?.repository || {}
528+
const sender = body?.sender || {}
529+
const action = body?.action || ''
530+
531+
// Build GitHub-specific variables based on the trigger config outputs
532+
const githubData = {
533+
// Event metadata
534+
event_type: eventType,
535+
action: action,
536+
delivery_id: delivery,
537+
538+
// Repository information (avoid 'repository' to prevent conflict with the object)
539+
repository_full_name: repository.full_name || '',
540+
repository_name: repository.name || '',
541+
repository_owner: repository.owner?.login || '',
542+
repository_id: repository.id || '',
543+
repository_url: repository.html_url || '',
544+
545+
// Sender information (avoid 'sender' to prevent conflict with the object)
546+
sender_login: sender.login || '',
547+
sender_id: sender.id || '',
548+
sender_type: sender.type || '',
549+
sender_url: sender.html_url || '',
550+
551+
// Event-specific data
552+
...(body?.ref && {
553+
ref: body.ref,
554+
branch: body.ref?.replace('refs/heads/', '') || '',
555+
}),
556+
...(body?.before && { before: body.before }),
557+
...(body?.after && { after: body.after }),
558+
...(body?.commits && {
559+
commits: JSON.stringify(body.commits),
560+
commit_count: body.commits.length || 0,
561+
}),
562+
...(body?.head_commit && {
563+
commit_message: body.head_commit.message || '',
564+
commit_author: body.head_commit.author?.name || '',
565+
commit_sha: body.head_commit.id || '',
566+
commit_url: body.head_commit.url || '',
567+
}),
568+
...(body?.pull_request && {
569+
pull_request: JSON.stringify(body.pull_request),
570+
pr_number: body.pull_request.number || '',
571+
pr_title: body.pull_request.title || '',
572+
pr_state: body.pull_request.state || '',
573+
pr_url: body.pull_request.html_url || '',
574+
}),
575+
...(body?.issue && {
576+
issue: JSON.stringify(body.issue),
577+
issue_number: body.issue.number || '',
578+
issue_title: body.issue.title || '',
579+
issue_state: body.issue.state || '',
580+
issue_url: body.issue.html_url || '',
581+
}),
582+
...(body?.comment && {
583+
comment: JSON.stringify(body.comment),
584+
comment_body: body.comment.body || '',
585+
comment_url: body.comment.html_url || '',
586+
}),
587+
}
588+
589+
// Set input based on event type for workflow processing
590+
let input = ''
591+
switch (eventType) {
592+
case 'push':
593+
input = `Push to ${githubData.branch || githubData.ref}: ${githubData.commit_message || 'No commit message'}`
594+
break
595+
case 'pull_request':
596+
input = `${action} pull request: ${githubData.pr_title || 'No title'}`
597+
break
598+
case 'issues':
599+
input = `${action} issue: ${githubData.issue_title || 'No title'}`
600+
break
601+
case 'issue_comment':
602+
case 'pull_request_review_comment':
603+
input = `Comment ${action}: ${githubData.comment_body?.slice(0, 100) || 'No comment body'}${(githubData.comment_body?.length || 0) > 100 ? '...' : ''}`
604+
break
605+
default:
606+
input = `GitHub ${eventType} event${action ? ` (${action})` : ''}`
607+
}
608608

609609
return {
610610
// Expose raw GitHub payload at the root

0 commit comments

Comments
 (0)