This repository has no description
1package notella
2
3import (
4 "encoding/json"
5 "strings"
6 "sync"
7
8 "git.inpt.fr/churros/notella/db"
9 "github.com/SherClockHolmes/webpush-go"
10 ll "github.com/gwennlbh/label-logger-go"
11)
12
13type WebPushNotification struct {
14 Title string `json:"title"`
15 Actions []webpushAction `json:"actions"`
16 Badge string `json:"badge"`
17 Icon string `json:"icon"`
18 Image string `json:"image"`
19 Body string `json:"body"`
20 Renotify bool `json:"renotify"`
21 RequireInteraction bool `json:"requireInteraction"`
22 Silent bool `json:"silent"`
23 Tag string `json:"tag"`
24 Timestamp int64 `json:"timestamp"`
25 Vibrate []int `json:"vibrate"`
26 Data webpushNotificationData `json:"data"`
27}
28
29type webpushAction struct {
30 Action string `json:"action"`
31 Label string `json:"label"`
32 Icon string `json:"icon"`
33}
34
35type webpushNotificationData struct {
36 Group string `json:"group"`
37 Channel db.NotificationChannel `json:"channel"`
38 SubscriptionName string `json:"subscriptionName"`
39 Goto string `json:"goto"`
40}
41
42func (msg Message) WebPush(groupId string) WebPushNotification {
43 actions := make([]webpushAction, len(msg.Actions))
44 for i, action := range msg.Actions {
45 actions[i] = webpushAction{
46 Action: action.Action,
47 Label: action.Label,
48 Icon: "",
49 }
50 }
51
52 return WebPushNotification{
53 Title: msg.Title,
54 Actions: actions,
55 Badge: "",
56 Icon: "",
57 Image: msg.Image,
58 Body: msg.Body,
59 Data: webpushNotificationData{
60 Group: groupId,
61 Channel: msg.Channel(),
62 SubscriptionName: "",
63 Goto: msg.Action,
64 },
65 }
66}
67
68func (msg Message) SendWebPush(groupId string, subs []Subscription) error {
69
70 jsoned, err := json.Marshal(msg.WebPush(groupId))
71 if err != nil {
72 ll.ErrorDisplay("could not marshal notification to json", err)
73 }
74
75 var wg sync.WaitGroup
76 wg.Add(len(subs))
77 for _, sub := range subs {
78 go func(wg *sync.WaitGroup, sub Subscription) {
79 if config.DryRunMode {
80 ll.Warn("dry run mode enabled, not sending webpush notification to %s", sub.Owner.Uid)
81 wg.Done()
82 return
83 }
84 resp, err := webpush.SendNotification(jsoned, &sub.Webpush, &webpush.Options{
85 TTL: 30,
86 Subscriber: config.ContactEmail,
87 VAPIDPublicKey: config.VapidPublicKey,
88 VAPIDPrivateKey: config.VapidPrivateKey,
89 })
90 wg.Done()
91
92 if err != nil {
93 ll.ErrorDisplay("could not send notification to %s", err, sub.Owner.Uid)
94 } else if resp.StatusCode == 410 {
95 ll.Log("Deleting", "yellow", "invalid webpush subscription %s", sub.Webpush.Endpoint)
96 sub.Destroy()
97 } else if resp.StatusCode >= 400 {
98 ll.Error("could not send notification to %s: HTTP %d", sub.Owner.Uid, resp.StatusCode)
99 }
100
101 }(&wg, sub)
102 }
103 wg.Wait()
104
105 return nil
106}
107
108func (sub Subscription) IsWebpush() bool {
109 // Native subscriptions don't use the https: protocol
110 return strings.HasPrefix(sub.Webpush.Endpoint, "https://")
111}