This repository has no description
1package notella
2
3import (
4 "context"
5 "fmt"
6 "strings"
7
8 "git.inpt.fr/churros/notella/db"
9 ll "github.com/gwennlbh/label-logger-go"
10)
11
12var prisma = db.NewClient()
13
14type ChurrosId struct {
15 Type string
16 LocalID string
17}
18
19func (id ChurrosId) String() string {
20 return fmt.Sprintf("%s:%s", id.Type, id.LocalID)
21}
22
23func ParseChurrosId(churrosId string) (ChurrosId, error) {
24 parts := strings.Split(churrosId, ":")
25 if len(parts) != 2 {
26 return ChurrosId{}, fmt.Errorf("malformed churros global id: %q", churrosId)
27 }
28
29 return ChurrosId{
30 Type: parts[0],
31 LocalID: parts[1],
32 }, nil
33}
34
35// UnmarshalText implements the encoding.TextUnmarshaler interface for ChurrosId.
36func (id *ChurrosId) UnmarshalText(text []byte) error {
37 s := string(text)
38
39 parsed, err := ParseChurrosId(s)
40 if err != nil {
41 return err
42 }
43
44 id.Type = parsed.Type
45 id.LocalID = parsed.LocalID
46
47 return nil
48}
49
50func (msg Message) CreateInDatabaseNotifications(groupId string, subs []Subscription) {
51 if config.DryRunMode && len(config.DryRunExceptions) == 0 {
52 ll.Warn("dry run mode enabled, not creating notifications in database")
53 return
54 }
55
56 subsFilter := func(sub Subscription) bool { return true }
57
58 if len(config.DryRunExceptions) > 0 && config.DryRunMode {
59 ll.Warn("dry run mode enabled: only creating notifications in database for %+v", config.DryRunExceptions)
60 subsFilter = func(sub Subscription) bool {
61 for _, username := range config.DryRunExceptions {
62 if username == sub.Owner.Uid {
63 return true
64 }
65 }
66 return false
67 }
68 }
69
70 // Create sequentially: this is not something that has to be done fast, and parallelizing would swamp the database connections
71 for _, sub := range subs {
72 if !subsFilter(sub) {
73 continue
74 }
75
76 prisma.Notification.CreateOne(
77 db.Notification.Subscription.Link(
78 db.NotificationSubscription.Endpoint.Equals(sub.Webpush.Endpoint),
79 ),
80 db.Notification.Title.Set(msg.Title),
81 db.Notification.Body.Set(msg.Body),
82 db.Notification.ID.Set(msg.Id),
83 db.Notification.Channel.Set(msg.Channel()),
84 db.Notification.Group.Link(db.Group.ID.Equals(groupId)),
85 db.Notification.Goto.Set(msg.Action),
86 db.Notification.Timestamp.Set(msg.SendAt),
87 ).Exec(context.Background())
88 }
89}
90
91func ConnectToDababase() error {
92 return prisma.Connect()
93}
94
95// Group returns the Churros group ID responsible for the notification
96func (msg Message) Group() (string, error) {
97 switch msg.Event {
98 case EventNewPost:
99 post, err := prisma.Article.FindUnique(
100 db.Article.ID.Equals(msg.ChurrosObjectId),
101 ).Select(
102 db.Article.GroupID.Field(),
103 ).Exec(context.Background())
104 if err != nil {
105 return "", fmt.Errorf("while getting the group responsible for the notification: %w", err)
106 }
107
108 return post.GroupID, nil
109 case EventShotgunClosesSoon, EventShotgunOpensSoon:
110 event, err := prisma.Event.FindUnique(
111 db.Event.ID.Equals(msg.ChurrosObjectId),
112 ).Exec(context.Background())
113 if err != nil {
114 return "", fmt.Errorf("while getting the group responsible for the notification: %w", err)
115 }
116 return event.GroupID, nil
117 case EventCustom, EventGodchildAccepted, EventGodchildRejected, EventGodchildRequest, EventTest:
118 return "", nil
119 }
120
121 return "", fmt.Errorf("unknown event type %q", msg.Event)
122}
123
124func (msg Message) Channel() db.NotificationChannel {
125 switch msg.Event {
126 case EventNewPost:
127 return db.NotificationChannelArticles
128 case EventShotgunClosesSoon, EventShotgunOpensSoon:
129 return db.NotificationChannelShotguns
130 case EventGodchildRequest, EventGodchildAccepted, EventGodchildRejected:
131 return db.NotificationChannelGodparentRequests
132 }
133
134 return db.NotificationChannelOther
135}