This repository has no description
1package notella
2
3import (
4 "context"
5 "fmt"
6
7 "git.inpt.fr/churros/notella/db"
8)
9
10// AllUsers returns all the users in the database that have at least one notification subscription
11func AllUsers() ([]string, error) {
12 users, err := prisma.User.FindMany(
13 db.User.NotificationSubscriptions.Some(
14 db.NotificationSubscription.Endpoint.Not(""),
15 ),
16 ).Select(
17 db.User.ID.Field(),
18 ).Exec(context.Background())
19
20 if err != nil {
21 return []string{}, fmt.Errorf("while getting all users: %w", err)
22 }
23
24 ids := make([]string, len(users))
25 for i, user := range users {
26 ids[i] = user.ID
27 }
28
29 return ids, nil
30}
31
32// Receivers determines which users to send the notification to
33func Receivers(message Message) ([]string, error) {
34 switch message.Event {
35 case EventNewPost:
36 return receiversForPost(message)
37 case EventNewComment:
38 return receiversForNewComment(message)
39 case EventBookingPaid:
40 return receiversForBookingPaid(message)
41 case EventCommentReply:
42 return receiversForCommentReply(message)
43 case EventContributionPaid:
44 return receiversForContributionPaid(message)
45 case EventGodchildAccepted, EventGodchildRejected:
46 return receiversForGodchildResponse(message)
47 case EventGodchildRequest:
48 return receiversForGodchildRequest(message)
49 case EventShotgunOpensSoon:
50 return receiversForShotgunOpens(message)
51 case EventShotgunClosesSoon:
52 return receiversForShotgunCloses(message)
53 }
54
55 // For other events, assume the message churros object id is the user id
56 if message.ChurrosObjectId != "" {
57 _, err := prisma.User.FindUnique(
58 db.User.ID.Equals(message.ChurrosObjectId),
59 ).Exec(context.Background())
60 if err == nil {
61 return []string{message.ChurrosObjectId}, nil
62 }
63 }
64
65 return []string{}, nil
66}
67
68func receiversForPost(message Message) (userIds []string, err error) {
69 post, err := prisma.Article.FindUnique(
70 db.Article.ID.Equals(message.ChurrosObjectId),
71 ).With(
72 db.Article.Group.Fetch().With(
73 db.Group.Members.Fetch().Select(
74 db.GroupMember.MemberID.Field(),
75 ),
76 db.Group.StudentAssociation.Fetch().With(
77 db.StudentAssociation.School.Fetch().With(
78 db.School.Majors.Fetch().With(
79 db.Major.Students.Fetch().Select(
80 db.User.ID.Field(),
81 ),
82 ),
83 ),
84 ),
85 ),
86 ).Exec(context.Background())
87
88 if err != nil {
89 return []string{}, fmt.Errorf("while getting the post %q: %w", message.Id, err)
90 }
91
92 switch post.Visibility {
93 case db.VisibilityPrivate, db.VisibilityUnlisted:
94 return []string{}, nil
95 case db.VisibilityPublic:
96 return AllUsers()
97 case db.VisibilitySchoolRestricted:
98 for _, major := range post.Group().StudentAssociation().School().Majors() {
99 for _, student := range major.Students() {
100 userIds = append(userIds, student.ID)
101 }
102 }
103 return
104 case db.VisibilityGroupRestricted:
105 for _, member := range post.Group().Members() {
106 userIds = append(userIds, member.MemberID)
107 }
108 }
109
110 return userIds, fmt.Errorf("unknown post visibility %q", post.Visibility)
111}
112
113func receiversForNewComment(message Message) (userIds []string, err error) {
114 comment, err := prisma.Comment.FindUnique(
115 db.Comment.ID.Equals(message.ChurrosObjectId),
116 ).With(
117 db.Comment.Article.Fetch(),
118 ).Exec(context.Background())
119 if err != nil {
120 err = fmt.Errorf("while getting comment: %w", err)
121 return
122 }
123
124 post, ok := comment.Article()
125 if !ok {
126 err = fmt.Errorf("comment %q has no parent post", comment.ID)
127 return
128 }
129
130 authorId, ok := post.AuthorID()
131 if !ok {
132 err = fmt.Errorf("post %q has no author", post.ID)
133 return
134 }
135
136 return []string{authorId}, nil
137}
138
139func receiversForBookingPaid(message Message) (userIds []string, err error) {
140 booking, err := prisma.Registration.FindUnique(
141 db.Registration.ID.Equals(message.ChurrosObjectId),
142 ).Exec(context.Background())
143
144 if err != nil {
145 err = fmt.Errorf("while getting booking: %w", err)
146 return
147 }
148
149 authorId, ok := booking.AuthorID()
150 if ok {
151 userIds = append(userIds, authorId)
152 }
153
154 beneficiaryId, ok := booking.InternalBeneficiaryID()
155 if ok {
156 userIds = append(userIds, beneficiaryId)
157 }
158
159 return
160}
161
162func receiversForCommentReply(message Message) (userIds []string, err error) {
163 comment, err := prisma.Comment.FindUnique(
164 db.Comment.ID.Equals(message.ChurrosObjectId),
165 ).With(
166 db.Comment.InReplyTo.Fetch(),
167 ).Exec(context.Background())
168 if err != nil {
169 err = fmt.Errorf("while getting comment: %w", err)
170 return
171 }
172
173 parent, ok := comment.InReplyTo()
174 if !ok {
175 err = fmt.Errorf("comment %q has no parent", comment.ID)
176 return
177 }
178
179 authorId, ok := parent.AuthorID()
180 if !ok {
181 err = fmt.Errorf("comment %q has no author", parent.ID)
182 return
183 }
184
185 return []string{authorId}, nil
186}
187
188func receiversForContributionPaid(message Message) (userIds []string, err error) {
189 contribution, err := prisma.Contribution.FindUnique(
190 db.Contribution.ID.Equals(message.ChurrosObjectId),
191 ).Exec(context.Background())
192
193 if err != nil {
194 err = fmt.Errorf("while getting contribution: %w", err)
195 return
196 }
197
198 return []string{contribution.UserID}, nil
199}
200
201func receiversForGodchildResponse(message Message) (userIds []string, err error) {
202 godchildRequest, err := prisma.GodparentRequest.FindUnique(
203 db.GodparentRequest.ID.Equals(message.ChurrosObjectId),
204 ).Exec(context.Background())
205
206 if err != nil {
207 err = fmt.Errorf("while getting godchild request: %w", err)
208 return
209 }
210
211 return []string{godchildRequest.GodchildID}, nil
212}
213
214func receiversForGodchildRequest(message Message) (userIds []string, err error) {
215 godchildRequest, err := prisma.GodparentRequest.FindUnique(
216 db.GodparentRequest.ID.Equals(message.ChurrosObjectId),
217 ).Exec(context.Background())
218
219 if err != nil {
220 err = fmt.Errorf("while getting godchild request: %w", err)
221 return
222 }
223
224 return []string{godchildRequest.GodparentID}, nil
225}
226
227func receiversForShotgunOpens(message Message) (userIds []string, err error) {
228 shotgun, err := prisma.Event.FindUnique(
229 db.Event.ID.Equals(message.ChurrosObjectId),
230 ).With(
231 db.Event.Group.Fetch().With(
232 db.Group.Members.Fetch().Select(
233 db.GroupMember.MemberID.Field(),
234 ),
235 db.Group.StudentAssociation.Fetch().With(
236 db.StudentAssociation.School.Fetch().With(
237 db.School.Majors.Fetch().With(
238 db.Major.Students.Fetch().Select(
239 db.User.ID.Field(),
240 ),
241 ),
242 ),
243 ),
244 ),
245 ).Exec(context.Background())
246
247 userIds = make([]string, 0)
248
249 switch shotgun.Visibility {
250 case db.VisibilityPublic:
251 return AllUsers()
252 case db.VisibilitySchoolRestricted:
253 for _, major := range shotgun.Group().StudentAssociation().School().Majors() {
254 for _, student := range major.Students() {
255 userIds = append(userIds, student.ID)
256 }
257 }
258 return
259 case db.VisibilityGroupRestricted:
260 for _, member := range shotgun.Group().Members() {
261 userIds = append(userIds, member.MemberID)
262 }
263 return
264 }
265
266 return
267}
268
269func receiversForShotgunCloses(message Message) (userIds []string, err error) {
270 shotgun, err := prisma.Event.FindUnique(
271 db.Event.ID.Equals(message.ChurrosObjectId),
272 ).With(
273 db.Event.Group.Fetch().With(
274 db.Group.Members.Fetch().Select(
275 db.GroupMember.MemberID.Field(),
276 ),
277 db.Group.StudentAssociation.Fetch().With(
278 db.StudentAssociation.School.Fetch().With(
279 db.School.Majors.Fetch().With(
280 db.Major.Students.Fetch().Select(
281 db.User.ID.Field(),
282 ),
283 ),
284 ),
285 ),
286 ),
287 db.Event.Tickets.Fetch().With(
288 db.Ticket.Registrations.Fetch().Select(
289 db.Registration.AuthorID.Field(),
290 db.Registration.InternalBeneficiaryID.Field(),
291 ),
292 ),
293 ).Exec(context.Background())
294
295 switch shotgun.Visibility {
296 case db.VisibilityPublic:
297 return AllUsers()
298 case db.VisibilitySchoolRestricted:
299 for _, major := range shotgun.Group().StudentAssociation().School().Majors() {
300 for _, student := range major.Students() {
301 userIds = append(userIds, student.ID)
302 }
303 }
304 return
305 case db.VisibilityGroupRestricted:
306 for _, member := range shotgun.Group().Members() {
307 userIds = append(userIds, member.MemberID)
308 }
309 return
310 }
311
312 // Remove users that are booked to the event
313
314 usersToRemove := make([]string, 0)
315
316 for _, ticket := range shotgun.Tickets() {
317 for _, registration := range ticket.Registrations() {
318 authorId, ok := registration.AuthorID()
319 if ok {
320 usersToRemove = append(usersToRemove, authorId)
321 }
322
323 beneficiaryId, ok := registration.InternalBeneficiaryID()
324 if ok {
325 usersToRemove = append(usersToRemove, beneficiaryId)
326 }
327 }
328 }
329
330 for _, user := range usersToRemove {
331 for i, id := range userIds {
332 if id == user {
333 userIds = append(userIds[:i], userIds[i+1:]...)
334 break
335 }
336 }
337 }
338
339 return
340}