Custom Notification Channels

Learn how to add custom notification channels like WhatsApp, SMS, or Telegram to WooNooW

WooNooW supports custom notification channels through a pluggable architecture. You can extend the notification system to send messages via WhatsApp, SMS, Telegram, or any other service.

Architecture Overview

The multi-channel notification system consists of three core components:

  1. ChannelInterface - Contract that all channels must implement
  2. ChannelRegistry - Central registry for managing channels
  3. NotificationManager - Sends notifications through registered channels
graph LR
    A[NotificationManager] --> B[ChannelRegistry]
    B --> C[Email Channel]
    B --> D[WhatsApp Channel]
    B --> E[SMS Channel]
    B --> F[Custom Channel]

Creating a Custom Channel

Step 1: Implement ChannelInterface

Create a class that implements WooNooW\Core\Notifications\Channels\ChannelInterface:

<?php
namespace MyPlugin\Channels;

use WooNooW\Core\Notifications\Channels\ChannelInterface;

class WhatsAppChannel implements ChannelInterface {
    
    public function get_id() {
        return 'whatsapp';
    }
    
    public function get_label() {
        return __('WhatsApp', 'my-plugin');
    }
    
    public function is_configured() {
        $api_key = get_option('my_whatsapp_api_key');
        return !empty($api_key);
    }
    
    public function send($event_id, $recipient, $data) {
        // Your sending logic here
        return [
            'success' => true,
            'message' => 'Sent successfully'
        ];
    }
    
    public function get_config_fields() {
        return [
            [
                'id' => 'my_whatsapp_api_key',
                'label' => 'API Key',
                'type' => 'text',
            ],
        ];
    }
}

Step 2: Register Your Channel

Register your channel with the ChannelRegistry during plugin initialization:

use WooNooW\Core\Notifications\ChannelRegistry;
use MyPlugin\Channels\WhatsAppChannel;

add_action('init', function() {
    $channel = new WhatsAppChannel();
    ChannelRegistry::register($channel);
});

Step 3: Enable in Settings

Once registered, your channel will be available in the notification settings UI, where users can configure which events should use WhatsApp.

Interface Reference

get_id()

Returns a unique identifier for your channel.

public function get_id(): string

Example:

public function get_id() {
    return 'whatsapp'; // or 'sms', 'telegram', etc.
}

get_label()

Returns a human-readable label for the admin UI.

public function get_label(): string

Example:

public function get_label() {
    return __('WhatsApp Business', 'my-plugin');
}

is_configured()

Checks if the channel has all required configuration (API keys, credentials, etc.).

public function is_configured(): bool

Example:

public function is_configured() {
    $api_key = get_option('my_whatsapp_api_key');
    $phone = get_option('my_whatsapp_phone');
    return !empty($api_key) && !empty($phone);
}

send()

Sends a notification through this channel.

public function send(string $event_id, string $recipient, array $data): bool|array

Parameters:

  • $event_id - Event identifier (e.g., 'order_completed', 'newsletter_confirm')
  • $recipient - Recipient type ('customer' or 'staff')
  • $data - Context data including order, user, custom variables

Returns:

  • bool - Simple success/failure
  • array - Detailed result with success and message keys

Example:

public function send($event_id, $recipient, $data) {
    $phone = $this->get_recipient_phone($recipient, $data);
    $message = $this->build_message($event_id, $data);
    
    $response = wp_remote_post('https://api.provider.com/send', [
        'body' => [
            'to' => $phone,
            'message' => $message,
            'api_key' => get_option('my_api_key'),
        ],
    ]);
    
    if (is_wp_error($response)) {
        return [
            'success' => false,
            'message' => $response->get_error_message(),
        ];
    }
    
    return ['success' => true];
}

get_config_fields()

Returns configuration fields for the admin settings UI (optional).

public function get_config_fields(): array

Field Structure:

[
    'id' => 'option_name',
    'label' => 'Field Label',
    'type' => 'text|select|textarea',
    'description' => 'Help text',
    'options' => [], // For select fields
    'default' => 'value',
]

Complete Example: WhatsApp Channel

See the reference implementation:
WhatsAppChannel.example.php

This example includes:

  • ✅ Twilio API integration
  • ✅ Phone number extraction from orders/users
  • ✅ Message templates for common events
  • ✅ Configuration fields for admin settings

Message Customization

Use filters to customize messages for specific events:

add_filter('woonoow_whatsapp_message_order_completed', function($message, $data) {
    if (isset($data['order'])) {
        $order = $data['order'];
        return sprintf(
            "🎉 Order #%s confirmed! Track here: %s",
            $order->get_order_number(),
            $order->get_view_order_url()
        );
    }
    return $message;
}, 10, 2);

Available Events

Your channel can handle any registered notification event:

EventRecipientData Available
order_completedcustomerorder, user_id
order_cancelledcustomerorder, user_id
newsletter_confirmcustomeremail, confirmation_url
newsletter_welcomecustomeremail, user_id
subscription_expiringcustomersubscription, user_id

See Event Registry for the complete list.

Testing Your Channel

// Manual test
use WooNooW\Core\Notifications\NotificationManager;

NotificationManager::send('order_completed', 'whatsapp', [
    'order' => wc_get_order(123),
    'user_id' => 1,
]);

Best Practices

  1. Validate Configuration: Always check is_configured() before attempting to send
  2. Handle Errors Gracefully: Return detailed error messages for debugging
  3. Log Send Attempts: Use do_action() for tracking/analytics
  4. Support Filtering: Allow message customization via filters
  5. Rate Limiting: Consider implementing rate limiting for API calls

Hooks

Registration Hook

// Register channels during init
add_action('init', function() {
    ChannelRegistry::register(new MyChannel());
});

Custom Hooks in Your Channel

// Allow logging/tracking
do_action('my_channel_sent', $event_id, $recipient, $result);

// Allow message customization
$message = apply_filters(
    "my_channel_message_{$event_id}", 
    $default_message, 
    $data
);

Troubleshooting

Channel not appearing in settings?

  • Ensure ChannelRegistry::register() is called during init
  • Check that get_id() returns a unique string
  • Verify is_configured() returns true

Messages not sending?

  • Check notification settings: Marketing > Notifications
  • Verify the event has your channel enabled
  • Enable debug mode and check logs
  • Test is_configured() returns true

API errors?

  • Validate API credentials in settings
  • Check API provider status/quotas
  • Review error logs for API responses