Skip to content

Feature Request: Inbound Webhook Support #15

Description

@bhubbard

This feature proposes adding support for inbound webhooks from Resend, allowing WordPress to listen and react to events in real-time. This would enable powerful automation and deeper integration between the two platforms.


Admin UI & Configuration

A new settings tab, "Webhooks", should be added to the plugin's admin interface with the following controls:

  • Enable Webhooks: A master toggle to activate or deactivate all webhook handling.
  • Webhook URL: A read-only field displaying the unique REST API endpoint generated by the plugin (e.g., https://yourdomain.com/wp-json/resend-wp/v1/webhooks). Users can copy this URL to their Resend dashboard.
  • Signing Secret: An input field for the admin to paste the Signing Secret from Resend to secure the endpoint.
  • Log Retention: A setting to automatically clear old logs. For example, a dropdown with options like "Keep logs for 7 days," "30 days," "90 days," or "Forever."
  • Clear All Logs: A button that allows an admin to manually purge the entire webhook log table (with a confirmation prompt).

Webhook Processing & Security

The generated REST API endpoint must be secure and robust.

  1. Verify Signature: Upon receiving a POST request, the endpoint must use the saved Signing Secret to validate the Resend-Signature header. Requests with an invalid signature must be rejected with a 401 Unauthorized error.
  2. Acknowledge Promptly: After successful verification, the endpoint should immediately return a 200 OK response to Resend to prevent timeouts and retries. Further processing should happen after the response is sent.

Webhook Logging & Management

To provide an audit trail and aid in debugging, all verified webhooks should be logged.

  • Custom Table: A new database table (e.g., wp_resend_webhooks_log) should be created to store incoming events.
    • Columns: id, event_type, resend_event_id, payload (JSON), status ('processed', 'unhandled', 'failed'), received_at (timestamp).
  • Log Viewer: A new admin page under the Resend menu to view, search, and filter these logs.
  • Automated Cleanup: A daily WP Cron job should run to delete log entries older than the configured Log Retention period.

Developer Experience: Action Hooks

To make the feature extensible, the plugin should fire WordPress actions after a webhook is successfully verified and logged.

  • Generic Hook: Fires for any event.
    do_action( 'resend_wp_webhook_received', $event_type, $payload );
  • Dynamic, Event-Specific Hook: Fires for a specific event type, making it easy to target individual events.
    // Example for a 'contact.created' event
    // Hook name: 'resend_wp_webhook_contact_created'
    do_action( 'resend_wp_webhook_' . str_replace('.', '_', $event_type), $payload );

Example Use Case: Create WordPress User from Resend Contact

This new functionality unlocks many potential workflows.

  1. Setup: An admin enables webhooks, configures the contact.created event in their Resend dashboard, and adds the Signing Secret to WordPress.
  2. Trigger: A new contact is added to an audience in Resend.
  3. Action: Resend sends a webhook to WordPress. The plugin verifies it and fires the resend_wp_webhook_contact_created action.
  4. Custom Code: A developer can easily hook into this action to create a corresponding WordPress user.
    add_action( 'resend_wp_webhook_contact_created', function( $payload ) {
        $email = $payload['data']['email'];
    
        if ( ! email_exists( $email ) ) {
            // Create a new WordPress user with the 'subscriber' role
            $user_id = wp_create_user( $email, wp_generate_password(), $email );
            wp_update_user( array( 'ID' => $user_id, 'role' => 'subscriber' ) );
        }
    });

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions