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 EventBookingPaid:
38 return receiversForBookingPaid(message)
39 case EventContributionPaid:
40 return receiversForContributionPaid(message)
41 case EventGodchildAccepted, EventGodchildRejected:
42 return receiversForGodchildResponse(message)
43 case EventGodchildRequest:
44 return receiversForGodchildRequest(message)
45 case EventShotgunOpensSoon:
46 return receiversForShotgunOpens(message)
47 case EventShotgunClosesSoon:
48 return receiversForShotgunCloses(message)
49 }
50
51 // For other events, assume the message churros object id is the user id
52 if message.ChurrosObjectId != "" {
53 _, err := prisma.User.FindUnique(
54 db.User.ID.Equals(message.ChurrosObjectId),
55 ).Exec(context.Background())
56 if err == nil {
57 return []string{message.ChurrosObjectId}, nil
58 }
59 }
60
61 return []string{}, nil
62}
63
64func receiversForPost(message Message) (userIds []string, err error) {
65 post, err := prisma.Article.FindUnique(
66 db.Article.ID.Equals(message.ChurrosObjectId),
67 ).With(
68 db.Article.Group.Fetch().With(
69 db.Group.Members.Fetch().Select(
70 db.GroupMember.MemberID.Field(),
71 ),
72 db.Group.StudentAssociation.Fetch().With(
73 db.StudentAssociation.School.Fetch().With(
74 db.School.Majors.Fetch().With(
75 db.Major.Students.Fetch().Select(
76 db.User.ID.Field(),
77 ),
78 ),
79 ),
80 ),
81 ),
82 ).Exec(context.Background())
83
84 if err != nil {
85 return []string{}, fmt.Errorf("while getting the post %q: %w", message.Id, err)
86 }
87
88 switch post.Visibility {
89 case db.VisibilityPrivate, db.VisibilityUnlisted:
90 return []string{}, nil
91 case db.VisibilityPublic:
92 return AllUsers()
93 case db.VisibilitySchoolRestricted:
94 for _, major := range post.Group().StudentAssociation().School().Majors() {
95 for _, student := range major.Students() {
96 userIds = append(userIds, student.ID)
97 }
98 }
99 return
100 case db.VisibilityGroupRestricted:
101 for _, member := range post.Group().Members() {
102 userIds = append(userIds, member.MemberID)
103 }
104 }
105
106 return userIds, fmt.Errorf("unknown post visibility %q", post.Visibility)
107}
108
109func receiversForBookingPaid(message Message) (userIds []string, err error) {
110 booking, err := prisma.Registration.FindUnique(
111 db.Registration.ID.Equals(message.ChurrosObjectId),
112 ).Exec(context.Background())
113
114 if err != nil {
115 err = fmt.Errorf("while getting booking: %w", err)
116 return
117 }
118
119 authorId, ok := booking.AuthorID()
120 if ok {
121 userIds = append(userIds, authorId)
122 }
123
124 beneficiaryId, ok := booking.InternalBeneficiaryID()
125 if ok {
126 userIds = append(userIds, beneficiaryId)
127 }
128
129 return
130}
131
132func receiversForContributionPaid(message Message) (userIds []string, err error) {
133 contribution, err := prisma.Contribution.FindUnique(
134 db.Contribution.ID.Equals(message.ChurrosObjectId),
135 ).Exec(context.Background())
136
137 if err != nil {
138 err = fmt.Errorf("while getting contribution: %w", err)
139 return
140 }
141
142 return []string{contribution.UserID}, nil
143}
144
145func receiversForGodchildResponse(message Message) (userIds []string, err error) {
146 godchildRequest, err := prisma.GodparentRequest.FindUnique(
147 db.GodparentRequest.ID.Equals(message.ChurrosObjectId),
148 ).Exec(context.Background())
149
150 if err != nil {
151 err = fmt.Errorf("while getting godchild request: %w", err)
152 return
153 }
154
155 return []string{godchildRequest.GodchildID}, nil
156}
157
158func receiversForGodchildRequest(message Message) (userIds []string, err error) {
159 godchildRequest, err := prisma.GodparentRequest.FindUnique(
160 db.GodparentRequest.ID.Equals(message.ChurrosObjectId),
161 ).Exec(context.Background())
162
163 if err != nil {
164 err = fmt.Errorf("while getting godchild request: %w", err)
165 return
166 }
167
168 return []string{godchildRequest.GodparentID}, nil
169}
170
171func receiversForShotgunOpens(message Message) (userIds []string, err error) {
172 shotgun, err := prisma.Event.FindUnique(
173 db.Event.ID.Equals(message.ChurrosObjectId),
174 ).With(
175 db.Event.Group.Fetch().With(
176 db.Group.Members.Fetch().Select(
177 db.GroupMember.MemberID.Field(),
178 ),
179 db.Group.StudentAssociation.Fetch().With(
180 db.StudentAssociation.School.Fetch().With(
181 db.School.Majors.Fetch().With(
182 db.Major.Students.Fetch().Select(
183 db.User.ID.Field(),
184 ),
185 ),
186 ),
187 ),
188 ),
189 ).Exec(context.Background())
190
191 userIds = make([]string, 0)
192
193 switch shotgun.Visibility {
194 case db.VisibilityPublic:
195 return AllUsers()
196 case db.VisibilitySchoolRestricted:
197 for _, major := range shotgun.Group().StudentAssociation().School().Majors() {
198 for _, student := range major.Students() {
199 userIds = append(userIds, student.ID)
200 }
201 }
202 return
203 case db.VisibilityGroupRestricted:
204 for _, member := range shotgun.Group().Members() {
205 userIds = append(userIds, member.MemberID)
206 }
207 return
208 }
209
210 return
211}
212
213func receiversForShotgunCloses(message Message) (userIds []string, err error) {
214 shotgun, err := prisma.Event.FindUnique(
215 db.Event.ID.Equals(message.ChurrosObjectId),
216 ).With(
217 db.Event.Group.Fetch().With(
218 db.Group.Members.Fetch().Select(
219 db.GroupMember.MemberID.Field(),
220 ),
221 db.Group.StudentAssociation.Fetch().With(
222 db.StudentAssociation.School.Fetch().With(
223 db.School.Majors.Fetch().With(
224 db.Major.Students.Fetch().Select(
225 db.User.ID.Field(),
226 ),
227 ),
228 ),
229 ),
230 ),
231 db.Event.Tickets.Fetch().With(
232 db.Ticket.Registrations.Fetch().Select(
233 db.Registration.AuthorID.Field(),
234 db.Registration.InternalBeneficiaryID.Field(),
235 ),
236 ),
237 ).Exec(context.Background())
238
239 switch shotgun.Visibility {
240 case db.VisibilityPublic:
241 return AllUsers()
242 case db.VisibilitySchoolRestricted:
243 for _, major := range shotgun.Group().StudentAssociation().School().Majors() {
244 for _, student := range major.Students() {
245 userIds = append(userIds, student.ID)
246 }
247 }
248 return
249 case db.VisibilityGroupRestricted:
250 for _, member := range shotgun.Group().Members() {
251 userIds = append(userIds, member.MemberID)
252 }
253 return
254 }
255
256 // Remove users that are booked to the event
257
258 usersToRemove := make([]string, 0)
259
260 for _, ticket := range shotgun.Tickets() {
261 for _, registration := range ticket.Registrations() {
262 authorId, ok := registration.AuthorID()
263 if ok {
264 usersToRemove = append(usersToRemove, authorId)
265 }
266
267 beneficiaryId, ok := registration.InternalBeneficiaryID()
268 if ok {
269 usersToRemove = append(usersToRemove, beneficiaryId)
270 }
271 }
272 }
273
274 for _, user := range usersToRemove {
275 for i, id := range userIds {
276 if id == user {
277 userIds = append(userIds[:i], userIds[i+1:]...)
278 break
279 }
280 }
281 }
282
283 return
284}