Aten Design Group: Introducing Entity Webhook: Config-Driven Webhook Integration for Drupal

Before a value is written to an entity field, you can optionally run it through a mutation plugin to transform it: convert an ISO date string to a Unix timestamp, map a source status to a Drupal equivalent (paid → completed), convert a cents integer to a decimal price, apply a regex substitution, and more.Webhook Receiver is a code-first plugin framework. Its README is straightforward about this: “This module does not contain any graphical user interface.” You extend a plugin base class, implement validatePayload() and processPayload(), and wire everything together in code. It’s a solid foundation for developers building bespoke integrations, but every integration is custom work from scratch.Once configured, external services POST to:

What Is Entity Webhook?

To keep entities in sync rather than creating duplicates, you mark one or more field mappings as identifiers. Before saving, the module performs a lookup — if an entity with those field values already exists, it updates it instead of creating a new one. Multiple identifier fields form a composite key.

  • Inbound (core module): Receive JSON payloads from external services and automatically create or update Drupal entities
  • Outbound (entity_webhook_broadcast submodule): Notify external systems when Drupal entities are created, updated, or deleted
  • Polling (entity_webhook_polling submodule): Actively fetch data from external APIs on a schedule, as a fallback for systems that don’t push webhooks
To avoid unnecessary processing, each fetched record is hashed with SHA-256. Only records whose hash has changed since the last run are queued for processing.

There are a few other maintained, Drupal 11-compatible webhook modules worth knowing about. Here’s how they differ, based on reviewing each module’s source code.At Aten, we build a lot of integrations. A recent project made the need for a more complete webhook solution clear: a client needed a centralized hub that could aggregate order data from Shopify and multiple Drupal Commerce sites, and keep customer addresses synchronized across all of them. Data was flowing in multiple directions, from multiple sources, with different payload formats. The existing options in the Drupal ecosystem either required significant custom code or handled one direction well but not the other. So we built something.

Flexible Field Extraction

Entity Webhook gives Drupal a complete webhook toolkit built around three capabilities:Webhooks are one of the most useful tools in a modern integration toolkit. Instead of your Drupal site repeatedly asking “anything new?” on a schedule, an external system taps your shoulder the moment something changes. The result is faster data, fewer redundant requests, and integrations that actually behave like real-time systems.

Deduplication and Updates

Three verification plugins are included: HMAC-SHA256 signature validation (with configurable header name and encoding), API Key validation from a header or query parameter, and an IP/CIDR whitelist. All verification runs synchronously before any processing begins.

Verification Built In

If you’re working on a Drupal integration — connecting an e-commerce platform, a CRM, a payment processor, or another Drupal site — we’d love to help. Get in touch with the Aten team.

Developer Extensibility

Not every external service supports webhooks. The entity_webhook_polling submodule handles those cases. You configure a schedule using a standard cron expression (e.g., */15 * * * *), implement a polling provider plugin for your API, and it feeds results into the same entity upsert pipeline used by inbound webhooks.

Broadcasting Outbound Webhooks

Delivery is queue-based and asynchronous. If a delivery fails, the module retries with exponential backoff up to a configurable number of attempts. Every attempt — successful or not — is written to an audit log, which makes debugging integrations considerably less painful.We’re excited to introduce Entity Webhook, now available as a contributed module on drupal.org.

Polling for APIs That Don’t Push

Webhooks is the most established option and works well for outbound use cases. When it receives a webhook, it fires a webhook.receive Drupal event — your code handles what happens next. That flexibility is useful, but it means every inbound integration requires a custom event subscriber and no entity upsert comes for free.When configuration isn’t enough, the module dispatches Symfony events before and after entity saves. A PreSaveEvent subscriber can modify the entity or cancel the save entirely. A PostSaveEvent subscriber can trigger downstream workflows or notifications — without touching core module code.

How It Compares to Other Webhook Modules

Entity Webhook is designed for the scenario where you want integrations to live in configuration — deployable, exportable via Drupal’s config management, and maintainable without a developer on call every time a payload format changes.

Feature entity_webhook webhooks webhook_receiver symfony_webhook_receiver
Inbound webhooks
Entity upsert — config-driven, no code
Field mapping UI
Outbound broadcasting Submodule
Polling Submodule
HMAC verification Token-in-URL only Symfony-native
API Key / IP whitelist verification
Admin UI
Custom code required to process inbound
Drupal 11 compatible

The key design decision: all three are driven by the admin UI. No custom module code is required to get a working integration.Field values are extracted from the JSON payload using JSONPath expressions. A mapping like $.order.billing_address.first_name can reach deep into a nested payload structure. You can also combine multiple expressions or use hardcoded static values.The core module handles inbound webhooks through a three-tier configuration structure: endpoints, source types, and field mappings.The entity_webhook_broadcast submodule monitors entity CRUD events and delivers signed JSON payloads to external endpoints. You configure outbound field mappings to define the payload shape, set a shared secret for HMAC-SHA256 signing, and optionally define conditions that filter which events trigger a broadcast.

Getting Started

Symfony Webhook Receiver brings Symfony’s Webhook component into Drupal. If your team is comfortable with Symfony’s ConsumerInterface and service container conventions, it’s a clean approach. Like the others, it has no admin UI, and each integration requires custom service definitions and consumer classes.

Let’s Build Something

An endpoint defines the target entity type — a Commerce Order, a taxonomy term, a user, or any custom entity. A source type represents a particular payload format from a particular service (Shopify, Stripe, another Drupal site), along with its verification method. A field mapping connects a JSON value in the payload to a Drupal entity field.

Similar Posts