as-cornell/as_webhook_entities

Manage Drupal entities like people records and articles via webhook notifications.

Maintainers

Package info

github.com/as-cornell/as_webhook_entities

Homepage

Type:drupal-custom-module

pkg:composer/as-cornell/as_webhook_entities

Statistics

Installs: 852

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.8 2026-03-02 20:35 UTC

This package is auto-updated.

Last update: 2026-04-02 21:17:24 UTC


README

Latest Stable Version

AS WEBHOOK ENTITIES (as_webhook_entities)

INTRODUCTION

Touchdown!

Receives webhook notifications from remote systems and creates, updates, or deletes local Drupal entities (people, articles, taxonomy terms) accordingly. Uses a Strategy pattern with per-type handler classes for maintainability and extensibility.

REQUIREMENTS

System Requirements

  • Drupal 9.5+ or Drupal 10+
  • PHP 8.0+

INSTALLATION

New Installation

  1. Enable the module:

    drush en as_webhook_entities -y
  2. Configure the module settings:

    • Navigate to /admin/config/as_webhook_entities/settings
    • Configure the authorization token and cron trigger settings
  3. Verify the queue worker is registered:

    drush queue:list

    You should see webhook_entities_processor in the list.

Upgrading from 1.x to 2.0

  1. Pull the updated code and clear cache:

    drush cr
  2. Verify the module is functioning:

    drush watchdog:show --type=as_webhook_entities --count=10

CONFIGURATION

  • Settings UI: /admin/config/as_webhook_entities/settings
  • Runs on cron (webhook_entities_processor queue, 30 seconds per cron run)
  • Cron can be triggered on receipt via the crontrigger setting
  • Logs create/update/delete operations as as_webhook_entities

ARCHITECTURE

Strategy Pattern (v2.0+)

Per-type field logic is handled by dedicated handler classes. WebhookCrudManager is a thin dispatcher that handles shared logic (title, status, departments/domain access, save) and delegates to the appropriate handler.

as_webhook_entities/
├── src/
│   ├── WebhookCrudManager.php              - Thin dispatcher, shared CRUD logic
│   ├── WebhookUuidLookup.php               - Looks up existing entities by UUID
│   ├── WebhookHandler/
│   │   ├── WebhookHandlerInterface.php     - applyCreateFields / applyUpdateFields
│   │   ├── WebhookHandlerBase.php          - Shared lookup helpers
│   │   ├── PersonWebhookHandler.php
│   │   ├── ArticleWebhookHandler.php
│   │   ├── MediaReportEntryWebhookHandler.php
│   │   ├── MediaReportPersonWebhookHandler.php
│   │   └── TermWebhookHandler.php
│   └── Plugin/QueueWorker/
│       └── WebhookEntitiesQueue.php        - Queue processor, event dispatcher

Supported Entity Types

Payload type Drupal entity Handler
person node:person PersonWebhookHandler
article node:article ArticleWebhookHandler
media_report_entry node:media_report_entry MediaReportEntryWebhookHandler
media_report_person node:person MediaReportPersonWebhookHandler
term taxonomy_term TermWebhookHandler

Adding a New Entity Type

  1. Create a class in src/WebhookHandler/ extending WebhookHandlerBase
  2. Implement getType(), applyCreateFields(), and applyUpdateFields()
  3. Register it in WebhookCrudManager::__construct():
    'my_type' => new MyTypeWebhookHandler($entity_type_manager),

MAINTAINERS

Current maintainers for Drupal 10:

  • Mark Wilson (markewilson)

TROUBLESHOOTING

Queue items not processing

  1. Check the queue size:

    drush queue:list
  2. Run the queue manually:

    drush queue:run webhook_entities_processor
  3. Check recent logs:

    drush watchdog:show --type=as_webhook_entities --count=20

Entity not created or updated

  1. Verify the UUID lookup is finding the entity:

    lando drush php-eval "
    \$lookup = \Drupal::service('as_webhook_entities.uuid_lookup');
    \$entity = \$lookup->findEntity('YOUR-UUID-HERE', 'person');
    echo \$entity ? 'Found: ' . \$entity->id() : 'Not found';
    "
  2. Push a test payload directly into the queue:

    lando drush php-eval "
    \$payload = json_encode([
      'event' => 'create',
      'type' => 'person',
      'uuid' => 'test-uuid-001',
      'status' => '1',
      'uid' => '1',
      'title' => 'Test Person',
      'field_departments_programs' => [],
      'field_overview_research' => [],
      'field_links' => [],
    ]);
    \Drupal::queue('webhook_entities_processor')->createItem(\$payload);
    echo 'Queued.' . PHP_EOL;
    "
    lando drush queue:run webhook_entities_processor
  3. Check for field errors — if a field in the payload doesn't exist on the destination bundle, the update will fail. Verify field existence:

    lando drush php-eval "
    \$fields = \Drupal::service('entity_field.manager')->getFieldDefinitions('node', 'article');
    echo implode(', ', array_keys(\$fields));
    "

CHANGELOG

2.0

  • Refactored WebhookCrudManager using the Strategy pattern — per-type field logic extracted into dedicated handler classes under src/WebhookHandler/
  • Added WebhookHandlerInterface and WebhookHandlerBase with shared entity lookup helpers (lookupTermTidsByName, lookupTermTidsByProperty, lookupNodeNidsByRemoteUuid)
  • Added handler classes: PersonWebhookHandler, ArticleWebhookHandler, MediaReportEntryWebhookHandler, MediaReportPersonWebhookHandler, TermWebhookHandler
  • WebhookCrudManager is now a thin dispatcher; shared logic (departments/domain access, node creation, save) remains centralised
  • Simplified WebhookUuidLookup::findEntity() to a type-keyed lookup map, eliminating duplicate if blocks
  • Cleaned up WebhookEntitiesQueue: removed redundant UUID ternary, extracted dispatchCreate() helper, removed dead code
  • Fixed two bugs in MediaReportEntryWebhookHandler: field_news_date was incorrectly read from field_outlet_name, and field_media_report_public_cat had a variable typo
  • Moved field_portrait_image_alt out of shared update logic into ArticleWebhookHandler where it belongs