@@ -277,6 +277,7 @@ app.get("/models", authMiddleware, async (req, res) => {
277277} ) ;
278278
279279app . post ( "/fal-ai/webhook/train" , async ( req , res ) => {
280+ console . log ( "====================Received training webhook====================" ) ;
280281 console . log ( "Received training webhook:" , req . body ) ;
281282 const requestId = req . body . request_id as string ;
282283
@@ -287,81 +288,122 @@ app.post("/fal-ai/webhook/train", async (req, res) => {
287288 } ,
288289 } ) ;
289290
291+ console . log ( "Found model:" , model ) ;
292+
290293 if ( ! model ) {
291294 console . error ( "No model found for requestId:" , requestId ) ;
292295 res . status ( 404 ) . json ( { message : "Model not found" } ) ;
293296 return ;
294297 }
295298
296- console . log ( "Found model:" , model ) ;
297-
298- const result = await fal . queue . result ( "fal-ai/flux-lora" , {
299- requestId,
300- } ) ;
301-
302- console . log ( "Fal.ai result:" , result ) ;
303-
304- // check if the user has enough credits
305- const credits = await prismaClient . userCredit . findUnique ( {
306- where : {
307- userId : model . userId ,
308- } ,
309- } ) ;
310-
311- console . log ( "User credits:" , credits ) ;
312-
313- if ( ( credits ?. amount ?? 0 ) < TRAIN_MODEL_CREDITS ) {
314- console . error ( "Not enough credits for user:" , model . userId ) ;
315- res . status ( 411 ) . json ( {
316- message : "Not enough credits" ,
299+ // Handle error case
300+ if ( req . body . status === "ERROR" ) {
301+ console . error ( "Training error:" , req . body . error ) ;
302+ await prismaClient . model . updateMany ( {
303+ where : {
304+ falAiRequestId : requestId ,
305+ } ,
306+ data : {
307+ trainingStatus : "Failed" ,
308+ } ,
309+ } ) ;
310+
311+ res . json ( {
312+ message : "Error recorded" ,
317313 } ) ;
318314 return ;
319315 }
320316
321- try {
322- // Use type assertion to bypass TypeScript type checking
323- const resultData = result . data as any ;
324- const loraUrl = resultData . diffusers_lora_file . url ;
317+ // Check for both "COMPLETED" and "OK" status
318+ if ( req . body . status === "COMPLETED" || req . body . status === "OK" ) {
319+ try {
320+ // Check if we have payload data directly in the webhook
321+ let loraUrl ;
322+ if ( req . body . payload && req . body . payload . diffusers_lora_file && req . body . payload . diffusers_lora_file . url ) {
323+ // Extract directly from webhook payload
324+ loraUrl = req . body . payload . diffusers_lora_file . url ;
325+ console . log ( "Using lora URL from webhook payload:" , loraUrl ) ;
326+ } else {
327+ // Fetch result from fal.ai if not in payload
328+ console . log ( "Fetching result from fal.ai" ) ;
329+ const result = await fal . queue . result ( "fal-ai/flux-lora-fast-training" , {
330+ requestId,
331+ } ) ;
332+ console . log ( "Fal.ai result:" , result ) ;
333+ const resultData = result . data as any ;
334+ loraUrl = resultData . diffusers_lora_file . url ;
335+ }
336+
337+ // check if the user has enough credits
338+ const credits = await prismaClient . userCredit . findUnique ( {
339+ where : {
340+ userId : model . userId ,
341+ } ,
342+ } ) ;
325343
326- const { imageUrl } = await falAiModel . generateImageSync ( loraUrl ) ;
344+ console . log ( "User credits:" , credits ) ;
345+
346+ if ( ( credits ?. amount ?? 0 ) < TRAIN_MODEL_CREDITS ) {
347+ console . error ( "Not enough credits for user:" , model . userId ) ;
348+ res . status ( 411 ) . json ( {
349+ message : "Not enough credits" ,
350+ } ) ;
351+ return ;
352+ }
353+
354+ console . log ( "Generating preview image with lora URL:" , loraUrl ) ;
355+ const { imageUrl } = await falAiModel . generateImageSync ( loraUrl ) ;
356+
357+ console . log ( "Generated preview image:" , imageUrl ) ;
358+
359+ await prismaClient . model . updateMany ( {
360+ where : {
361+ falAiRequestId : requestId ,
362+ } ,
363+ data : {
364+ trainingStatus : "Generated" ,
365+ tensorPath : loraUrl ,
366+ thumbnail : imageUrl ,
367+ } ,
368+ } ) ;
327369
328- console . log ( "Generated preview image:" , imageUrl ) ;
370+ await prismaClient . userCredit . update ( {
371+ where : {
372+ userId : model . userId ,
373+ } ,
374+ data : {
375+ amount : { decrement : TRAIN_MODEL_CREDITS } ,
376+ } ,
377+ } ) ;
329378
379+ console . log ( "Updated model and decremented credits for user:" , model . userId ) ;
380+ } catch ( error ) {
381+ console . error ( "Error processing webhook:" , error ) ;
382+ await prismaClient . model . updateMany ( {
383+ where : {
384+ falAiRequestId : requestId ,
385+ } ,
386+ data : {
387+ trainingStatus : "Failed" ,
388+ } ,
389+ } ) ;
390+ }
391+ } else {
392+ // For any other status, keep it as Pending
393+ console . log ( "Updating model status to: Pending" ) ;
330394 await prismaClient . model . updateMany ( {
331395 where : {
332396 falAiRequestId : requestId ,
333397 } ,
334398 data : {
335- trainingStatus : "Generated" ,
336- tensorPath : loraUrl ,
337- thumbnail : imageUrl ,
338- } ,
339- } ) ;
340-
341- await prismaClient . userCredit . update ( {
342- where : {
343- userId : model . userId ,
344- } ,
345- data : {
346- amount : { decrement : TRAIN_MODEL_CREDITS } ,
399+ trainingStatus : "Pending" ,
347400 } ,
348401 } ) ;
349-
350- console . log (
351- "Updated model and decremented credits for user:" ,
352- model . userId
353- ) ;
354-
355- res . json ( {
356- message : "Webhook processed successfully" ,
357- } ) ;
358- } catch ( error ) {
359- console . error ( "Error processing webhook:" , error ) ;
360- res . status ( 500 ) . json ( {
361- message : "Error processing webhook" ,
362- error : error instanceof Error ? error . message : "Unknown error" ,
363- } ) ;
364402 }
403+
404+ res . json ( {
405+ message : "Webhook processed successfully" ,
406+ } ) ;
365407} ) ;
366408
367409app . post ( "/fal-ai/webhook/image" , async ( req , res ) => {
0 commit comments