Files
attune/work-summary/2026-02-04-webhook-event-processing-fix.md
2026-02-04 17:46:30 -06:00

5.9 KiB

Webhook Event Processing Fix

Date: 2026-02-04
Issue: Webhook events were not triggering rule processing
Status: Fixed and Verified

Problem Description

When webhooks were submitted to triggers (e.g., default.example), the events were being created in the database successfully, but they were not engaging with any rules. The events didn't specify a specific rule when created (as expected), so they should have matched against all rules subscribing to that trigger. However, the executor service never processed these events.

Root Cause

The webhook receiver endpoint (/api/v1/webhooks/{trigger_ref}) was creating events in the database but was not publishing EventCreated messages to the RabbitMQ message queue. This meant the executor service had no notification that a new event existed and therefore could not:

  1. Find matching rules for the event's trigger
  2. Evaluate rule conditions
  3. Create enforcements
  4. Schedule executions

In contrast, the regular event creation endpoint (POST /api/v1/events) was correctly publishing EventCreated messages after creating events.

Solution

Added EventCreated message publishing to the webhook receiver endpoint to match the behavior of the regular event creation endpoint.

Changes Made

File: attune/crates/api/src/routes/webhooks.rs

  1. Added imports for message queue types:

    use attune_common::{
        mq::{EventCreatedPayload, MessageEnvelope, MessageType},
        repositories::{
            event::{CreateEventInput, EventRepository},
            trigger::{TriggerRepository, WebhookEventLogInput},
            Create, FindById, FindByRef,
        },
    };
    
  2. Added message publishing logic after event creation (lines 647-676):

    • Construct EventCreatedPayload with event details
    • Create MessageEnvelope with source "api-webhook-receiver"
    • Publish to message queue via publisher.publish_envelope()
    • Log success/failure appropriately
    • Continue processing even if publishing fails (event already recorded)

Event Flow (After Fix)

Webhook Request → API validates request → Event created in DB →
EventCreated message published to RabbitMQ → Executor receives message →
Finds matching rules (event.rule is None, so matches all enabled rules for trigger) →
Creates enforcements → Schedules executions → Workers execute actions

Verification

The executor service properly handles events without a specific rule:

  • When event.rule is None, the find_matching_rules() function matches all enabled rules with the same trigger_ref
  • This logic was already correct in attune/crates/executor/src/event_processor.rs (lines 145-153)

Deployment

Since both API and executor services run in Docker:

# Rebuild API service with fix
docker compose build api

# Restart API service (must use down/up to pick up new image)
docker compose down api
docker compose up -d api

Important: Using docker compose restart alone may not pick up the new image. Use down + up to ensure the new image is used.

Testing

To test the fix:

  1. Ensure you have a rule that subscribes to a webhook trigger (e.g., default.example)
  2. Submit a webhook to the trigger endpoint
  3. Verify the event is created and the EventCreated message is logged
  4. Verify the executor processes the event and creates enforcements
  5. Verify executions are scheduled and run

Verified Example

Submitted webhook with correct payload format:

curl -X POST http://localhost:8080/api/v1/webhooks/wh_kxuvd5ai4hqrzsoog2kzuz3tcskihjpj \
  -H "Content-Type: application/json" \
  -d '{"payload": {"test": "verify_fix", "timestamp": "2026-02-04T04:34:39Z"}}'

Note: Webhook payload must be wrapped in a payload field per the WebhookReceiverRequest DTO.

API logs confirmed:

attune-api | Webhook event 8581 created, attempting to publish EventCreated message
attune-api | Message 11134cae-6c56-4fb9-8395-babf1ae420cd published successfully to 'attune.events'
attune-api | Published EventCreated message for event 8581 (trigger: default.example)

Executor logs confirmed full flow:

attune-executor | Processing EventCreated for event 8581 (trigger: default.example)
attune-executor | Found 1 matching rule(s) for event 8581
attune-executor | Rule default.example_webhook_rule matched event 8581 - creating enforcement
attune-executor | Enforcement 8564 created for rule default.example_webhook_rule (event: 8581)
attune-executor | Creating execution for enforcement: 8564, rule: 3, action: 1
attune-executor | Execution 8564 scheduled to worker 3
attune-executor | Successfully processed completion for execution: 8564 (action: 1)

Impact

  • Webhooks now properly trigger rule processing as expected
  • Events without a specific rule correctly match all enabled rules for the trigger
  • No changes to database schema or message formats
  • No breaking changes to existing functionality
  • Webhook events now behave consistently with manually created events
  • Full event → enforcement → execution flow verified working
  • attune/crates/api/src/routes/webhooks.rs - Fixed file (added EventCreated publishing)
  • attune/crates/api/src/routes/events.rs - Reference implementation
  • attune/crates/executor/src/event_processor.rs - Event processing logic (already correct)
  • attune/scripts/test-webhook-event-processing.sh - Test script for verification

Lessons Learned

  1. Log level matters: Initial implementation used tracing::debug! for success case, making it invisible in production logs. Changed to tracing::info! for visibility.
  2. Docker image updates: docker compose restart doesn't always pick up new images. Use docker compose down + up to force image reload.
  3. Webhook payload format: The webhook endpoint expects {"payload": {...}} not bare JSON, per WebhookReceiverRequest DTO.