( foundWebhook: PolledWebhookRecord, foundWorkflow: PolledWorkflowRecord, body: Record<string, unknown> | object, requestId: string )
| 738 | * admission control, preprocessing, block existence check, and queue execution. |
| 739 | */ |
| 740 | export async function processPolledWebhookEvent( |
| 741 | foundWebhook: PolledWebhookRecord, |
| 742 | foundWorkflow: PolledWorkflowRecord, |
| 743 | body: Record<string, unknown> | object, |
| 744 | requestId: string |
| 745 | ): Promise<PolledWebhookEventResult> { |
| 746 | if (!foundWebhook.provider) { |
| 747 | return { success: false, error: 'Webhook has no provider', statusCode: 400 } |
| 748 | } |
| 749 | const provider = foundWebhook.provider |
| 750 | |
| 751 | const ticket = tryAdmit() |
| 752 | if (!ticket) { |
| 753 | logger.warn(`[${requestId}] Admission gate rejected polled webhook event`) |
| 754 | return { success: false, error: 'Server at capacity', statusCode: 429 } |
| 755 | } |
| 756 | |
| 757 | try { |
| 758 | const preprocessResult = await checkWebhookPreprocessing(foundWorkflow, foundWebhook, requestId) |
| 759 | if (preprocessResult.error) { |
| 760 | const errorResponse = preprocessResult.error |
| 761 | const statusCode = errorResponse.status |
| 762 | const errorBody = await errorResponse.json().catch(() => ({})) |
| 763 | const errorMessage = errorBody.error ?? 'Preprocessing failed' |
| 764 | logger.warn(`[${requestId}] Polled webhook preprocessing failed`, { |
| 765 | statusCode, |
| 766 | error: errorMessage, |
| 767 | }) |
| 768 | return { success: false, error: errorMessage, statusCode } |
| 769 | } |
| 770 | |
| 771 | if (foundWebhook.blockId) { |
| 772 | const blockExists = await blockExistsInDeployment(foundWorkflow.id, foundWebhook.blockId) |
| 773 | if (!blockExists) { |
| 774 | logger.info( |
| 775 | `[${requestId}] Trigger block ${foundWebhook.blockId} not found in deployment for workflow ${foundWorkflow.id}` |
| 776 | ) |
| 777 | return { success: false, error: 'Trigger block not found in deployment', statusCode: 404 } |
| 778 | } |
| 779 | } |
| 780 | |
| 781 | const providerConfig = (foundWebhook.providerConfig as Record<string, unknown>) || {} |
| 782 | const credentialId = providerConfig.credentialId as string | undefined |
| 783 | const credentialSetId = foundWebhook.credentialSetId as string | undefined |
| 784 | |
| 785 | if (credentialSetId) { |
| 786 | const billingCheck = await verifyCredentialSetBilling(credentialSetId) |
| 787 | if (!billingCheck.valid) { |
| 788 | logger.warn(`[${requestId}] Credential set billing check failed: ${billingCheck.error}`) |
| 789 | return { success: false, error: billingCheck.error, statusCode: 403 } |
| 790 | } |
| 791 | } |
| 792 | |
| 793 | const actorUserId = preprocessResult.actorUserId |
| 794 | if (!actorUserId) { |
| 795 | logger.error(`[${requestId}] No actorUserId provided for webhook ${foundWebhook.id}`) |
| 796 | return { success: false, error: 'Unable to resolve billing account', statusCode: 500 } |
| 797 | } |
no test coverage detected