parent
d6fbccab55
commit
f966b2f9d7
|
@ -64,5 +64,14 @@ It looked something like this:
|
|||
curl -d "$(hostname),$count,$time" ntfy.sh/results
|
||||
```
|
||||
|
||||
## Ansible, Salt and Puppet
|
||||
You can easily integrate ntfy into Ansible, Salt, or Puppet to notify you when runs are done or are highstated.
|
||||
One of my co-workers uses the following Ansible task to let him know when things are done:
|
||||
|
||||
|
||||
```yml
|
||||
- name: Send ntfy.sh update
|
||||
uri:
|
||||
url: "https://ntfy.sh/{{ ntfy_channel }}"
|
||||
method: POST
|
||||
body: "{{ inventory_hostname }} reseeding complete"
|
||||
```
|
||||
|
|
|
@ -332,7 +332,14 @@ them with a comma, e.g. `tag1,tag2,tag3`.
|
|||
<figcaption>Detail view of notifications with tags</figcaption>
|
||||
</figure>
|
||||
|
||||
## Message caching
|
||||
## Advanced features
|
||||
|
||||
### Message caching
|
||||
!!! info
|
||||
If `Cache: no` is used, messages will only be delivered to connected subscribers, and won't be re-delivered if a
|
||||
client re-connects. If a subscriber has (temporary) network issues or is reconnecting momentarily,
|
||||
**messages might be missed**.
|
||||
|
||||
By default, the ntfy server caches messages on disk for 12 hours (see [message caching](config.md#message-cache)), so
|
||||
all messages you publish are stored server-side for a little while. The reason for this is to overcome temporary
|
||||
client-side network disruptions, but arguably this feature also may raise privacy concerns.
|
||||
|
@ -385,3 +392,61 @@ are still delivered to connected subscribers, but [`since=`](subscribe/api.md#fe
|
|||
]
|
||||
]));
|
||||
```
|
||||
|
||||
### Firebase
|
||||
!!! info
|
||||
If `Firebase: no` is used and [instant delivery](subscribe/phone.md#instant-delivery) isn't enabled in the Android
|
||||
app (Google Play variant only), **message delivery will be significantly delayed (up to 15 minutes)**. To overcome
|
||||
this delay, simply enable instant delivery.
|
||||
|
||||
The ntfy server can be configured to use [Firebase Cloud Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging)
|
||||
(see [Firebase config](config.md#firebase-fcm)) for message delivery on Android (to minimize the app's battery footprint).
|
||||
The ntfy.sh server is configured this way, meaning that all messages published to ntfy.sh are also published to corresponding
|
||||
FCM topics.
|
||||
|
||||
If you'd like to avoid forwarding messages to Firebase, you can set the `X-Firebase` header (or its alias: `Firebase`)
|
||||
to `no`. This will instruct the server not to forward messages to Firebase.
|
||||
|
||||
=== "Command line (curl)"
|
||||
```
|
||||
curl -H "X-Firebase: no" -d "This message won't be forwarded to FCM" ntfy.sh/mytopic
|
||||
curl -H "Firebase: no" -d "This message won't be forwarded to FCM" ntfy.sh/mytopic
|
||||
```
|
||||
|
||||
=== "HTTP"
|
||||
``` http
|
||||
POST /mytopic HTTP/1.1
|
||||
Host: ntfy.sh
|
||||
Firebase: no
|
||||
|
||||
This message won't be forwarded to FCM
|
||||
```
|
||||
|
||||
=== "JavaScript"
|
||||
``` javascript
|
||||
fetch('https://ntfy.sh/mytopic', {
|
||||
method: 'POST',
|
||||
body: 'This message won't be forwarded to FCM',
|
||||
headers: { 'Firebase': 'no' }
|
||||
})
|
||||
```
|
||||
|
||||
=== "Go"
|
||||
``` go
|
||||
req, _ := http.NewRequest("POST", "https://ntfy.sh/mytopic", strings.NewReader("This message won't be forwarded to FCM"))
|
||||
req.Header.Set("Firebase", "no")
|
||||
http.DefaultClient.Do(req)
|
||||
```
|
||||
|
||||
=== "PHP"
|
||||
``` php-inline
|
||||
file_get_contents('https://ntfy.sh/mytopic', false, stream_context_create([
|
||||
'http' => [
|
||||
'method' => 'POST',
|
||||
'header' =>
|
||||
"Content-Type: text/plain\r\n" .
|
||||
"Firebase: no",
|
||||
'content' => 'This message won't be stored server-side'
|
||||
]
|
||||
]));
|
||||
```
|
||||
|
|
|
@ -128,11 +128,6 @@ func New(conf *config.Config) (*Server, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, t := range topics {
|
||||
if firebaseSubscriber != nil {
|
||||
t.Subscribe(firebaseSubscriber)
|
||||
}
|
||||
}
|
||||
return &Server{
|
||||
config: conf,
|
||||
cache: cache,
|
||||
|
@ -284,13 +279,20 @@ func (s *Server) handlePublish(w http.ResponseWriter, r *http.Request, _ *visito
|
|||
if m.Message == "" {
|
||||
return errHTTPBadRequest
|
||||
}
|
||||
title, priority, tags, cache := parseHeaders(r.Header)
|
||||
title, priority, tags, cache, firebase := parseHeaders(r.Header)
|
||||
m.Title = title
|
||||
m.Priority = priority
|
||||
m.Tags = tags
|
||||
if err := t.Publish(m); err != nil {
|
||||
return err
|
||||
}
|
||||
if s.firebase != nil && firebase {
|
||||
go func() {
|
||||
if err := s.firebase(m); err != nil {
|
||||
log.Printf("Unable to publish to Firebase: %v", err.Error())
|
||||
}
|
||||
}()
|
||||
}
|
||||
if cache {
|
||||
if err := s.cache.AddMessage(m); err != nil {
|
||||
return err
|
||||
|
@ -306,7 +308,7 @@ func (s *Server) handlePublish(w http.ResponseWriter, r *http.Request, _ *visito
|
|||
return nil
|
||||
}
|
||||
|
||||
func parseHeaders(header http.Header) (title string, priority int, tags []string, cache bool) {
|
||||
func parseHeaders(header http.Header) (title string, priority int, tags []string, cache bool, firebase bool) {
|
||||
title = readHeader(header, "x-title", "title", "ti", "t")
|
||||
priorityStr := readHeader(header, "x-priority", "priority", "prio", "p")
|
||||
if priorityStr != "" {
|
||||
|
@ -333,7 +335,8 @@ func parseHeaders(header http.Header) (title string, priority int, tags []string
|
|||
}
|
||||
}
|
||||
cache = readHeader(header, "x-cache", "cache") != "no"
|
||||
return title, priority, tags, cache
|
||||
firebase = readHeader(header, "x-firebase", "firebase") != "no"
|
||||
return title, priority, tags, cache, firebase
|
||||
}
|
||||
|
||||
func readHeader(header http.Header, names ...string) string {
|
||||
|
@ -512,9 +515,6 @@ func (s *Server) topicsFromIDs(ids ...string) ([]*topic, error) {
|
|||
return nil, errHTTPTooManyRequests
|
||||
}
|
||||
s.topics[id] = newTopic(id)
|
||||
if s.firebase != nil {
|
||||
s.topics[id].Subscribe(s.firebase)
|
||||
}
|
||||
}
|
||||
topics = append(topics, s.topics[id])
|
||||
}
|
||||
|
@ -547,7 +547,7 @@ func (s *Server) updateStatsAndExpire() {
|
|||
log.Printf("cannot get stats for topic %s: %s", t.ID, err.Error())
|
||||
continue
|
||||
}
|
||||
if msgs == 0 && (subs == 0 || (s.firebase != nil && subs == 1)) { // Firebase is a subscriber!
|
||||
if msgs == 0 && subs == 0 {
|
||||
delete(s.topics, t.ID)
|
||||
continue
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue