A notification library for gophers and their furry friends.
Heavily inspired by caronc/apprise.
- Full Documentation
- Installation
- Usage
- Supported Services
- Contributors ✨
- Related Project(s)
Visit the project's GitHub Page for full documentation.
go install github.com/nicholas-fedor/shoutrrr/shoutrrr@latestInstall the latest release binary to $HOME/go/bin (ensure it's in your PATH).
-
Windows (amd64):
New-Item -ItemType Directory -Path $HOME\go\bin -Force | Out-Null; iwr (iwr https://api.github.com/repos/nicholas-fedor/shoutrrr/releases/latest | ConvertFrom-Json).assets.where({$_.name -like "*windows_amd64*.zip"}).browser_download_url -OutFile shoutrrr.zip; Add-Type -AssemblyName System.IO.Compression.FileSystem; ($z=[System.IO.Compression.ZipFile]::OpenRead("$PWD\shoutrrr.zip")).Entries | ? {$_.Name -eq 'shoutrrr.exe'} | % {[System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, "$HOME\go\bin\$($_.Name)", $true)}; $z.Dispose(); rm shoutrrr.zip; if (Test-Path "$HOME\go\bin\shoutrrr.exe") { Write-Host "Successfully installed shoutrrr.exe to $HOME\go\bin" } else { Write-Host "Failed to install shoutrrr.exe" }
-
Linux (amd64):
mkdir -p $HOME/go/bin && curl -L $(curl -s https://api.github.com/repos/nicholas-fedor/shoutrrr/releases/latest | grep -o 'https://[^"]*linux_amd64[^"]*\.tar\.gz"' | grep -o 'https://[^"]*' | head -n1) | tar -xz -C $HOME/go/bin shoutrrr
-
macOS (amd64):
mkdir -p $HOME/go/bin && curl -L $(curl -s https://api.github.com/repos/nicholas-fedor/shoutrrr/releases/latest | grep -o 'https://[^"]*macOS_amd64[^"]*\.tar\.gz"' | grep -o 'https://[^"]*' | head -n1) | tar -xz -C $HOME/go/bin shoutrrr
Note
Visit the releases page for other architectures (e.g., arm, arm64, i386, riscv64).
-
docker pull nickfedor/shoutrrr:latest
-
GHCR:
docker pull ghcr.io/nicholas-fedor/shoutrrr:latest
Note
Tags: latest (stable), vX.Y.Z (specific version), nightly (development), platform-specific (e.g., amd64-nightly).
go get github.com/nicholas-fedor/shoutrrr@latest- name: Shoutrrr
uses: nicholas-fedor/shoutrrr-action@v1
with:
url: ${{ secrets.SHOUTRRR_URL }}
title: Deployed ${{ github.sha }}
message: See changes at ${{ github.event.compare }}.shoutrrr send --url "slack://hook:T00000000-B00000000-XXXXXXXXXXXXXXXXXXXXXXXX@webhook" --message "Hello, Slack!"import "github.com/nicholas-fedor/shoutrrr"
errs := shoutrrr.Send("slack://hook:T00000000-B00000000-XXXXXXXXXXXXXXXXXXXXXXXX@webhook", "Hello, Slack!")
if len(errs) > 0 {
// Handle errors
}docker run --rm nickfedor/shoutrrr:latest send --url "slack://hook:T00000000-B00000000-XXXXXXXXXXXXXXXXXXXXXXXX@webhook" --message "Hello, Slack!"See installation example above.
url := "slack://token-a/token-b/token-c"
err := shoutrrr.Send(url, "Hello world (or slack channel) !")url := "slack://token-a/token-b/token-c"
sender, err := shoutrrr.CreateSender(url)
params := types.Params{}
sender.Send("Hello world (or slack channel) !", ¶ms)urls := []string {
"slack://token-a/token-b/token-c"
"discord://token@channel"
}
sender, err := shoutrrr.CreateSender(urls...)
params := types.Params{}
sender.Send("Hello world (or slack channel) !", ¶ms)import (
"crypto/tls"
"log"
"net/http"
"github.com/nicholas-fedor/shoutrrr"
"github.com/nicholas-fedor/shoutrrr/pkg/types"
)
customClient := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{MinVersion: tls.VersionTLS12},
},
}
sender, err := shoutrrr.NewSenderWithOptions(
nil,
types.SenderOptions{HTTPClient: customClient},
"discord://token@channel",
)
if err != nil {
log.Fatal(err)
}
sender.Send("Hello with custom egress!", nil)Services that support severity or priority can receive a semantic level through the level param.
Shoutrrr defines five levels: Unknown, Debug, Info, Warning, and Error. The default is Info.
params := types.Params{}
params.SetLevel(types.Warning)
params.SetTitle("Disk usage high")
errs := sender.Send("Root partition at 92%", ¶ms)Services that implement types.RichSender (such as Discord) receive the full []types.MessageItem slice when using SendItems, preserving level, fields, and file attachments.
Services that do not implement RichSender fall back to plain text automatically.
Sender.Send, *ServiceRouter.SendAsync, and *ServiceRouter.SendItems return one error per unique configured target, in the deduplicated target order produced by CreateSender. Each error is wrapped in *types.TargetError, which carries the service URL/ID and supports errors.Unwrap, errors.Is, and errors.As:
errs := sender.Send("deploy complete", nil)
for i, err := range errs {
if err == nil {
continue
}
var targetErr *types.TargetError
if errors.As(err, &targetErr) {
log.Printf("failed to send to %s: %v", targetErr.URL, targetErr.Err)
}
}Services that implement types.ContextSender or types.ContextAttachmentSender receive a context.Context derived from the router's base context with a per-service timeout.
This enables cancellation and deadline propagation without changing the existing Sender or RichSender contracts.
import "github.com/nicholas-fedor/shoutrrr/pkg/format"
body, err := format.ConvertFormat("Hello **world**", "markdown", "text")Supported conversions: text ↔ markdown ↔ html.
shoutrrr send [OPTIONS] <URL> <Message [...]>You can also use Shoutrrr in a GitHub Actions workflow.
name: Deploy
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- [Your other workflow steps]
- name: Shoutrrr
uses: nicholas-fedor/shoutrrr-action@v0.0.11
with:
url: ${{ secrets.SHOUTRRR_URL }}
title: Deployed ${{ github.sha }}
message: See changes at ${{ github.event.compare }}.| Service | Description |
|---|---|
| Bark | iOS push notifications |
| Discord | Discord webhooks |
| Generic | Custom HTTP webhooks |
| Google Chat | Google Chat webhooks |
| Gotify | Gotify push notifications |
| IFTTT | IFTTT webhooks |
| Join | Join push notifications |
| Lark | Lark (Feishu) webhooks |
| Logger | Local logging (for testing) |
| Matrix | Matrix rooms |
| Mattermost | Mattermost webhooks |
| MQTT | MQTT message broker |
| Notifiarr | Notifiarr message forwarding |
| Ntfy | Ntfy push notifications |
| Opsgenie | Opsgenie alerts |
| PagerDuty | PagerDuty incident notifications |
| Pushbullet | Pushbullet push notifications |
| Pushover | Pushover push notifications |
| Rocket.Chat | Rocket.Chat webhooks |
| Slack | Slack webhooks or Bot API |
| SMTP | Email notifications |
| Teams | Microsoft Teams webhooks |
| Telegram | Telegram bots |
| Twilio | Twilio SMS notifications |
| Zulip | Zulip chat |
| XMPP | XMPP messages (if enabled) |
Use services.SupportedSchemas() and services.SupportsSchema(schema) to enumerate or check available notification services without constructing a router:
import "github.com/nicholas-fedor/shoutrrr/pkg/services"
for _, schema := range services.SupportedSchemas() {
fmt.Println(schema)
}
if services.SupportsSchema("discord") {
// ...
}Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!
- Watchtower - Automate Docker container image updates.
- Shoutrrr GitHub Action - Notifications using Shoutrrr in GitHub Actions.
- Bezel - A lightweight server monitoring platform that includes Docker statistics, historical data, and alert functions.
- WatchYourLAN - Lightweight network IP scanner with web GUI.
- DNSControl- Infrastructure as code for DNS.
- docker-volume-backup - Backup Docker volumes locally or to any S3, WebDAV, Azure Blob Storage, Dropbox, Google Drive or SSH compatible storage.
- BirdNET-Go - An AI solution for continuous avian monitoring and identification.