MCPcopy
hub / github.com/simstudioai/sim / handleWebhookPost

Function handleWebhookPost

apps/sim/app/api/webhooks/trigger/[path]/route.ts:68–239  ·  view source on GitHub ↗
(
  request: NextRequest,
  context: { params: Promise<{ path: string }> }
)

Source from the content-addressed store, hash-verified

66)
67
68async function handleWebhookPost(
69 request: NextRequest,
70 context: { params: Promise<{ path: string }> }
71): Promise<NextResponse> {
72 const receivedAt = Date.now()
73 /**
74 * Slack signs every interactive request with the originating interaction time.
75 * Capturing it lets the executor surface the true trigger_id age (the window
76 * that expires at 3s) instead of only the in-workflow block timings.
77 */
78 const slackRequestTimestamp = request.headers.get('x-slack-request-timestamp')
79 const triggerTimestampMs = slackRequestTimestamp
80 ? Number(slackRequestTimestamp) * 1000
81 : undefined
82
83 const requestId = generateRequestId()
84 const parsed = await parseRequest(webhookTriggerPostContract, request, context)
85 if (!parsed.success) return parsed.response
86 const { path } = parsed.data.params
87
88 const earlyChallenge = await handleProviderChallenges({}, request, requestId, path)
89 if (earlyChallenge) {
90 return earlyChallenge
91 }
92
93 const parseResult = await parseWebhookBody(request, requestId)
94
95 // Check if parseWebhookBody returned an error response
96 if (parseResult instanceof NextResponse) {
97 return parseResult
98 }
99
100 const { body, rawBody } = parseResult
101
102 const challengeResponse = await handleProviderChallenges(body, request, requestId, path, rawBody)
103 if (challengeResponse) {
104 return challengeResponse
105 }
106
107 // Find all webhooks for this path (supports credential set fan-out where multiple webhooks share a path)
108 const allWebhooksForPath = await findAllWebhooksForPath({ requestId, path })
109
110 // Internal trigger providers (sim, table) are fired in-process, never over
111 // HTTP. Their rows still register a path, so reject deliveries here to keep
112 // forged events out.
113 const webhooksForPath = allWebhooksForPath.filter(
114 ({ webhook: foundWebhook }) => !isInternalTriggerProvider(foundWebhook.provider)
115 )
116
117 if (allWebhooksForPath.length > 0 && webhooksForPath.length === 0) {
118 logger.warn(`[${requestId}] Rejected HTTP delivery to internal trigger path: ${path}`)
119 return new NextResponse('Not Found', { status: 404 })
120 }
121
122 if (webhooksForPath.length === 0) {
123 const verificationResponse = await handlePreLookupWebhookVerification(
124 request.method,
125 body as Record<string, unknown> | undefined,

Callers 1

route.tsFile · 0.85

Calls 15

generateRequestIdFunction · 0.90
parseRequestFunction · 0.90
handleProviderChallengesFunction · 0.90
parseWebhookBodyFunction · 0.90
findAllWebhooksForPathFunction · 0.90
verifyProviderAuthFunction · 0.90
blockExistsInDeploymentFunction · 0.90

Tested by

no test coverage detected