From drupal-core
Use when creating automated reactions to Drupal site events with ECA (Event-Condition-Action) workflows — covers component wiring, plugin discovery, and module management for content creation, form submissions, and user actions.
npx claudepluginhub ajv009/drupal-devkitThis skill uses the workspace's default tool permissions.
**Source**: Converted from `ai_agents_eca` Drupal AI agent (`drupal.org/project/ai_agents`)
Registers Webflow webhooks, verifies HMAC signatures, and handles events like form submissions, site publishes, ecommerce orders, and CMS changes for event-driven backends.
Guides n8n-mcp tool usage for node discovery, workflow management, credential handling, configuration validation, template deployment, and instance security auditing to prevent common errors.
Creates, edits n8n workflows as TypeScript files with node docs access and n8nac CLI for workspace init, preventing param errors.
Share bugs, ideas, or general feedback.
Source: Converted from ai_agents_eca Drupal AI agent (drupal.org/project/ai_agents)
Module: ECA (Event-Condition-Action)
Requires: eca base module plus submodules for specific event/action domains
Use this skill when working with ECA workflows in Drupal:
An ECA workflow (model) consists of four types of components linked together:
Events, actions, and gateways have successors -- an array defining what runs next:
"successors": [
{"id": "action_1", "condition": ""},
{"id": "action_2", "condition": "cond_1"}
]
id: References another component (action or gateway) by its component_id.condition: References a condition component by its component_id, or empty string for unconditional execution.Conditions do NOT have successors -- they are referenced FROM successors.
ECA has submodules that provide events, conditions, and actions for different areas. Check which are enabled before creating workflows, and enable any required modules first.
| Module | Domain |
|---|---|
eca_content | Content entity events (insert, update, delete, presave) |
eca_form | Form events (alter, validate, submit) |
eca_user | User events (login, logout, register) |
eca_workflow | Content moderation/workflow transitions |
eca_views | Views-related events and actions |
eca_base | Basic conditions and actions (field values, tokens, logic) |
eca_misc | Miscellaneous actions (redirects, messages, HTTP responses) |
eca_log | Logging actions |
eca_render | Render/display actions |
eca_cache | Cache tag invalidation |
eca_config | Configuration change events |
eca_queue | Queue processing |
eca_endpoint | Custom URL endpoints |
eca_access | Access control |
eca_file | File operation events |
These are the 11 tools available for ECA workflow management:
| # | Tool | Operation | Description |
|---|---|---|---|
| 1 | ListEcaModels | Read | Lists all ECA workflow models with ID, label, status, and component counts |
| 2 | GetEcaModel | Read | Gets the complete configuration of an ECA model including all events, conditions, actions, gateways, and successor connections |
| 3 | CreateEcaModel | Write | Creates a new ECA workflow model -- empty or with full structure (events, conditions, actions, gateways as JSON) in one call |
| 4 | DeleteEcaModel | Write | Permanently deletes an ECA workflow model and all its components |
| 5 | SetEcaModelStatus | Write | Enables or disables an ECA workflow model (disabled models do not react to events) |
| 6 | AddEcaComponent | Write | Adds an event, condition, action, or gateway to an existing ECA model |
| 7 | UpdateEcaComponent | Write | Updates the configuration, label, or successors of an existing component (partial update -- only provided fields change) |
| 8 | RemoveEcaComponent | Write | Removes a component from an ECA model and cleans up all successor references |
| 9 | SearchEcaPlugins | Read | Searches available ECA plugins (events, conditions, or actions) by keyword to discover plugin IDs, labels, descriptions, and provider modules |
| 10 | ListEcaModules | Read | Lists all available ECA submodules with name, description, and enabled/disabled status |
| 11 | EnableEcaModule | Write | Enables an ECA submodule to make its events, conditions, and actions available (restricted to eca* modules only) |
Check which ECA submodules are enabled. Enable any needed modules before creating workflows that use their plugins.
Search for the right event, condition, and action plugin IDs:
plugin_type: "event" + search: "insert" -- find content insert eventsplugin_type: "condition" + search: "bundle" -- find entity type/bundle conditionsplugin_type: "action" + search: "message" -- find message actionsChoose meaningful IDs for each component (e.g., event_node_insert, cond_is_article, action_send_email). These IDs are used in successor references.
Option A -- Create complete model in one call with events, conditions, actions, and gateways JSON.
Option B -- Create empty model, then add components one by one.
Retrieve the model to verify the complete workflow structure.
| Plugin ID | Description | Example Configuration |
|---|---|---|
content_entity:insert | Entity created | {"type": "node article"} or {"type": "node _all"} |
content_entity:update | Entity updated | {"type": "node article"} |
content_entity:delete | Entity deleted | {"type": "node _all"} |
content_entity:presave | Before entity save | {"type": "node article"} |
form:form_alter | Form is being built | {"form_id": "node_article_edit_form"} |
form:form_submit | Form submitted | {"form_id": "node_article_edit_form"} |
form:form_validate | Form validation | {"form_id": "node_article_edit_form"} |
ECA event plugin IDs follow a compound format. Always use SearchEcaPlugins to find the exact ID -- the content_entity events have many variations.
| Plugin ID | Description | Example Configuration |
|---|---|---|
eca_entity_type_bundle | Check entity type and bundle | {"type": "node article", "negate": false} |
eca_entity_field_value_empty | Check if field is empty | {"field_name": "field_name", "negate": false} |
eca_scalar_comparison | Compare two values | {"left": "[entity:field_name]", "right": "expected_value", "operator": "=="} |
eca_current_user_role | Check current user's role | {"role": "administrator"} |
eca_entity_is_new | Check if entity is new | {} |
| Plugin ID | Description | Example Configuration |
|---|---|---|
action_message_action | Display a status message | {"message": "Hello [entity:title]"} |
eca_set_field_value | Set an entity field value | {"field_name": "field_status", "field_value": "1", "save_entity": true} |
eca_save_entity | Save the current entity | {"entity": ""} |
eca_token_set_value | Set a token value | {"token_name": "my_token", "token_value": "some value"} |
eca_write_log_message | Log a message | {"message": "Something happened", "severity": "info"} |
eca_state_write | Write to Drupal state | {"key": "my_key", "value": "my_value"} |
eca_redirect_response | Redirect user | {"url": "/some/path", "status": "302"} |
"When an article is created, display a welcome message":
{
"events": {
"event_1": {
"plugin": "content_entity:insert",
"label": "Article created",
"configuration": {"type": "node article"},
"successors": [{"id": "action_1", "condition": ""}]
}
},
"actions": {
"action_1": {
"plugin": "action_message_action",
"label": "Show welcome message",
"configuration": {"message": "New article created: [entity:title]"},
"successors": []
}
}
}
"When content is saved, if it's an article send a message, otherwise log it":
{
"events": {
"event_1": {
"plugin": "content_entity:insert",
"label": "Content created",
"configuration": {"type": "node _all"},
"successors": [{"id": "gw_1", "condition": ""}]
}
},
"conditions": {
"cond_article": {
"plugin": "eca_entity_type_bundle",
"label": "Is article",
"configuration": {"type": "node article", "negate": false}
}
},
"gateways": {
"gw_1": {
"type": 0,
"successors": [
{"id": "action_msg", "condition": "cond_article"},
{"id": "action_log", "condition": ""}
]
}
},
"actions": {
"action_msg": {
"plugin": "action_message_action",
"label": "Article message",
"configuration": {"message": "Article created!"},
"successors": []
},
"action_log": {
"plugin": "eca_write_log_message",
"label": "Log other",
"configuration": {"message": "Non-article content created", "severity": "info"},
"successors": []
}
}
}
"When content is submitted for review, notify editors by email, and if approved, publish automatically":
This requires multiple modules: eca_content, eca_workflow, eca_misc. The workflow would chain:
eca_set_field_value"Check content type on creation and assign default taxonomy terms based on bundle":
content_entity:insert with {"type": "node _all"}eca_entity_type_bundle for each content typeeca_set_field_value to assign the appropriate term referenceECA uses Drupal's token system for dynamic values in configurations:
[entity:title] -- Current entity title[entity:field_name] -- Entity field value[entity:nid] -- Entity node ID[current-user:name] -- Current user's name[current-user:mail] -- Current user's email[site:name] -- Site nameevent_node_insert, not e1).