@@ -4,10 +4,13 @@ import { generateRequestId } from '@/lib/core/utils/request'
44import {
55 checkWebhookPreprocessing ,
66 findAllWebhooksForPath ,
7+ formatProviderErrorResponse ,
8+ handlePreDeploymentVerification ,
79 handleProviderChallenges ,
810 handleProviderReachabilityTest ,
911 parseWebhookBody ,
1012 queueWebhookExecution ,
13+ shouldSkipWebhookEvent ,
1114 verifyProviderAuth ,
1215} from '@/lib/webhooks/processor'
1316import { blockExistsInDeployment } from '@/lib/workflows/persistence/utils'
@@ -22,19 +25,7 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{
2225 const requestId = generateRequestId ( )
2326 const { path } = await params
2427
25- // Handle Microsoft Graph subscription validation
26- const url = new URL ( request . url )
27- const validationToken = url . searchParams . get ( 'validationToken' )
28-
29- if ( validationToken ) {
30- logger . info ( `[${ requestId } ] Microsoft Graph subscription validation for path: ${ path } ` )
31- return new NextResponse ( validationToken , {
32- status : 200 ,
33- headers : { 'Content-Type' : 'text/plain' } ,
34- } )
35- }
36-
37- // Handle other GET-based verifications if needed
28+ // Handle provider-specific GET verifications (Microsoft Graph, WhatsApp, etc.)
3829 const challengeResponse = await handleProviderChallenges ( { } , request , requestId , path )
3930 if ( challengeResponse ) {
4031 return challengeResponse
@@ -50,26 +41,10 @@ export async function POST(
5041 const requestId = generateRequestId ( )
5142 const { path } = await params
5243
53- // Log ALL incoming webhook requests for debugging
54- logger . info ( `[${ requestId } ] Incoming webhook request` , {
55- path,
56- method : request . method ,
57- headers : Object . fromEntries ( request . headers . entries ( ) ) ,
58- } )
59-
60- // Handle Microsoft Graph subscription validation (some environments send POST with validationToken)
61- try {
62- const url = new URL ( request . url )
63- const validationToken = url . searchParams . get ( 'validationToken' )
64- if ( validationToken ) {
65- logger . info ( `[${ requestId } ] Microsoft Graph subscription validation (POST) for path: ${ path } ` )
66- return new NextResponse ( validationToken , {
67- status : 200 ,
68- headers : { 'Content-Type' : 'text/plain' } ,
69- } )
70- }
71- } catch {
72- // ignore URL parsing errors; proceed to normal handling
44+ // Handle provider challenges before body parsing (Microsoft Graph validationToken, etc.)
45+ const earlyChallenge = await handleProviderChallenges ( { } , request , requestId , path )
46+ if ( earlyChallenge ) {
47+ return earlyChallenge
7348 }
7449
7550 const parseResult = await parseWebhookBody ( request , requestId )
@@ -99,23 +74,6 @@ export async function POST(
9974 const responses : NextResponse [ ] = [ ]
10075
10176 for ( const { webhook : foundWebhook , workflow : foundWorkflow } of webhooksForPath ) {
102- // Log HubSpot webhook details for debugging
103- if ( foundWebhook . provider === 'hubspot' ) {
104- const events = Array . isArray ( body ) ? body : [ body ]
105- const firstEvent = events [ 0 ]
106-
107- logger . info ( `[${ requestId } ] HubSpot webhook received` , {
108- path,
109- subscriptionType : firstEvent ?. subscriptionType ,
110- objectId : firstEvent ?. objectId ,
111- portalId : firstEvent ?. portalId ,
112- webhookId : foundWebhook . id ,
113- workflowId : foundWorkflow . id ,
114- triggerId : foundWebhook . providerConfig ?. triggerId ,
115- eventCount : events . length ,
116- } )
117- }
118-
11977 const authError = await verifyProviderAuth (
12078 foundWebhook ,
12179 foundWorkflow ,
@@ -162,32 +120,19 @@ export async function POST(
162120 continue
163121 }
164122
165- if ( foundWebhook . provider === 'microsoft-teams' ) {
166- return NextResponse . json (
167- {
168- type : 'message' ,
169- text : 'An unexpected error occurred during preprocessing' ,
170- } ,
171- { status : 500 }
172- )
173- }
174-
175- return NextResponse . json (
176- { error : 'An unexpected error occurred during preprocessing' } ,
177- { status : 500 }
123+ return formatProviderErrorResponse (
124+ foundWebhook ,
125+ 'An unexpected error occurred during preprocessing' ,
126+ 500
178127 )
179128 }
180129
181130 if ( foundWebhook . blockId ) {
182131 const blockExists = await blockExistsInDeployment ( foundWorkflow . id , foundWebhook . blockId )
183132 if ( ! blockExists ) {
184- // For Grain, if block doesn't exist in deployment, treat as verification request
185- // Grain validates webhook URLs during creation, and the block may not be deployed yet
186- if ( foundWebhook . provider === 'grain' ) {
187- logger . info (
188- `[${ requestId } ] Grain webhook verification - block not in deployment, returning 200 OK`
189- )
190- return NextResponse . json ( { status : 'ok' , message : 'Webhook endpoint verified' } )
133+ const preDeploymentResponse = handlePreDeploymentVerification ( foundWebhook , requestId )
134+ if ( preDeploymentResponse ) {
135+ return preDeploymentResponse
191136 }
192137
193138 logger . info (
@@ -200,20 +145,8 @@ export async function POST(
200145 }
201146 }
202147
203- if ( foundWebhook . provider === 'stripe' ) {
204- const providerConfig = ( foundWebhook . providerConfig as Record < string , any > ) || { }
205- const eventTypes = providerConfig . eventTypes
206-
207- if ( eventTypes && Array . isArray ( eventTypes ) && eventTypes . length > 0 ) {
208- const eventType = body ?. type
209-
210- if ( eventType && ! eventTypes . includes ( eventType ) ) {
211- logger . info (
212- `[${ requestId } ] Stripe event type '${ eventType } ' not in allowed list for webhook ${ foundWebhook . id } , skipping`
213- )
214- continue
215- }
216- }
148+ if ( shouldSkipWebhookEvent ( foundWebhook , body , requestId ) ) {
149+ continue
217150 }
218151
219152 const response = await queueWebhookExecution ( foundWebhook , foundWorkflow , body , request , {
0 commit comments