Holler

URL-based notification library for Elixir — send notifications to 18 services with a single URL string. An Elixir port of shoutrrr.

Installation

Add holler to your dependencies in mix.exs:

def deps do
  [
    {:holler, "~> 0.2"}
  ]
end

Usage

Send to a single service

Holler.send("gotify://example.com/AqEtoken123456", "Hello from Holler!")
# => :ok

Send to multiple services concurrently

urls = [
  "gotify://example.com/AqEtoken123456",
  "slack://hook:TXXXXXXXX/BXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX",
  "telegram://123456789:AABBccdd@telegram?chats=-100123456789"
]

{:ok, sender} = Holler.create_sender(urls)
Holler.Sender.send(sender, "Deploy complete!")
# => [:ok, :ok, :ok]

Override per-send params

Holler.send(
  "ntfy://ntfy.sh/my-topic",
  "Disk usage at 95%",
  %{title: "Warning", priority: "high"}
)

Supported services

Service URL scheme Example URL
Bark barkbark://:devicekey@api.day.app
Discord discorddiscord://token@webhook_id
Generic genericgeneric://example.com/webhook
Google Chat googlechatgooglechat://chat.googleapis.com/v1/spaces/FOO/messages?key=bar&token=baz
Gotify gotifygotify://example.com/AqEtoken123456
IFTTT iftttifttt://webhookkey/?events=myevent
Join joinjoin://shoutrrr:apikey@join/?devices=device1
Matrix matrixmatrix://:accesstoken@matrix.example.com/
Mattermost mattermostmattermost://example.com/webhooktoken
Ntfy ntfyntfy://ntfy.sh/my-topic
OpsGenie opsgenieopsgenie://api.opsgenie.com/myapikey
Pushbullet pushbulletpushbullet://myapitoken
Pushover pushoverpushover://shoutrrr:token@userkey/
Rocket.Chat rocketchatrocketchat://example.com/tokenA/tokenB/general
Slack slackslack://hook:TXXXXXXXX/BXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX
Teams teamsteams://group@tenant/altId/groupOwner?host=org.webhook.office.com
Telegram telegramtelegram://botid:token@telegram?chats=@mychannel
Zulip zulipzulip://bot%40example.com:apikey@org.zulipchat.com/?stream=general
Mercure mercuremercure://:jwt@example.com?topic=https://example.com/books/1

API

Holler.send/3

@spec send(url :: String.t(), message :: String.t(), params :: map()) ::
  :ok | {:error, term()}

Parses url, initialises the matching service, and sends message in one step. params is merged into the config and can override per-call options like title or priority.

Holler.create_sender/1

@spec create_sender([String.t()]) :: {:ok, Holler.Sender.t()} | {:error, term()}

Parses and initialises all URLs upfront. Returns a Holler.Sender struct that can be reused to send to all configured services concurrently.

Holler.Sender.send/2

@spec send(Holler.Sender.t(), message :: String.t(), params :: map()) ::
  [:ok | {:error, term()}]

Sends message to all services in the sender concurrently using Task.async_stream. Returns a list of results in the same order as the URLs passed to create_sender/1.

License

MIT — see LICENSE.