# FlowDrop Trigger

> Event-driven workflow triggering — automatically execute workflows when Drupal entities are created, updated, or deleted, when users log in/out, on form submissions, or on cron schedules.

## Overview

The `flowdrop_trigger` module enables event-driven workflow automation. Trigger configurations are stored as dedicated config entities (`FlowDropTriggerConfig`) and are created automatically when a trigger node is dropped into the workflow editor.

When a matching Drupal event occurs, the trigger manager queries matching trigger configurations, filters by conditions (entity type, bundle, user role), and executes the associated workflow via the configured orchestrator.

## Dependencies

- [flowdrop](flowdrop.md)
- [flowdrop_node_type](flowdrop_node_type.md) (trigger node type)
- [flowdrop_workflow](flowdrop_workflow.md) (workflow definitions)
- [flowdrop_runtime](flowdrop_runtime.md) (workflow execution)
- [flowdrop_pipeline](flowdrop_pipeline.md) (pipeline management)

## Configuration

### Admin Pages

| Path | Description |
|------|-------------|
| `/admin/flowdrop/triggers` | List all trigger configurations |
| `/admin/flowdrop/triggers/configure` | Configure a trigger |
| `/admin/flowdrop/triggers/{trigger_id}` | View trigger details |
| `/admin/flowdrop/config/triggers` | General trigger settings (default orchestrator, logging) |
| `/admin/flowdrop/config/triggers/entity` | Entity event settings |
| `/admin/flowdrop/config/triggers/form` | Form event settings |
| `/admin/flowdrop/config/triggers/user` | User event settings |
| `/admin/flowdrop/config/triggers/cron` | Cron event settings |

### Permissions

| Permission | Description |
|------------|-------------|
| `administer flowdrop triggers` | Create, edit, and delete trigger configurations |
| `view flowdrop triggers` | View trigger configuration list and details |

## Tips and Tricks

### Event Types

**Entity Events:**

| Event | Description | Default Orchestrator |
|-------|-------------|---------------------|
| `entity.insert` | Entity created | Asynchronous |
| `entity.update` | Entity updated | Asynchronous |
| `entity.delete` | Entity deleted | Asynchronous |
| `entity.presave` | Before entity save | Synchronous |

**User Events:**

| Event | Description | Default Orchestrator |
|-------|-------------|---------------------|
| `user.login` | User logged in | Asynchronous |
| `user.logout` | User logged out | Asynchronous |

**Form Events:**

| Event | Description | Default Orchestrator |
|-------|-------------|---------------------|
| `form.submit` | Form submitted | Asynchronous |
| `form.validate` | Form validation | Synchronous |

**Cron Events:**

| Event | Description | Default Orchestrator |
|-------|-------------|---------------------|
| `cron.run` | Drupal cron runs | Asynchronous |

### Data Mapping with JSONPath

Trigger configurations support JSONPath expressions (RFC 9535) for extracting event data and mapping it to workflow inputs:

```yaml
initial_data_mapping:
  # JSONPath expressions
  user_email: '$.entity.mail.value'
  all_tags: '$.entity.field_tags[*].target_id'
  active_items: '$.entity.items[?(@.status == "active")]'

  # Literal values
  source: 'literal:trigger_api'
```

**Available context data for entity events:**

| Key | Description |
|-----|-------------|
| `entity` | Serialized entity data |
| `original_entity` | Original entity (for update/presave events) |
| `entity_type` | Entity type ID |
| `entity_id` | Entity ID |
| `bundle` | Entity bundle |
| `is_new` | Whether entity is new |
| `timestamp` | Unix timestamp |
| `trigger_config_id` | Trigger configuration ID |

### Trigger Config Entity ID Format

Trigger config entities use the format `{workflow_id}__{node_id}` — they are automatically created when a trigger node is placed in the workflow editor and deleted when the node is removed.

### Cron Triggers

Cron triggers are ideal for:

- Periodic data synchronization with external services
- Scheduled content publishing or unpublishing
- Automated cleanup and maintenance tasks
- Report generation at regular intervals

### Performance on High-Traffic Sites

For entity triggers on busy sites, use the asynchronous orchestrator (the default) to avoid blocking entity save operations. Monitor the queue sizes and consider dedicated queue workers for trigger pipelines.

### Troubleshooting Triggers Not Firing

1. Verify the workflow is enabled (`status: true`)
2. Check the trigger config is enabled
3. Verify entity type and bundle conditions match
4. Check Drupal logs: `drush watchdog:show --type=flowdrop_trigger`

## Developer API

### Services

| Service ID | Class | Description |
|-----------|-------|-------------|
| `flowdrop_trigger.manager` | `TriggerManager` | Main trigger management — matches events to triggers and dispatches execution |
| `plugin.manager.flowdrop_event_type` | `EventTypePluginManager` | Plugin manager for event type discovery |
| `flowdrop_trigger.schema_builder` | `TriggerConfigSchemaBuilder` | Builds JSON schema for trigger configuration forms |
| `flowdrop_trigger.cron_schedule_matcher` | `CronScheduleMatcher` | Evaluates cron trigger schedule expressions |
| `flowdrop_trigger.cron_state_service` | `CronTriggerStateService` | Tracks cron trigger execution history |
| `flowdrop_trigger.entity_serializer` | `EntitySerializer` | Entity serialization for trigger data |

### Entities

#### FlowDropTriggerConfig (Config Entity)

Stores trigger configuration including event type, conditions, orchestrator settings, and data mapping.

**Configuration structure:**

```yaml
id: my_workflow__node_abc123
label: 'Article Creation Trigger'
workflow_id: my_workflow
node_id: node_abc123
event_type: entity.insert
conditions:
  entity_types: [node]
  bundles: [article]
orchestrator_settings:
  type: asynchronous
  priority: normal
  timeout: 300
  retry:
    enabled: true
    max_attempts: 3
    delay: 60
    backoff: exponential
initial_data_mapping: {}
status: true
```

### Plugin Types

#### FlowDropEventType

Custom event types can be added by contrib modules:

```php
namespace Drupal\my_module\Plugin\FlowDropEventType;

use Drupal\flowdrop_trigger\Attribute\FlowDropEventType;
use Drupal\flowdrop_trigger\Plugin\FlowDropEventTypeBase;

#[FlowDropEventType(
  id: "my_custom.event",
  label: new TranslatableMarkup("My Custom Event"),
  description: new TranslatableMarkup("Triggered on custom event"),
  category: "custom",
  defaultOrchestrator: "flowdrop_runtime:asynchronous",
  defaultExecutionMode: "async",
)]
class MyCustomEvent extends FlowDropEventTypeBase {
  public function extractTriggerData(
    EntityInterface $entity,
    ?EntityInterface $originalEntity = NULL,
    array $context = [],
  ): array {
    return $this->getBaseTriggerData($entity);
  }
}
```

### Adding Custom Settings Categories

Contrib modules can add their own trigger settings tabs:

1. Extend `TriggerSettingsCategoryFormBase`
2. Register a route under `/admin/flowdrop/triggers/settings/{category}`
3. Add a local task tab with `base_route: flowdrop.config.triggers`

### API Endpoints

| Method | Path | Description |
|--------|------|-------------|
| POST | `/api/flowdrop/triggers` | Create trigger config |
| GET | `/api/flowdrop/triggers/{id}` | Get trigger config with schema |
| PATCH | `/api/flowdrop/triggers/{id}` | Update trigger config |
| DELETE | `/api/flowdrop/triggers/{id}` | Delete trigger config |
| GET | `/api/flowdrop/triggers/schema` | Get schema for an event type |
| GET | `/api/flowdrop/triggers/event-types` | List available event types |
| GET | `/api/flowdrop/triggers/{id}/history` | Get cron execution history |
| POST | `/api/flowdrop/triggers/{id}/reset-state` | Reset cron state |

## References

- [flowdrop_runtime](flowdrop_runtime.md) — executes triggered workflows
- [flowdrop_orchestration_connector](flowdrop_orchestration_connector.md) — extends triggers for external platforms
- [flowdrop_workflow](flowdrop_workflow.md) — workflow definitions
