from fastapi import HTTPException, status, Request from sqlalchemy.orm import Session from typing import Dict, Any import logging from app.services.webhook import WebhookService from app.schemas.webhook import WebhookEventCreate from app.models.integration import IntegrationType from app.core.config import settings logger = logging.getLogger(__name__) class WebhookHandler: def __init__(self, db: Session): self.db = db self.webhook_service = WebhookService(db) async def handle_user_webhook( self, request: Request, organization_id: int, payload: Dict[str, Any] ): """Handle webhooks from user management service""" # Verify webhook signature signature = request.headers.get("x-webhook-signature") if not signature: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Missing webhook signature" ) body = await request.body() if not self.webhook_service.verify_webhook_signature( body, signature, settings.WEBHOOK_SECRET ): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid webhook signature" ) # Extract event data event_id = payload.get("event_id") event_type = payload.get("event_type") if not event_id or not event_type: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Missing required fields: event_id, event_type" ) # Create webhook event webhook_data = WebhookEventCreate( external_id=event_id, event_type=event_type, payload=payload, integration_type=IntegrationType.USER_MANAGEMENT, organization_id=organization_id ) webhook_event = self.webhook_service.create_webhook_event(webhook_data) logger.info(f"User webhook received: {event_type} - {event_id}") return {"status": "accepted", "webhook_id": webhook_event.id} async def handle_payment_webhook( self, request: Request, organization_id: int, payload: Dict[str, Any] ): """Handle webhooks from payment service""" # Verify webhook signature signature = request.headers.get("x-webhook-signature") if not signature: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Missing webhook signature" ) body = await request.body() if not self.webhook_service.verify_webhook_signature( body, signature, settings.WEBHOOK_SECRET ): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid webhook signature" ) # Extract event data event_id = payload.get("event_id") event_type = payload.get("event_type") if not event_id or not event_type: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Missing required fields: event_id, event_type" ) # Create webhook event webhook_data = WebhookEventCreate( external_id=event_id, event_type=event_type, payload=payload, integration_type=IntegrationType.PAYMENT, organization_id=organization_id ) webhook_event = self.webhook_service.create_webhook_event(webhook_data) logger.info(f"Payment webhook received: {event_type} - {event_id}") return {"status": "accepted", "webhook_id": webhook_event.id} async def handle_communication_webhook( self, request: Request, organization_id: int, payload: Dict[str, Any] ): """Handle webhooks from communication service""" # Verify webhook signature signature = request.headers.get("x-webhook-signature") if not signature: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Missing webhook signature" ) body = await request.body() if not self.webhook_service.verify_webhook_signature( body, signature, settings.WEBHOOK_SECRET ): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid webhook signature" ) # Extract event data event_id = payload.get("event_id") event_type = payload.get("event_type") if not event_id or not event_type: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Missing required fields: event_id, event_type" ) # Create webhook event webhook_data = WebhookEventCreate( external_id=event_id, event_type=event_type, payload=payload, integration_type=IntegrationType.COMMUNICATION, organization_id=organization_id ) webhook_event = self.webhook_service.create_webhook_event(webhook_data) logger.info(f"Communication webhook received: {event_type} - {event_id}") return {"status": "accepted", "webhook_id": webhook_event.id}