Files
navidrome/plugins/examples/README.md

181 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Navidrome Plugin Examples
This folder contains example plugins demonstrating various capabilities and languages supported by Navidrome's plugin system.
## Available Examples
| Plugin | Language | Capabilities | Description |
|-------------------------------------------------------|----------|-------------------------------------------------|--------------------------------|
| [minimal](minimal/) | Go | MetadataAgent | Basic plugin structure |
| [wikimedia](wikimedia/) | Go | MetadataAgent | Wikidata/Wikipedia metadata |
| [crypto-ticker](crypto-ticker/) | Go | Scheduler, WebSocket, Cache | Real-time crypto prices (demo) |
| [coverartarchive-py](coverartarchive-py/) | Python | MetadataAgent | Cover Art Archive |
| [nowplaying-py](nowplaying-py/) | Python | Scheduler, SubsonicAPI | Now playing logger |
| [webhook-rs](webhook-rs/) | Rust | Scrobbler | HTTP webhook on scrobble |
| [library-inspector-rs](library-inspector-rs/) | Rust | Library, Scheduler | Periodic library stats logging |
| [discord-rich-presence-rs](discord-rich-presence-rs/) | Rust | Scrobbler, Scheduler, WebSocket, Cache, Artwork | Discord integration (Rust) |
## Building
### Prerequisites
- **Go plugins:** [TinyGo](https://tinygo.org/getting-started/install/) 0.30+
- **Python plugins:** [extism-py](https://github.com/extism/python-pdk)
- **Rust plugins:** [Rust](https://rustup.rs/) with `wasm32-unknown-unknown` target
### Build All Plugins
```bash
make all
```
This creates `.ndp` package files for each plugin.
### Build Individual Plugin
```bash
make minimal.ndp
make wikimedia.ndp
make discord-rich-presence-rs.ndp
```
### Clean
```bash
make clean
```
## Testing Plugins
### With Extism CLI
Test any plugin without running Navidrome. First extract the `.wasm` file from the `.ndp` package:
```bash
# Install: https://extism.org/docs/install
# Extract the wasm file from the package
unzip -p minimal.ndp plugin.wasm > minimal.wasm
# Test a capability function
extism call minimal.wasm nd_get_artist_biography --wasi \
--input '{"id":"1","name":"The Beatles"}'
```
For plugins that make HTTP requests, allow the hosts:
```bash
unzip -p wikimedia.ndp plugin.wasm > wikimedia.wasm
extism call wikimedia.wasm nd_get_artist_biography --wasi \
--input '{"id":"1","name":"Yussef Dayes"}' \
--allow-host "query.wikidata.org" \
--allow-host "en.wikipedia.org"
```
### With Navidrome
1. Copy the `.ndp` file to your plugins folder
2. Enable plugins in `navidrome.toml`:
```toml
[Plugins]
Enabled = true
Folder = "/path/to/plugins"
```
3. For metadata agents, add to your agents list:
```toml
Agents = "lastfm,spotify,wikimedia"
```
## Creating Your Own Plugin
### Option 1: Start from Minimal
Copy the [minimal](minimal/) example and modify:
```bash
cp -r minimal my-plugin
cd my-plugin
# Edit main.go and manifest.json
tinygo build -o plugin.wasm -target wasip1 -buildmode=c-shared .
zip -j my-plugin.ndp manifest.json plugin.wasm
```
### Option 2: Bootstrap with XTP CLI
Generate boilerplate from a schema:
```bash
# Install XTP: https://docs.xtp.dylibso.com/docs/cli
xtp plugin init \
--schema-file ../schemas/metadata_agent.yaml \
--template go \
--path ./my-plugin \
--name my-plugin
# Then create manifest.json and package
cd my-plugin
xtp plugin build
zip -j my-plugin.ndp manifest.json dist/plugin.wasm
```
Available schemas in [../schemas/](../schemas/):
- `metadata_agent.yaml` Artist/album metadata
- `scrobbler.yaml` Scrobbling integration
- `lifecycle.yaml` Init callbacks
- `scheduler_callback.yaml` Scheduled tasks
- `websocket_callback.yaml` WebSocket events
### Option 3: Different Language
See language-specific examples:
- **Python:** [coverartarchive-py](coverartarchive-py/)
- **Rust:** [webhook-rs](webhook-rs/)
## Example Breakdown
### Minimal (Go)
The simplest possible plugin. Shows:
- Manifest export
- Single capability function
- Basic input/output handling
### Wikimedia (Go)
Real-world metadata agent. Shows:
- HTTP requests to external APIs
- SPARQL queries (Wikidata)
- Error handling
- Host allowlisting
### Discord Rich Presence (Go)
Complex multi-capability plugin. Shows:
- **Scrobbler** Receives play events
- **WebSocket** Maintains Discord gateway connection
- **Scheduler** Heartbeat and timeout management
- **Cache** Connection state storage
- **Artwork** Getting album art URLs
### Cover Art Archive (Python)
Python metadata agent. Shows:
- extism-py plugin structure
- HTTP requests
- JSON handling
### Webhook (Rust)
Rust scrobbler. Shows:
- extism-rs plugin structure
- HTTP POST requests
- Minimal dependencies
## Resources
- [Plugin System Documentation](../README.md)
- [Extism PDK Docs](https://extism.org/docs/concepts/pdk)
- [TinyGo WebAssembly](https://tinygo.org/docs/guides/webassembly/)
- [XTP CLI](https://docs.xtp.dylibso.com/docs/cli)