as-cornell / as_webhook_update
Provides a webhook notification service tied into hook_post_action, used to generate remote nodes and terms.
Package info
github.com/as-cornell/as_webhook_update
Type:drupal-custom-module
pkg:composer/as-cornell/as_webhook_update
README
AS WEBHOOK UPDATE (as_webhook_update)
INTRODUCTION
Provides a webhook notification service that sends entity changes (articles, people, taxonomy terms) to remote systems via HTTP webhooks. Uses an OOP architecture with services, extractors, and dependency injection for maintainability and testability.
REQUIREMENTS
Required Modules
drupal/hook_post_action- Provides post-action hooks for entity operationsdrupal/key- Provides secure storage for the authorization token
System Requirements
- Drupal 9.5+ or Drupal 10+
- PHP 8.0+
INSTALLATION
New Installation
-
Install dependencies:
composer require drupal/hook_post_action drupal/key
-
Enable the modules:
drush en hook_post_action key as_webhook_update -y
-
Configure the authorization token:
- Navigate to
/admin/config/services/webhook-update - Enter your authorization token
- Click "Save Configuration"
The token is securely stored using the Key module and will not be exported with configuration.
- Navigate to
-
Verify the configuration:
drush config:get as_webhook_update.domain_config
Upgrading from Previous Version
IMPORTANT: If you're upgrading from the procedural version to the OOP version, you must manually import the domain configuration. You will need to set up the relationship between domains as fits your use case:
-
Clear cache:
drush cr
-
Import domain configuration:
drush config:import --partial --source=modules/custom/as_webhook_update/config/install -y
Or if using Lando:
lando drush config:import --partial --source=/app/web/modules/custom/as_webhook_update/config/install -y
Or if on Pantheon (adapt pattern as appropriate):
terminus remote:drush artsci-as.dev -- config:import --partial --source=modules/custom/as_webhook_update/config/install -y terminus remote:drush artsci-people.dev -- config:import --partial --source=modules/custom/as_webhook_update/config/install -y terminus remote:drush artsci-as.test -- config:import --partial --source=modules/custom/as_webhook_update/config/install -y terminus remote:drush artsci-people.test -- config:import --partial --source=modules/custom/as_webhook_update/config/install -y terminus remote:drush artsci-as.live -- config:import --partial --source=modules/custom/as_webhook_update/config/install -y terminus remote:drush artsci-people.live -- config:import --partial --source=modules/custom/as_webhook_update/config/install -y
-
Verify the config was imported:
drush config:get as_webhook_update.domain_config
You should see environment-specific webhook URLs.
-
Migrate the authorization token (if you had one configured):
# Get the old token value drush cget as_webhook_update.settings token # Set it via the new form at /admin/config/services/webhook-update # Or via drush: drush php-eval " \$key = \Drupal\key\Entity\Key::create([ 'id' => 'as_webhook_update_token', 'label' => 'Webhook Update Authorization Token', 'key_type' => 'authentication', 'key_provider' => 'config', 'key_provider_settings' => ['key_value' => 'YOUR_TOKEN_HERE'], ]); \$key->save(); "
-
Test the webhooks:
- Update an article, person, or taxonomy term
- Check logs:
drush watchdog:show --type=as_webhook_update
CONFIGURATION
Authorization Token
The webhook authorization token is stored securely via the Key module and is NOT exported with configuration:
- Configure via UI:
/admin/config/services/webhook-update - Configure via Drush: See installation instructions above
- Documentation: See
KEY_SETUP.mdfor detailed setup instructions
Webhook Destinations
Webhook URLs are configured in config/install/as_webhook_update.domain_config.yml and are environment-specific:
- Local (Lando):
artsci-*.lndo.site - Dev/Test (Pantheon):
*-artsci-*.pantheonsite.io - Production:
*.as.cornell.edu
The module automatically determines the correct webhook URLs based on the current domain.
ARCHITECTURE
OOP Design (v2.0+)
The module uses a service-based architecture with dependency injection:
as_webhook_update/
├── src/
│ ├── Service/
│ │ ├── WebhookDispatcherService.php - Main orchestrator
│ │ ├── HttpClientService.php - HTTP/cURL handling
│ │ ├── DestinationResolverService.php - URL resolution
│ │ └── PersonTypeRoutingService.php - Person routing logic
│ ├── DataExtractor/
│ │ ├── EntityDataExtractorInterface.php - Common interface
│ │ ├── ArticleDataExtractor.php - Article data
│ │ ├── PersonDataExtractor.php - Person data
│ │ ├── MediaReportPersonDataExtractor.php - Simplified person data
│ │ └── TaxonomyTermDataExtractor.php - Taxonomy data
│ ├── Factory/
│ │ └── EntityExtractorFactory.php - Extractor selection
│ └── ValueObject/
│ └── WebhookDestination.php - Destination VO
Hooks
The module implements Drupal hooks that delegate to the dispatcher service:
hook_ENTITY_TYPE_postinsert()- For nodes and taxonomy termshook_ENTITY_TYPE_postupdate()- For nodes and taxonomy termshook_ENTITY_TYPE_postdelete()- For nodes
Supported Entities
- Article nodes - Sent to articles webhook
- Person nodes - Sent to AS, department, and/or media report webhooks based on person type
- Taxonomy terms -
academic_interests,academic_role,research_areas
MAINTAINERS
Current maintainers for Drupal 10:
- Mark Wilson (markewilson)
DOCUMENTATION
- REFACTORING.md - Details about the OOP refactoring
- KEY_SETUP.md - Complete guide to setting up the authorization token
- as_webhook_update.services.yml - Service definitions
TROUBLESHOOTING
No webhooks being sent
-
Check if domain config is imported:
drush config:get as_webhook_update.domain_config
If it returns "Config does not exist", import it:
drush config:import --partial --source=modules/custom/as_webhook_update/config/install -y
-
Check if authorization token is configured:
drush php-eval "\$key = \Drupal::service('key.repository')->getKey('as_webhook_update_token'); echo \$key ? 'Token configured' : 'Token NOT configured';" -
Check the logs:
drush watchdog:show --type=as_webhook_update --count=10
-
Verify the dispatcher service exists:
drush php-eval "echo get_class(\Drupal::service('as_webhook_update.dispatcher'));"
HTTP code 0 errors
If webhooks show "HTTP code 0", the destination server is unreachable:
- Verify the destination server is running
- Check network connectivity
- Verify the webhook listener endpoint exists
Testing webhooks
# Manually trigger a webhook drush php-eval " \$node = \Drupal::entityTypeManager()->getStorage('node')->load(NODE_ID); \Drupal::service('as_webhook_update.dispatcher')->dispatch(\$node, 'update'); " # Monitor logs in real-time drush watchdog:tail --type=as_webhook_update