| 15 | |
| 16 | |
| 17 | def trigger_event(event_name, payload): |
| 18 | if event_name not in SUPPORTED_EVENTS: |
| 19 | logger.debug(f"Unsupported event '{event_name}' - skipping") |
| 20 | return |
| 21 | |
| 22 | logger.debug( |
| 23 | f"Triggering connect event: {event_name} payload_keys={list((payload or {}).keys())}" |
| 24 | ) |
| 25 | subscriptions = EventSubscription.objects.filter( |
| 26 | event=event_name, enabled=True |
| 27 | ).select_related("integration") |
| 28 | |
| 29 | count = subscriptions.count() |
| 30 | logger.info(f"Found {count} connect subscription(s) for event '{event_name}'") |
| 31 | |
| 32 | # First, fetch all subscriptions and trigger |
| 33 | for sub in subscriptions: |
| 34 | integration = sub.integration |
| 35 | if not integration.enabled: |
| 36 | logger.debug( |
| 37 | f"Skipping disabled integration id={integration.id} name={integration.name}" |
| 38 | ) |
| 39 | continue |
| 40 | |
| 41 | # apply optional payload template (only for webhook integrations) |
| 42 | # If the rendered template is valid JSON, use that object as the payload. |
| 43 | # Otherwise, pass the rendered string as-is. |
| 44 | final_payload = payload |
| 45 | if integration.type == 'webhook' and sub.payload_template: |
| 46 | try: |
| 47 | template = Template(sub.payload_template) |
| 48 | final_payload = template.render(Context(payload)).strip() |
| 49 | except Exception as e: |
| 50 | logger.error( |
| 51 | f"Payload template render failed for subscription id={sub.id}: {e}" |
| 52 | ) |
| 53 | final_payload = payload |
| 54 | |
| 55 | handler_cls = HANDLERS.get(integration.type) |
| 56 | if not handler_cls: |
| 57 | DeliveryLog.objects.create( |
| 58 | subscription=sub, |
| 59 | status="failed", |
| 60 | request_payload=final_payload, |
| 61 | error_message=f"No handler for integration type '{integration.type}'", |
| 62 | ) |
| 63 | logger.error( |
| 64 | f"No handler for integration type '{integration.type}' (integration id={integration.id})" |
| 65 | ) |
| 66 | continue |
| 67 | |
| 68 | handler = handler_cls(integration, sub, final_payload) |
| 69 | logger.debug( |
| 70 | f"Executing handler type={integration.type} integration_id={integration.id} subscription_id={sub.id}" |
| 71 | ) |
| 72 | |
| 73 | try: |
| 74 | result = handler.execute() |