This repository has no description
1package notella
2
3import (
4 "context"
5 "fmt"
6
7 "git.inpt.fr/churros/notella/db"
8 ll "github.com/gwennlbh/label-logger-go"
9)
10
11// AllUsers returns all the users in the database that have at least one notification subscription
12func AllUsers() ([]string, error) {
13 users, err := prisma.User.FindMany(
14 db.User.NotificationSubscriptions.Some(
15 db.NotificationSubscription.Endpoint.Not(""),
16 ),
17 ).Select(
18 db.User.ID.Field(),
19 ).Exec(context.Background())
20
21 if err != nil {
22 return []string{}, fmt.Errorf("while getting all users: %w", err)
23 }
24
25 ids := make([]string, len(users))
26 for i, user := range users {
27 ids[i] = user.ID
28 }
29
30 return ids, nil
31}
32
33// Receivers determines which users to send the notification to
34func Receivers(message Message) ([]string, error) {
35 ll.Debug("Determining receivers for message %s on %s", message.Event, message.ChurrosObjectId)
36 switch message.Event {
37 case EventNewPost:
38 return receiversForPost(message)
39 case EventBookingPaid:
40 return receiversForBookingPaid(message)
41 case EventContributionPaid:
42 return receiversForContributionPaid(message)
43 case EventGodchildAccepted, EventGodchildRejected:
44 return receiversForGodchildResponse(message)
45 case EventGodchildRequest:
46 return receiversForGodchildRequest(message)
47 case EventShotgunOpensSoon:
48 return receiversForShotgunOpens(message)
49 case EventShotgunClosesSoon:
50 return receiversForShotgunCloses(message)
51 case EventTest:
52 return []string{}, fmt.Errorf("test event is for subscriptions, not users")
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 return
109 }
110
111 return userIds, fmt.Errorf("unknown post visibility %q", post.Visibility)
112}
113
114func receiversForBookingPaid(message Message) (userIds []string, err error) {
115 booking, err := prisma.Registration.FindUnique(
116 db.Registration.ID.Equals(message.ChurrosObjectId),
117 ).Exec(context.Background())
118
119 if err != nil {
120 err = fmt.Errorf("while getting booking: %w", err)
121 return
122 }
123
124 authorId, ok := booking.AuthorID()
125 if ok {
126 userIds = append(userIds, authorId)
127 }
128
129 beneficiaryId, ok := booking.InternalBeneficiaryID()
130 if ok {
131 userIds = append(userIds, beneficiaryId)
132 }
133
134 return
135}
136
137func receiversForContributionPaid(message Message) (userIds []string, err error) {
138 contribution, err := prisma.Contribution.FindUnique(
139 db.Contribution.ID.Equals(message.ChurrosObjectId),
140 ).Exec(context.Background())
141
142 if err != nil {
143 err = fmt.Errorf("while getting contribution: %w", err)
144 return
145 }
146
147 return []string{contribution.UserID}, nil
148}
149
150func receiversForGodchildResponse(message Message) (userIds []string, err error) {
151 godchildRequest, err := prisma.GodparentRequest.FindUnique(
152 db.GodparentRequest.ID.Equals(message.ChurrosObjectId),
153 ).Exec(context.Background())
154
155 if err != nil {
156 err = fmt.Errorf("while getting godchild request: %w", err)
157 return
158 }
159
160 return []string{godchildRequest.GodchildID}, nil
161}
162
163func receiversForGodchildRequest(message Message) (userIds []string, err error) {
164 godchildRequest, err := prisma.GodparentRequest.FindUnique(
165 db.GodparentRequest.ID.Equals(message.ChurrosObjectId),
166 ).Exec(context.Background())
167
168 if err != nil {
169 err = fmt.Errorf("while getting godchild request: %w", err)
170 return
171 }
172
173 return []string{godchildRequest.GodparentID}, nil
174}
175
176func receiversForShotgunOpens(message Message) (userIds []string, err error) {
177 shotgun, err := prisma.Event.FindUnique(
178 db.Event.ID.Equals(message.ChurrosObjectId),
179 ).With(
180 db.Event.Group.Fetch().With(
181 db.Group.Members.Fetch().Select(
182 db.GroupMember.MemberID.Field(),
183 ),
184 db.Group.StudentAssociation.Fetch().With(
185 db.StudentAssociation.School.Fetch().With(
186 db.School.Majors.Fetch().With(
187 db.Major.Students.Fetch().Select(
188 db.User.ID.Field(),
189 ),
190 ),
191 ),
192 ),
193 ),
194 ).Exec(context.Background())
195
196 userIds = make([]string, 0)
197
198 switch shotgun.Visibility {
199 case db.VisibilityPublic:
200 return AllUsers()
201 case db.VisibilitySchoolRestricted:
202 for _, major := range shotgun.Group().StudentAssociation().School().Majors() {
203 for _, student := range major.Students() {
204 userIds = append(userIds, student.ID)
205 }
206 }
207 return
208 case db.VisibilityGroupRestricted:
209 for _, member := range shotgun.Group().Members() {
210 userIds = append(userIds, member.MemberID)
211 }
212 return
213 }
214
215 return
216}
217
218func receiversForShotgunCloses(message Message) (userIds []string, err error) {
219 shotgun, err := prisma.Event.FindUnique(
220 db.Event.ID.Equals(message.ChurrosObjectId),
221 ).With(
222 db.Event.Group.Fetch().With(
223 db.Group.Members.Fetch().Select(
224 db.GroupMember.MemberID.Field(),
225 ),
226 db.Group.StudentAssociation.Fetch().With(
227 db.StudentAssociation.School.Fetch().With(
228 db.School.Majors.Fetch().With(
229 db.Major.Students.Fetch().Select(
230 db.User.ID.Field(),
231 ),
232 ),
233 ),
234 ),
235 ),
236 db.Event.Tickets.Fetch().With(
237 db.Ticket.Registrations.Fetch().Select(
238 db.Registration.AuthorID.Field(),
239 db.Registration.InternalBeneficiaryID.Field(),
240 ),
241 ),
242 ).Exec(context.Background())
243
244 switch shotgun.Visibility {
245 case db.VisibilityPublic:
246 return AllUsers()
247 case db.VisibilitySchoolRestricted:
248 for _, major := range shotgun.Group().StudentAssociation().School().Majors() {
249 for _, student := range major.Students() {
250 userIds = append(userIds, student.ID)
251 }
252 }
253 return
254 case db.VisibilityGroupRestricted:
255 for _, member := range shotgun.Group().Members() {
256 userIds = append(userIds, member.MemberID)
257 }
258 return
259 }
260
261 // Remove users that are booked to the event
262
263 usersToRemove := make([]string, 0)
264
265 for _, ticket := range shotgun.Tickets() {
266 for _, registration := range ticket.Registrations() {
267 authorId, ok := registration.AuthorID()
268 if ok {
269 usersToRemove = append(usersToRemove, authorId)
270 }
271
272 beneficiaryId, ok := registration.InternalBeneficiaryID()
273 if ok {
274 usersToRemove = append(usersToRemove, beneficiaryId)
275 }
276 }
277 }
278
279 for _, user := range usersToRemove {
280 for i, id := range userIds {
281 if id == user {
282 userIds = append(userIds[:i], userIds[i+1:]...)
283 break
284 }
285 }
286 }
287
288 return
289}