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 }
109
110 return userIds, fmt.Errorf("unknown post visibility %q", post.Visibility)
111}
112
113func receiversForBookingPaid(message Message) (userIds []string, err error) {
114 booking, err := prisma.Registration.FindUnique(
115 db.Registration.ID.Equals(message.ChurrosObjectId),
116 ).Exec(context.Background())
117
118 if err != nil {
119 err = fmt.Errorf("while getting booking: %w", err)
120 return
121 }
122
123 authorId, ok := booking.AuthorID()
124 if ok {
125 userIds = append(userIds, authorId)
126 }
127
128 beneficiaryId, ok := booking.InternalBeneficiaryID()
129 if ok {
130 userIds = append(userIds, beneficiaryId)
131 }
132
133 return
134}
135
136func receiversForContributionPaid(message Message) (userIds []string, err error) {
137 contribution, err := prisma.Contribution.FindUnique(
138 db.Contribution.ID.Equals(message.ChurrosObjectId),
139 ).Exec(context.Background())
140
141 if err != nil {
142 err = fmt.Errorf("while getting contribution: %w", err)
143 return
144 }
145
146 return []string{contribution.UserID}, nil
147}
148
149func receiversForGodchildResponse(message Message) (userIds []string, err error) {
150 godchildRequest, err := prisma.GodparentRequest.FindUnique(
151 db.GodparentRequest.ID.Equals(message.ChurrosObjectId),
152 ).Exec(context.Background())
153
154 if err != nil {
155 err = fmt.Errorf("while getting godchild request: %w", err)
156 return
157 }
158
159 return []string{godchildRequest.GodchildID}, nil
160}
161
162func receiversForGodchildRequest(message Message) (userIds []string, err error) {
163 godchildRequest, err := prisma.GodparentRequest.FindUnique(
164 db.GodparentRequest.ID.Equals(message.ChurrosObjectId),
165 ).Exec(context.Background())
166
167 if err != nil {
168 err = fmt.Errorf("while getting godchild request: %w", err)
169 return
170 }
171
172 return []string{godchildRequest.GodparentID}, nil
173}
174
175func receiversForShotgunOpens(message Message) (userIds []string, err error) {
176 shotgun, err := prisma.Event.FindUnique(
177 db.Event.ID.Equals(message.ChurrosObjectId),
178 ).With(
179 db.Event.Group.Fetch().With(
180 db.Group.Members.Fetch().Select(
181 db.GroupMember.MemberID.Field(),
182 ),
183 db.Group.StudentAssociation.Fetch().With(
184 db.StudentAssociation.School.Fetch().With(
185 db.School.Majors.Fetch().With(
186 db.Major.Students.Fetch().Select(
187 db.User.ID.Field(),
188 ),
189 ),
190 ),
191 ),
192 ),
193 ).Exec(context.Background())
194
195 userIds = make([]string, 0)
196
197 switch shotgun.Visibility {
198 case db.VisibilityPublic:
199 return AllUsers()
200 case db.VisibilitySchoolRestricted:
201 for _, major := range shotgun.Group().StudentAssociation().School().Majors() {
202 for _, student := range major.Students() {
203 userIds = append(userIds, student.ID)
204 }
205 }
206 return
207 case db.VisibilityGroupRestricted:
208 for _, member := range shotgun.Group().Members() {
209 userIds = append(userIds, member.MemberID)
210 }
211 return
212 }
213
214 return
215}
216
217func receiversForShotgunCloses(message Message) (userIds []string, err error) {
218 shotgun, err := prisma.Event.FindUnique(
219 db.Event.ID.Equals(message.ChurrosObjectId),
220 ).With(
221 db.Event.Group.Fetch().With(
222 db.Group.Members.Fetch().Select(
223 db.GroupMember.MemberID.Field(),
224 ),
225 db.Group.StudentAssociation.Fetch().With(
226 db.StudentAssociation.School.Fetch().With(
227 db.School.Majors.Fetch().With(
228 db.Major.Students.Fetch().Select(
229 db.User.ID.Field(),
230 ),
231 ),
232 ),
233 ),
234 ),
235 db.Event.Tickets.Fetch().With(
236 db.Ticket.Registrations.Fetch().Select(
237 db.Registration.AuthorID.Field(),
238 db.Registration.InternalBeneficiaryID.Field(),
239 ),
240 ),
241 ).Exec(context.Background())
242
243 switch shotgun.Visibility {
244 case db.VisibilityPublic:
245 return AllUsers()
246 case db.VisibilitySchoolRestricted:
247 for _, major := range shotgun.Group().StudentAssociation().School().Majors() {
248 for _, student := range major.Students() {
249 userIds = append(userIds, student.ID)
250 }
251 }
252 return
253 case db.VisibilityGroupRestricted:
254 for _, member := range shotgun.Group().Members() {
255 userIds = append(userIds, member.MemberID)
256 }
257 return
258 }
259
260 // Remove users that are booked to the event
261
262 usersToRemove := make([]string, 0)
263
264 for _, ticket := range shotgun.Tickets() {
265 for _, registration := range ticket.Registrations() {
266 authorId, ok := registration.AuthorID()
267 if ok {
268 usersToRemove = append(usersToRemove, authorId)
269 }
270
271 beneficiaryId, ok := registration.InternalBeneficiaryID()
272 if ok {
273 usersToRemove = append(usersToRemove, beneficiaryId)
274 }
275 }
276 }
277
278 for _, user := range usersToRemove {
279 for i, id := range userIds {
280 if id == user {
281 userIds = append(userIds[:i], userIds[i+1:]...)
282 break
283 }
284 }
285 }
286
287 return
288}