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

Function parseWebhookBody

apps/sim/lib/webhooks/processor.ts:86–143  ·  view source on GitHub ↗
(
  request: NextRequest,
  requestId: string
)

Source from the content-addressed store, hash-verified

84const WEBHOOK_BODY_LABEL = 'Webhook request body'
85
86export async function parseWebhookBody(
87 request: NextRequest,
88 requestId: string
89): Promise<{ body: unknown; rawBody: string } | NextResponse> {
90 let rawBody: string | null = null
91 try {
92 assertContentLengthWithinLimit(request.headers, WEBHOOK_MAX_BODY_BYTES, WEBHOOK_BODY_LABEL)
93
94 const buffer = await readStreamToBufferWithLimit(request.clone().body, {
95 maxBytes: WEBHOOK_MAX_BODY_BYTES,
96 label: WEBHOOK_BODY_LABEL,
97 })
98 rawBody = new TextDecoder().decode(buffer)
99
100 if (!rawBody || rawBody.length === 0) {
101 return { body: {}, rawBody: '' }
102 }
103 } catch (bodyError) {
104 if (isPayloadSizeLimitError(bodyError)) {
105 logger.warn(`[${requestId}] Rejected oversized webhook body`, {
106 maxBytes: WEBHOOK_MAX_BODY_BYTES,
107 observedBytes: bodyError.observedBytes,
108 })
109 return new NextResponse('Request body too large', { status: 413 })
110 }
111 logger.error(`[${requestId}] Failed to read request body`, {
112 error: toError(bodyError).message,
113 })
114 return new NextResponse('Failed to read request body', { status: 400 })
115 }
116
117 let body: unknown
118 try {
119 const contentType = request.headers.get('content-type') || ''
120
121 if (contentType.includes('application/x-www-form-urlencoded')) {
122 const formData = new URLSearchParams(rawBody)
123 const payloadString = formData.get('payload')
124
125 if (payloadString) {
126 body = JSON.parse(payloadString)
127 } else {
128 body = Object.fromEntries(formData.entries())
129 }
130 } else {
131 body = JSON.parse(rawBody)
132 }
133 } catch (parseError) {
134 logger.error(`[${requestId}] Failed to parse webhook body`, {
135 error: toError(parseError).message,
136 contentType: request.headers.get('content-type'),
137 bodyPreview: `${rawBody?.slice(0, 100)}...`,
138 })
139 return new NextResponse('Invalid payload format', { status: 400 })
140 }
141
142 return { body, rawBody }
143}

Callers 1

handleWebhookPostFunction · 0.90

Calls 8

isPayloadSizeLimitErrorFunction · 0.90
toErrorFunction · 0.90
errorMethod · 0.80
parseMethod · 0.80
warnMethod · 0.65
getMethod · 0.65

Tested by

no test coverage detected