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 exempt := false
81 for _, username := range config.DryRunExceptions {
82 if username == sub.Owner.Uid {
83 exempt = true
84 }
85 }
86 if !exempt {
87 ll.Warn("dry run mode enabled, not sending webpush notification to %s", sub.Owner.Uid)
88 wg.Done()
89 return
90 }
91 }
92 resp, err := webpush.SendNotification(jsoned, &sub.Webpush, &webpush.Options{
93 TTL: 30,
94 Subscriber: config.ContactEmail,
95 VAPIDPublicKey: config.VapidPublicKey,
96 VAPIDPrivateKey: config.VapidPrivateKey,
97 })
98 wg.Done()
99
100 if err != nil {
101 ll.ErrorDisplay("could not send notification to %s", err, sub.Owner.Uid)
102 } else if resp.StatusCode == 410 {
103 ll.Log("Deleting", "yellow", "invalid webpush subscription %s", sub.Webpush.Endpoint)
104 sub.Destroy()
105 } else if resp.StatusCode >= 400 {
106 ll.Error("could not send notification to %s: HTTP %d", sub.Owner.Uid, resp.StatusCode)
107 }
108
109 }(&wg, sub)
110 }
111 wg.Wait()
112
113 return nil
114}
115
116func (sub Subscription) IsWebpush() bool {
117 // Native subscriptions don't use the https: protocol
118 return strings.HasPrefix(sub.Webpush.Endpoint, "https://")
119}