Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb69f18c39 | ||
|
|
fde5fda635 | ||
|
|
21990398c6 | ||
|
|
bbbab8d2ef | ||
|
|
ad057c12c0 | ||
|
|
e3bc92e158 | ||
|
|
45f94ead8b | ||
|
|
a56e1bf36d | ||
|
|
fa8a7ce43e |
@@ -2,17 +2,44 @@ before:
|
||||
hooks:
|
||||
- go mod download
|
||||
builds:
|
||||
- binary: ntfy
|
||||
-
|
||||
id: ntfy
|
||||
binary: ntfy
|
||||
env:
|
||||
- CGO_ENABLED=1 # required for go-sqlite3
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- amd64
|
||||
tags: [sqlite_omit_load_extension,osusergo,netgo]
|
||||
ldflags:
|
||||
- "-linkmode=external -extldflags=-static -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}"
|
||||
goos: [linux]
|
||||
goarch: [amd64]
|
||||
-
|
||||
id: ntfy_arm67
|
||||
binary: ntfy
|
||||
env:
|
||||
- CGO_ENABLED=1 # required for go-sqlite3
|
||||
- CC=arm-linux-gnueabi-gcc # apt install gcc-arm-linux-gnueabi
|
||||
tags: [sqlite_omit_load_extension,osusergo,netgo]
|
||||
ldflags:
|
||||
- "-linkmode=external -extldflags=-static -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}"
|
||||
goos: [linux]
|
||||
goarch: [arm]
|
||||
goarm:
|
||||
- 6
|
||||
- 7
|
||||
-
|
||||
id: ntfy_arm64
|
||||
binary: ntfy
|
||||
env:
|
||||
- CGO_ENABLED=1 # required for go-sqlite3
|
||||
- CC=aarch64-linux-gnu-gcc # apt install gcc-aarch64-linux-gnu
|
||||
tags: [sqlite_omit_load_extension,osusergo,netgo]
|
||||
ldflags:
|
||||
- "-linkmode=external -extldflags=-static -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}"
|
||||
goos: [linux]
|
||||
goarch: [arm64]
|
||||
nfpms:
|
||||
-
|
||||
package_name: ntfy
|
||||
file_name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Arch }}"
|
||||
homepage: https://heckel.io/ntfy
|
||||
maintainer: Philipp C. Heckel <philipp.heckel@gmail.com>
|
||||
description: Simple pub-sub notification service
|
||||
@@ -54,6 +81,8 @@ dockers:
|
||||
- dockerfile: Dockerfile
|
||||
ids:
|
||||
- ntfy
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
image_templates:
|
||||
- "binwiederhier/ntfy:latest"
|
||||
- "binwiederhier/ntfy:{{ .Tag }}"
|
||||
|
||||
25
Makefile
25
Makefile
@@ -61,6 +61,7 @@ coverage-html:
|
||||
coverage-upload:
|
||||
cd build/coverage && (curl -s https://codecov.io/bash | bash)
|
||||
|
||||
|
||||
# Lint/formatting targets
|
||||
|
||||
fmt:
|
||||
@@ -84,21 +85,27 @@ staticcheck: .PHONY
|
||||
PATH="$(PWD)/build/staticcheck:$(PATH)" staticcheck ./...
|
||||
rm -rf build/staticcheck
|
||||
|
||||
|
||||
# Building targets
|
||||
|
||||
build: .PHONY
|
||||
goreleaser build --rm-dist
|
||||
build-deps: .PHONY
|
||||
which arm-linux-gnueabi-gcc || { echo "ERROR: ARMv6/v7 cross compiler not installed. On Ubuntu, run: apt install gcc-arm-linux-gnueabi"; exit 1; }
|
||||
which aarch64-linux-gnu-gcc || { echo "ERROR: ARM64 cross compiler not installed. On Ubuntu, run: apt install gcc-aarch64-linux-gnu"; exit 1; }
|
||||
|
||||
build-snapshot:
|
||||
goreleaser build --snapshot --rm-dist
|
||||
build: build-deps
|
||||
goreleaser build --rm-dist --debug
|
||||
|
||||
build-snapshot: build-deps
|
||||
goreleaser build --snapshot --rm-dist --debug
|
||||
|
||||
build-simple: clean
|
||||
mkdir -p dist/ntfy_linux_amd64
|
||||
export CGO_ENABLED=1
|
||||
$(GO) build \
|
||||
-o dist/ntfy_linux_amd64/ntfy \
|
||||
-tags sqlite_omit_load_extension,osusergo,netgo \
|
||||
-ldflags \
|
||||
"-s -w -X main.version=$(VERSION) -X main.commit=$(shell git rev-parse --short HEAD) -X main.date=$(shell date +%s)"
|
||||
"-linkmode=external -extldflags=-static -s -w -X main.version=$(VERSION) -X main.commit=$(shell git rev-parse --short HEAD) -X main.date=$(shell date +%s)"
|
||||
|
||||
clean: .PHONY
|
||||
rm -rf dist build
|
||||
@@ -106,11 +113,11 @@ clean: .PHONY
|
||||
|
||||
# Releasing targets
|
||||
|
||||
release:
|
||||
goreleaser release --rm-dist
|
||||
release: build-deps
|
||||
goreleaser release --rm-dist --debug
|
||||
|
||||
release-snapshot:
|
||||
goreleaser release --snapshot --skip-publish --rm-dist
|
||||
release-snapshot: build-deps
|
||||
goreleaser release --snapshot --skip-publish --rm-dist --debug
|
||||
|
||||
|
||||
# Installing targets
|
||||
|
||||
46
README.md
46
README.md
@@ -2,7 +2,7 @@
|
||||
|
||||
# ntfy.sh | simple HTTP-based pub-sub
|
||||
|
||||
**Ntfy** (pronounce: *notify*) is a simple HTTP-based [pub-sub](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) notification service.
|
||||
**ntfy** (pronounce: *notify*) is a simple HTTP-based [pub-sub](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) notification service.
|
||||
It allows you to **send notifications to your phone or desktop via scripts** from any computer, entirely **without signup or cost**.
|
||||
It's also open source (as you can plainly see) if you want to run your own.
|
||||
|
||||
@@ -136,19 +136,29 @@ sudo apt install ntfy
|
||||
|
||||
**Debian/Ubuntu** (*manual install*)**:**
|
||||
```bash
|
||||
sudo apt install tmux
|
||||
wget https://github.com/binwiederhier/ntfy/releases/download/v1.4.3/ntfy_1.3.0_amd64.deb
|
||||
dpkg -i ntfy_1.4.3_amd64.deb
|
||||
wget https://github.com/binwiederhier/ntfy/releases/download/v1.4.6/ntfy_1.4.6_amd64.deb
|
||||
dpkg -i ntfy_1.4.6_amd64.deb
|
||||
```
|
||||
|
||||
**Fedora/RHEL/CentOS:**
|
||||
```bash
|
||||
rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v1.4.3/ntfy_1.3.0_amd64.rpm
|
||||
rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v1.4.6/ntfy_1.4.6_amd64.rpm
|
||||
```
|
||||
|
||||
**Docker:**
|
||||
Without cache:
|
||||
```
|
||||
docker run -p 80:80 -it binwiederhier/ntfy
|
||||
```
|
||||
|
||||
With cache:
|
||||
```bash
|
||||
docker run --rm -it binwiederhier/ntfy
|
||||
docker run \
|
||||
-v /var/cache/ntfy:/var/cache/ntfy \
|
||||
-p 80:80 \
|
||||
-it \
|
||||
binwiederhier/ntfy \
|
||||
--cache-file /var/cache/ntfy/cache.db
|
||||
```
|
||||
|
||||
**Go:**
|
||||
@@ -156,15 +166,27 @@ docker run --rm -it binwiederhier/ntfy
|
||||
go get -u heckel.io/ntfy
|
||||
```
|
||||
|
||||
**Manual install** (*any x86_64-based Linux*)**:**
|
||||
**Manual install:**
|
||||
```bash
|
||||
wget https://github.com/binwiederhier/ntfy/releases/download/v1.4.3/ntfy_1.3.0_linux_x86_64.tar.gz
|
||||
sudo tar -C /usr/bin -zxf ntfy_1.4.3_linux_x86_64.tar.gz ntfy
|
||||
# x86_64/amd64
|
||||
wget https://github.com/binwiederhier/ntfy/releases/download/v1.4.6/ntfy_1.4.6_linux_x86_64.tar.gz
|
||||
|
||||
# ARMv6
|
||||
wget https://github.com/binwiederhier/ntfy/releases/download/v1.4.6/ntfy_1.4.6_linux_armv6.tar.gz
|
||||
|
||||
# ARMv7
|
||||
wget https://github.com/binwiederhier/ntfy/releases/download/v1.4.6/ntfy_1.4.6_linux_armv7.tar.gz
|
||||
|
||||
# arm64
|
||||
wget https://github.com/binwiederhier/ntfy/releases/download/v1.4.6/ntfy_1.4.6_linux_arm64.tar.gz
|
||||
|
||||
# Extract and run
|
||||
sudo tar -C /usr/bin -zxf ntfy_1.4.6_linux_x86_64.tar.gz ntfy
|
||||
./ntfy
|
||||
```
|
||||
|
||||
## Building
|
||||
Building ntfy is simple. Here's how you do it:
|
||||
Building `ntfy` is simple. Here's how you do it:
|
||||
|
||||
```
|
||||
make build-simple
|
||||
@@ -174,9 +196,6 @@ make build-simple
|
||||
To build releases, I use [GoReleaser](https://goreleaser.com/). If you have that installed, you can run `make build` or
|
||||
`make build-snapshot`.
|
||||
|
||||
## TODO
|
||||
- add HTTPS
|
||||
|
||||
## Contributing
|
||||
I welcome any and all contributions. Just create a PR or an issue.
|
||||
|
||||
@@ -192,3 +211,4 @@ Third party libraries and resources:
|
||||
* [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) (MIT) is used to provide the persistent message cache
|
||||
* [Firebase Admin SDK](https://github.com/firebase/firebase-admin-go) (Apache 2.0) is used to send FCM messages
|
||||
* [Lightbox with vanilla JS](https://yossiabramov.com/blog/vanilla-js-lightbox)
|
||||
* [Statically linking go-sqlite3](https://www.arp242.net/static-go.html)
|
||||
|
||||
@@ -67,19 +67,19 @@
|
||||
Here's an example showing how to publish a message using <tt>curl</tt> (via POST):
|
||||
</p>
|
||||
<code>
|
||||
curl -d "Backup successful 😀" ntfy.sh/mytopic
|
||||
curl -d "Backup successful 😀" <span class="ntfyUrl">ntfy.sh</span>/mytopic
|
||||
</code>
|
||||
<p class="smallMarginBottom">
|
||||
And another one using PUT:
|
||||
</p>
|
||||
<code>
|
||||
echo -en "\u26A0\uFE0F Unauthorized login" | curl -sT- ntfy.sh/mytopic
|
||||
echo -en "\u26A0\uFE0F Unauthorized login" | curl -sT- <span class="ntfyUrl">ntfy.sh</span>/mytopic
|
||||
</code>
|
||||
<p class="smallMarginBottom">
|
||||
Here's an example in JS with <tt>fetch()</tt> (see <a href="https://github.com/binwiederhier/ntfy/tree/main/examples">full example</a>):
|
||||
</p>
|
||||
<code>
|
||||
fetch('https://ntfy.sh/mytopic', {<br/>
|
||||
fetch('https://<span class="ntfyUrl">ntfy.sh</span>/mytopic', {<br/>
|
||||
method: 'POST', // PUT works too<br/>
|
||||
body: 'Hello from the other side.'<br/>
|
||||
})
|
||||
@@ -127,7 +127,7 @@
|
||||
notifications like this (see <a href="example.html">live example</a>):
|
||||
</p>
|
||||
<code>
|
||||
const eventSource = new EventSource('https://ntfy.sh/mytopic/sse');<br/>
|
||||
const eventSource = new EventSource('<span class="ntfyProtocol">https://</span><span class="ntfyUrl">ntfy.sh</span>/mytopic/sse');<br/>
|
||||
eventSource.onmessage = (e) => {<br/>
|
||||
// Do something with e.data<br/>
|
||||
};
|
||||
@@ -136,7 +136,7 @@
|
||||
You can also use the same <tt>/sse</tt> endpoint via <tt>curl</tt> or any other HTTP library:
|
||||
</p>
|
||||
<code>
|
||||
$ curl -s ntfy.sh/mytopic/sse<br/>
|
||||
$ curl -s <span class="ntfyUrl">ntfy.sh</span>/mytopic/sse<br/>
|
||||
event: open<br/>
|
||||
data: {"id":"weSj9RtNkj","time":1635528898,"event":"open","topic":"mytopic"}<br/><br/>
|
||||
|
||||
@@ -149,7 +149,7 @@
|
||||
To consume JSON instead, use the <tt>/json</tt> endpoint, which prints one message per line:
|
||||
</p>
|
||||
<code>
|
||||
$ curl -s ntfy.sh/mytopic/json<br/>
|
||||
$ curl -s <span class="ntfyUrl">ntfy.sh</span>/mytopic/json<br/>
|
||||
{"id":"SLiKI64DOt","time":1635528757,"event":"open","topic":"mytopic"}<br/>
|
||||
{"id":"hwQ2YpKdmg","time":1635528741,"event":"message","topic":"mytopic","message":"Hi!"}<br/>
|
||||
{"id":"DGUDShMCsc","time":1635528787,"event":"keepalive","topic":"mytopic"}
|
||||
@@ -158,7 +158,7 @@
|
||||
Or use the <tt>/raw</tt> endpoint if you need something super simple (empty lines are keepalive messages):
|
||||
</p>
|
||||
<code>
|
||||
$ curl -s ntfy.sh/mytopic/raw<br/>
|
||||
$ curl -s <span class="ntfyUrl">ntfy.sh</span>/mytopic/raw<br/>
|
||||
<br/>
|
||||
This is a notification<br/>
|
||||
And another one with a smiley face 😀
|
||||
@@ -173,7 +173,7 @@
|
||||
cached messages).
|
||||
</p>
|
||||
<code>
|
||||
curl -s "ntfy.sh/mytopic/json?since=10m"
|
||||
curl -s "<span class="ntfyUrl">ntfy.sh</span>/mytopic/json?since=10m"
|
||||
</code>
|
||||
|
||||
<h3 id="polling" class="anchor">Polling (<tt>poll=1</tt>)</h3>
|
||||
@@ -183,7 +183,7 @@
|
||||
combined with <tt>since=</tt> (defaults to <tt>since=all</tt>).
|
||||
</p>
|
||||
<code>
|
||||
curl -s "ntfy.sh/mytopic/json?poll=1"
|
||||
curl -s "<span class="ntfyUrl">ntfy.sh</span>/mytopic/json?poll=1"
|
||||
</code>
|
||||
|
||||
<h3 id="multiple-topics" class="anchor">Subscribing to multiple topics (<tt>topic1,topic2,...</tt>)</h3>
|
||||
@@ -192,7 +192,7 @@
|
||||
comma-separated list of topics in the URL. This allows you to reduce the number of connections you have to maintain:
|
||||
</p>
|
||||
<code>
|
||||
$ curl -s ntfy.sh/mytopic1,mytopic2/json<br/>
|
||||
$ curl -s <span class="ntfyUrl">ntfy.sh</span>/mytopic1,mytopic2/json<br/>
|
||||
{"id":"0OkXIryH3H","time":1637182619,"event":"open","topic":"mytopic1,mytopic2,mytopic3"}<br/>
|
||||
{"id":"dzJJm7BCWs","time":1637182634,"event":"message","topic":"mytopic1","message":"for topic 1"}<br/>
|
||||
{"id":"Cm02DsxUHb","time":1637182643,"event":"message","topic":"mytopic2","message":"for topic 2"}
|
||||
@@ -214,8 +214,8 @@
|
||||
<code>
|
||||
rsync -a root@laptop /backups/laptop \<br/>
|
||||
&& zfs snapshot ... \<br/>
|
||||
&& curl -d "Laptop backup succeeded" ntfy.sh/backups \<br/>
|
||||
|| echo -en "\u26A0\uFE0F Laptop backup failed" | curl -sT- ntfy.sh/backups
|
||||
&& curl -d "Laptop backup succeeded" <span class="ntfyUrl">ntfy.sh</span>/backups \<br/>
|
||||
|| echo -en "\u26A0\uFE0F Laptop backup failed" | curl -sT- <span class="ntfyUrl">ntfy.sh</span>/backups
|
||||
</code>
|
||||
|
||||
<h3 id="example-web" class="anchor">Example: Server-sent messages in your web app</h3>
|
||||
@@ -242,7 +242,7 @@
|
||||
<code>
|
||||
#!/bin/bash<br/>
|
||||
if [ "${PAM_TYPE}" = "open_session" ]; then<br/>
|
||||
echo -en "\u26A0\uFE0F SSH login: ${PAM_USER} from ${PAM_RHOST}" | curl -T- ntfy.sh/alerts<br/>
|
||||
echo -en "\u26A0\uFE0F SSH login: ${PAM_USER} from ${PAM_RHOST}" | curl -T- <span class="ntfyUrl">ntfy.sh</span>/alerts<br/>
|
||||
fi
|
||||
</code>
|
||||
|
||||
@@ -254,7 +254,7 @@
|
||||
<code>
|
||||
while read result; do<br/>
|
||||
[ -n "$result" ] && echo "$result" >> results.csv<br/>
|
||||
done < <(stdbuf -i0 -o0 curl -s ntfy.sh/results/raw)
|
||||
done < <(stdbuf -i0 -o0 curl -s <span class="ntfyUrl">ntfy.sh</span>/results/raw)
|
||||
</code>
|
||||
|
||||
<h2 id="faq" class="anchor">FAQ</h2>
|
||||
@@ -331,7 +331,7 @@
|
||||
To send notifications to it, simply PUT or POST to the topic URL. Here's an example using <tt>curl</tt>:
|
||||
</p>
|
||||
<code>
|
||||
curl -d "Backup failed" <span id="detailTopicUrl"></span>
|
||||
curl -d "Backup failed" <span id="detailTopicUrl">ntfy.sh/topic</span>
|
||||
</code>
|
||||
<p id="detailNotificationsDisallowed">
|
||||
If you'd like to receive desktop notifications when new messages arrive on this topic, you have
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
let topics = {};
|
||||
let currentTopic = "";
|
||||
let currentTopicUnsubscribeOnClose = false;
|
||||
let currentUrl = window.location.hostname;
|
||||
if (window.location.port) {
|
||||
currentUrl += ':' + window.location.port
|
||||
}
|
||||
|
||||
/* Main view */
|
||||
const main = document.getElementById("main");
|
||||
@@ -131,15 +135,15 @@ const fetchCachedMessages = async (topic) => {
|
||||
|
||||
const showDetail = (topic) => {
|
||||
currentTopic = topic;
|
||||
history.replaceState(topic, `ntfy.sh/${topic}`, `/${topic}`);
|
||||
history.replaceState(topic, `${currentUrl}/${topic}`, `/${topic}`);
|
||||
window.scrollTo(0, 0);
|
||||
rerenderDetailView();
|
||||
return false;
|
||||
};
|
||||
|
||||
const rerenderDetailView = () => {
|
||||
detailTitle.innerHTML = `ntfy.sh/${currentTopic}`; // document.location.replaceAll(..)
|
||||
detailTopicUrl.innerHTML = `ntfy.sh/${currentTopic}`;
|
||||
detailTitle.innerHTML = `${currentUrl}/${currentTopic}`; // document.location.replaceAll(..)
|
||||
detailTopicUrl.innerHTML = `${currentUrl}/${currentTopic}`;
|
||||
while (detailEventsList.firstChild) {
|
||||
detailEventsList.removeChild(detailEventsList.firstChild);
|
||||
}
|
||||
@@ -347,3 +351,11 @@ document.querySelectorAll('.anchor').forEach((el) => {
|
||||
el.appendChild(anchor);
|
||||
}
|
||||
});
|
||||
|
||||
// Change ntfy.sh url and protocol to match self-hosted one
|
||||
document.querySelectorAll('.ntfyUrl').forEach((el) => {
|
||||
el.innerHTML = currentUrl;
|
||||
});
|
||||
document.querySelectorAll('.ntfyProtocol').forEach((el) => {
|
||||
el.innerHTML = window.location.protocol + "//";
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user