notifier plugin - degoya/rDownloader GitHub Wiki
A notification destination delivers rDownloader's messages to one more service — a chat, a push service, a server of the person's own. It delivers one message and reports how it went; retries, backoff and quiet hours belong to the application.
| Scaffold | rdownloader plugin new --type notifier |
plugin_type |
notifier |
| World | notifier-plugin |
| Exports | deliver |
Imports beyond host and http
|
destination-settings |
| Template | sdk/templates/notifier |
| Contract | Interface notifier |
- Retrying is not your decision. Report a failure and say what kind it is; the delivery hub applies its own backoff and quiet hours, the same ones the built-in webhook uses.
-
A secret reaches your request without reaching you. Put
{{secret}}in a header, a query value or the body and the host substitutes the destination's token on the way out. -
Only a few headers are sent at all —
authorization,content-type,acceptand a handful more; anything else goes in the query or the body.
The scaffold asks for net_http with the service's API. A destination that may live on a server of
the person's own adds * beside the services it names; the host then narrows every delivery to the
host its destination names, and requires https outside the person's own network.
[extension] claims stays empty: a destination is chosen by name when a notification target is
created.
A destination can let each target choose among fixed values — ntfy's priority per severity is one — or take free text, such as the path mapping of the media-server destinations. Declare each setting in the manifest:
[[extension.settings]]
name = "priority_info" # a-z, 0-9 and _
choices = ["1", "2", "3", "4", "5"] # every value offered, in this order
default = "2" # optional; without it the setting may stay unsetA setting without choices is free text: one line of at most 256 characters, or several lines
with multiline = true (4096 together), no control character but the line breaks; a default
follows the same rule.
[[extension.settings]]
name = "path_mapping"
multiline = true # a text area; without it a one-line fieldThe target editor offers a setting with choices as a select, free text as a field or a text area.
Its label is your own code
<slug>.setting.<name> in locales/*.json (an optional hint <slug>.setting.<name>.description),
each value's label <slug>.choice.<value>; without them the name and the value are shown.
Saving a target refuses a name you did not declare, a value you do not offer and free text
outside the rule; an empty value leaves the setting at its default. During
deliver, ask the host through the interface destination-settings:
use rdownloader::plugin::destination_settings;
let priority = destination_settings::setting("priority_info"); // Option<String>You hear the target's value, otherwise your default, otherwise None. Read None and anything
unexpected as "use the default" rather than failing the delivery. At most 16 settings, each with
1–32 choices or none.
For package_completed, notification.package-path names the folder of the finished package as
rDownloader sees it — its destination, where post-processing left the files; it is none for
every other event and for a test message. A retry, after a restart too, names the same folder.
Its last segments are a release name someone else wrote, so the host makes its braces inert like
those of the title; a path that held one is no longer the folder on disk, and a plugin that maps
it onto another server should not use it. The bundled Plex, Jellyfin and Emby destinations map it
through their free-text path_mapping setting onto the path the media server sees.
Ask for exactly what you use: the install preview shows every grant, and a component importing an interface its manifest does not grant cannot be instantiated. Every capability is listed under Capabilities.
plugin new reads its templates from sdk/templates, so run it from a checkout of the repository:
git clone https://github.com/degoya/rDownloader.git
cd rDownloader
rdownloader plugin new --type notifier --out ../mynotifier
cd ../mynotifierWithout an installation of rDownloader, the packaging tool rd-pack —
cargo build --profile release-test -p rd-pack in the checkout — takes the same arguments:
target/release-test/rd-pack plugin new --type notifier --out ../mynotifier.
The directory name becomes the crate name and the plugin's slug (--name sets another). The
scaffold gets its own plugin id, its own copy of the contract in wit/rdownloader.wit and its own
Ed25519 key pair: plugin-signing.key, whose public half is already in manifest.toml. Keep that
file out of version control.
-
src/lib.rsbuilds the address and the JSON body and decides how an answer is treated — delivered, retry, unauthorised or refused. -
src/guest.rsholdsdeliver. -
manifest.toml:[capabilities.net_http] domains. -
locales/en.json: the English text of every failure code you report.
Change description and author under [metadata], and read the comment at the top of
src/lib.rs: it states what the host promises this type.
cargo testThe unit tests need no WebAssembly toolchain: only src/guest.rs is wasm32-specific. Give every
answer of your provider you read a test of its own.
cargo build --release --target wasm32-unknown-unknown
wasm-tools component new target/wasm32-unknown-unknown/release/mynotifier.wasm -o target/mynotifier.wasmThis needs the wasm32-unknown-unknown target and wasm-tools 1.261.0, the version the bundled
plugins are made with: cargo build makes a core module that carries the world src/guest.rs
generates, and wasm-tools component new turns it into the component. The plugin is built
without WASI: a component importing anything outside rdownloader:plugin is refused — see
Building without WASI.
rdownloader plugin package --manifest manifest.toml \
--component target/mynotifier.wasm \
--locales locales --key plugin-signing.key --output mynotifier.rdplug
rdownloader plugin conformance mynotifier.rdplug --jsonconformance answers whether this application would run the package; it has to be clean before
you publish. For a key that outlives the scaffold, rdownloader plugin keygen --role plugin --output ./keys writes a pair: the Base64 in the .pub file goes into public_key, and key_id
gets a name of your own. In CI, RDOWNLOADER_PLUGIN_SIGNING_KEY holding the private key's PEM
text replaces --key. Details:
Packaging, signing and distribution.
For a first try without signing, package with --development instead of --key and start
rdownloader serve --plugin-development-mode, the only mode that accepts an unsigned package.
Install a signed package under Settings → Plugins → Add as an upload, or with
rdownloader plugin install mynotifier.rdplug --root data/plugins. Review before installing shows
every permission and the signing key; a key this installation has not seen asks to be trusted —
compare its fingerprint. The message after installing says whether the plugin runs at once or
after the next restart; see Installing and trust.
Create a target of the kind Plugin destination under Notifications, with your destination and its token, then send a test.
Publish the .rdplug together with your key's fingerprint, or — so that people get your new
versions in the Catalogue — in a plugin repository of your own: a signed index built with
rdownloader plugin index build and a repository-role key. A repository only delivers: every
package in it still needs your plugin key, approved by the person installing it. See
A repository index and
Running a plugin repository.
The SDK's reusable CI workflow,
sdk/ci/plugin.yml, builds,
checks the imports, packages and runs conformance on every push and pull request; it signs only
on a push to the default branch or a tag, so a pull request never sees the key.
- Notification destinations in the plugin reference — what the host does with each call, in full
-
Interface
notifier— every function and type, generated from the contract - Developing a plugin — the tools, translations, errors and what every type shares
-
The
notifiertemplate on GitHub