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 is about provider plugins only. Inbound webhook notifications are a separate feature and are documented on Webhooks.

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
  • 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 plugin becomes available in the notifications settings UI.

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.

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.0, the runtime plugin system covers notification providers only. Alert-source plugins are not dynamically loaded in v1.0, 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