73 lines
1.9 KiB
Go
73 lines
1.9 KiB
Go
package ntfy
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"bytes"
|
||
|
|
"encoding/json"
|
||
|
|
"fmt"
|
||
|
|
"io"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Event is one NDJSON object from GET /topic/json.
|
||
|
|
type Event struct {
|
||
|
|
ID string `json:"id"`
|
||
|
|
Time int64 `json:"time"`
|
||
|
|
Expires int64 `json:"expires,omitempty"`
|
||
|
|
Event string `json:"event"`
|
||
|
|
Topic string `json:"topic"`
|
||
|
|
Message string `json:"message"`
|
||
|
|
Title string `json:"title"`
|
||
|
|
Tags []string `json:"tags"`
|
||
|
|
Priority int `json:"priority"`
|
||
|
|
Click string `json:"click"`
|
||
|
|
SequenceID string `json:"sequence_id,omitempty"`
|
||
|
|
Attachment *Attachment `json:"attachment,omitempty"`
|
||
|
|
Actions json.RawMessage `json:"actions,omitempty"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// Attachment describes a file linked from a message.
|
||
|
|
type Attachment struct {
|
||
|
|
Name string `json:"name"`
|
||
|
|
URL string `json:"url"`
|
||
|
|
Type string `json:"type,omitempty"`
|
||
|
|
Size int64 `json:"size,omitempty"`
|
||
|
|
Expires int64 `json:"expires,omitempty"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// ParseLine decodes one NDJSON line. ok is false for blank lines.
|
||
|
|
func ParseLine(line []byte) (Event, bool, error) {
|
||
|
|
line = bytes.TrimSpace(line)
|
||
|
|
if len(line) == 0 {
|
||
|
|
return Event{}, false, nil
|
||
|
|
}
|
||
|
|
var ev Event
|
||
|
|
if err := json.Unmarshal(line, &ev); err != nil {
|
||
|
|
return Event{}, false, err
|
||
|
|
}
|
||
|
|
if ev.Event == "" {
|
||
|
|
return Event{}, false, fmt.Errorf("missing event")
|
||
|
|
}
|
||
|
|
return ev, true, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// ReadLines yields each decoded event until EOF or a read error.
|
||
|
|
// Malformed JSON is reported and skipped so one bad line does not kill the stream.
|
||
|
|
func ReadLines(r io.Reader, yield func(Event) error, onBad func(error)) error {
|
||
|
|
sc := newScanner(r)
|
||
|
|
for sc.Scan() {
|
||
|
|
ev, ok, err := ParseLine(sc.Bytes())
|
||
|
|
if err != nil {
|
||
|
|
if onBad != nil {
|
||
|
|
onBad(err)
|
||
|
|
}
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
if !ok {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
if err := yield(ev); err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return sc.Err()
|
||
|
|
}
|