Skip to content

Provider Plugins

ChannelWatch includes a Python file-based plugin loader for notification providers. If the built-in providers and Custom (Apprise) do not cover your destination, you can add a third-party provider as local Python code.

This page covers notification delivery plugins. Outbound Webhooks are a separate way to send signed HTTP requests without writing a Python plugin.

At startup, ChannelWatch scans /config/plugins/notifications/ for .py files. The current loader behavior is:

  • files are scanned in sorted order
  • filenames that start with _ are skipped
  • each file is imported under a unique module name
  • concrete subclasses of NotificationProvider are instantiated with no constructor arguments
  • initialize() is called with no keyword arguments
  • the provider is registered only if initialize() returns True
  • provider names must be unique; a plugin cannot replace a built-in provider or an earlier registered plugin
  • import and initialization failures are logged and skipped instead of stopping the app

The loader also supports CHANNELWATCH_PLUGIN_DIR if you need to override the scan directory for testing.

  1. Obtain the plugin .py file from the plugin author.
  2. Place it in the /config/plugins/notifications/ directory inside your mounted config volume.
  3. Restart the ChannelWatch container.
  4. Check the startup logs to confirm the plugin loaded:
Plugin registered: MyCustomProvider (my_plugin.py)

If the plugin failed to load, you’ll see a warning instead:

Plugin import failed, skipping: my_plugin.py: No module named 'requests'
  1. Once loaded, the monitoring core can use the provider for notification delivery. The v1.6.5 Settings UI does not create fields for third-party plugins, so the plugin must read its own configuration from environment variables or local files you control.

Your config volume should look like this after adding a plugin:

/config/
|-- settings.json
|-- channelwatch.db
`-- plugins/
`-- notifications/
`-- my_plugin.py

Create the plugins/notifications/ directories if they don’t exist yet.

Subclass core.notifications.providers.base.NotificationProvider. Set a unique PROVIDER_TYPE and implement all three abstract methods:

Method Return value Purpose
initialize(self, **kwargs) bool Read your own configuration and prepare the provider. The loader passes no configuration kwargs
is_configured(self) bool Report whether delivery is ready
send_notification(self, title, message, image_url=None, **kwargs) bool Send the payload and report the actual transport result

Do not return True just because a payload was constructed. The result feeds delivery logging and retries. Handle repeated sends safely if your destination can receive retries.

Start from the released console provider example and plugin reference. The console example demonstrates the interface; it does not deliver a push notification.

Plugins run inside the ChannelWatch container. If your plugin imports a third-party library that isn’t bundled with ChannelWatch, the import will fail and the plugin will be skipped.

To use a plugin with external dependencies, you have two options:

  • Extend the image, create a custom Dockerfile that installs the required packages on top of the ChannelWatch base image.
  • Use only stdlib or bundled packages, write the plugin using only Python’s standard library and packages already present in the ChannelWatch image, such as httpx, apprise, and pydantic.

Plugins can:

  • Register a new notification delivery provider
  • Receive the notification payload, title, message, optional image_url, and safe context kwargs like dvr_id, dvr_name, and event_type
  • Send notifications to any destination using any Python-accessible transport
  • Return a success or failure result that feeds into the delivery log

Plugins cannot:

  • Replace the built-in routing engine
  • Receive database handles, encryption keys, or raw ChannelWatch secrets from the loader
  • Be hot-reloaded without a container restart

In v1.6.5, the runtime plugin system covers notification providers only. Alert-source plugins are not dynamically loaded in v1.6.5, and UI plugins are not part of this system.

  • Delivery Log , track delivery status for all providers including plugins
  • Custom (Apprise) , use any Apprise-supported service without writing a plugin
  • Hot Reload , what changes take effect without a restart, plugins are not hot-reloaded