This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 9.1 kB View raw
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 EventLoginStuck, EventPendingSignup: 52 return receiversForUserCandidate(message) 53 case EventTest: 54 return []string{}, fmt.Errorf("test event is for subscriptions, not users") 55 } 56 57 // For other events, assume the message churros object id is the user id 58 if message.ChurrosObjectId != "" { 59 _, err := prisma.User.FindUnique( 60 db.User.ID.Equals(message.ChurrosObjectId), 61 ).Exec(context.Background()) 62 if err == nil { 63 return []string{message.ChurrosObjectId}, nil 64 } 65 } 66 67 return []string{}, nil 68} 69 70func receiversForPost(message Message) (userIds []string, err error) { 71 post, err := prisma.Article.FindUnique( 72 db.Article.ID.Equals(message.ChurrosObjectId), 73 ).With( 74 db.Article.Group.Fetch().With( 75 db.Group.Members.Fetch().Select( 76 db.GroupMember.MemberID.Field(), 77 ), 78 db.Group.StudentAssociation.Fetch().With( 79 db.StudentAssociation.School.Fetch().With( 80 db.School.Majors.Fetch().With( 81 db.Major.Students.Fetch().Select( 82 db.User.ID.Field(), 83 ), 84 ), 85 ), 86 ), 87 ), 88 ).Exec(context.Background()) 89 90 if err != nil { 91 return []string{}, fmt.Errorf("while getting the post %q: %w", message.Id, err) 92 } 93 94 switch post.Visibility { 95 case db.VisibilityPrivate, db.VisibilityUnlisted: 96 return []string{}, nil 97 case db.VisibilityPublic: 98 return AllUsers() 99 case db.VisibilitySchoolRestricted: 100 for _, major := range post.Group().StudentAssociation().School().Majors() { 101 for _, student := range major.Students() { 102 userIds = append(userIds, student.ID) 103 } 104 } 105 return 106 case db.VisibilityGroupRestricted: 107 for _, member := range post.Group().Members() { 108 userIds = append(userIds, member.MemberID) 109 } 110 return 111 } 112 113 return userIds, fmt.Errorf("unknown post visibility %q", post.Visibility) 114} 115 116func receiversForBookingPaid(message Message) (userIds []string, err error) { 117 booking, err := prisma.Registration.FindUnique( 118 db.Registration.ID.Equals(message.ChurrosObjectId), 119 ).Exec(context.Background()) 120 121 if err != nil { 122 err = fmt.Errorf("while getting booking: %w", err) 123 return 124 } 125 126 authorId, ok := booking.AuthorID() 127 if ok { 128 userIds = append(userIds, authorId) 129 } 130 131 beneficiaryId, ok := booking.InternalBeneficiaryID() 132 if ok { 133 userIds = append(userIds, beneficiaryId) 134 } 135 136 return 137} 138 139func receiversForContributionPaid(message Message) (userIds []string, err error) { 140 contribution, err := prisma.Contribution.FindUnique( 141 db.Contribution.ID.Equals(message.ChurrosObjectId), 142 ).Exec(context.Background()) 143 144 if err != nil { 145 err = fmt.Errorf("while getting contribution: %w", err) 146 return 147 } 148 149 return []string{contribution.UserID}, nil 150} 151 152func receiversForGodchildResponse(message Message) (userIds []string, err error) { 153 godchildRequest, err := prisma.GodparentRequest.FindUnique( 154 db.GodparentRequest.ID.Equals(message.ChurrosObjectId), 155 ).Exec(context.Background()) 156 157 if err != nil { 158 err = fmt.Errorf("while getting godchild request: %w", err) 159 return 160 } 161 162 return []string{godchildRequest.GodchildID}, nil 163} 164 165func receiversForGodchildRequest(message Message) (userIds []string, err error) { 166 godchildRequest, err := prisma.GodparentRequest.FindUnique( 167 db.GodparentRequest.ID.Equals(message.ChurrosObjectId), 168 ).Exec(context.Background()) 169 170 if err != nil { 171 err = fmt.Errorf("while getting godchild request: %w", err) 172 return 173 } 174 175 return []string{godchildRequest.GodparentID}, nil 176} 177 178func receiversForShotgunOpens(message Message) (userIds []string, err error) { 179 shotgun, err := prisma.Event.FindUnique( 180 db.Event.ID.Equals(message.ChurrosObjectId), 181 ).With( 182 db.Event.Group.Fetch().With( 183 db.Group.Members.Fetch().Select( 184 db.GroupMember.MemberID.Field(), 185 ), 186 db.Group.StudentAssociation.Fetch().With( 187 db.StudentAssociation.School.Fetch().With( 188 db.School.Majors.Fetch().With( 189 db.Major.Students.Fetch().Select( 190 db.User.ID.Field(), 191 ), 192 ), 193 ), 194 ), 195 ), 196 ).Exec(context.Background()) 197 198 userIds = make([]string, 0) 199 200 switch shotgun.Visibility { 201 case db.VisibilityPublic: 202 return AllUsers() 203 case db.VisibilitySchoolRestricted: 204 for _, major := range shotgun.Group().StudentAssociation().School().Majors() { 205 for _, student := range major.Students() { 206 userIds = append(userIds, student.ID) 207 } 208 } 209 return 210 case db.VisibilityGroupRestricted: 211 for _, member := range shotgun.Group().Members() { 212 userIds = append(userIds, member.MemberID) 213 } 214 return 215 } 216 217 return 218} 219 220func receiversForShotgunCloses(message Message) (userIds []string, err error) { 221 shotgun, err := prisma.Event.FindUnique( 222 db.Event.ID.Equals(message.ChurrosObjectId), 223 ).With( 224 db.Event.Group.Fetch().With( 225 db.Group.Members.Fetch().Select( 226 db.GroupMember.MemberID.Field(), 227 ), 228 db.Group.StudentAssociation.Fetch().With( 229 db.StudentAssociation.School.Fetch().With( 230 db.School.Majors.Fetch().With( 231 db.Major.Students.Fetch().Select( 232 db.User.ID.Field(), 233 ), 234 ), 235 ), 236 ), 237 ), 238 db.Event.Tickets.Fetch().With( 239 db.Ticket.Registrations.Fetch().Select( 240 db.Registration.AuthorID.Field(), 241 db.Registration.InternalBeneficiaryID.Field(), 242 ), 243 ), 244 ).Exec(context.Background()) 245 246 switch shotgun.Visibility { 247 case db.VisibilityPublic: 248 return AllUsers() 249 case db.VisibilitySchoolRestricted: 250 for _, major := range shotgun.Group().StudentAssociation().School().Majors() { 251 for _, student := range major.Students() { 252 userIds = append(userIds, student.ID) 253 } 254 } 255 return 256 case db.VisibilityGroupRestricted: 257 for _, member := range shotgun.Group().Members() { 258 userIds = append(userIds, member.MemberID) 259 } 260 return 261 } 262 263 // Remove users that are booked to the event 264 265 usersToRemove := make([]string, 0) 266 267 for _, ticket := range shotgun.Tickets() { 268 for _, registration := range ticket.Registrations() { 269 authorId, ok := registration.AuthorID() 270 if ok { 271 usersToRemove = append(usersToRemove, authorId) 272 } 273 274 beneficiaryId, ok := registration.InternalBeneficiaryID() 275 if ok { 276 usersToRemove = append(usersToRemove, beneficiaryId) 277 } 278 } 279 } 280 281 for _, user := range usersToRemove { 282 for i, id := range userIds { 283 if id == user { 284 userIds = append(userIds[:i], userIds[i+1:]...) 285 break 286 } 287 } 288 } 289 290 return 291} 292 293func receiversForUserCandidate(message Message) (userIds []string, err error) { 294 // Find school of the user candidate or user 295 school, err := prisma.School.FindFirst( 296 db.School.Majors.Some( 297 db.Major.Or( 298 db.Major.Students.Some(db.User.ID.Equals(message.ChurrosObjectId)), 299 db.Major.UserCandidates.Some(db.UserCandidate.ID.Equals(message.ChurrosObjectId)), 300 ), 301 ), 302 ).Exec(context.Background()) 303 304 if err != nil { 305 return []string{}, fmt.Errorf("while getting school of user or usercandidate %s: %w", message.ChurrosObjectId, err) 306 } 307 308 systemAdmins, err := prisma.User.FindMany( 309 db.User.Admin.Equals(true), 310 ).Select( 311 db.User.ID.Field(), 312 ).Exec(context.Background()) 313 314 if err != nil { 315 return []string{}, fmt.Errorf("while getting system admins: %w", err) 316 } 317 318 // If external account, send to system admins 319 if school == nil { 320 for _, admin := range systemAdmins { 321 userIds = append(userIds, admin.ID) 322 } 323 return 324 } 325 326 // If user or candidate has a school, get student association admins for that school 327 studentAssociationAdmins, err := prisma.User.FindMany( 328 db.User.AdminOfStudentAssociations.Some( 329 db.StudentAssociation.SchoolID.Equals(school.ID), 330 ), 331 ).Select( 332 db.User.ID.Field(), 333 ).Exec(context.Background()) 334 335 if err != nil { 336 return []string{}, fmt.Errorf("while getting student association admins for %+v: %w", school, err) 337 } 338 339 for _, admin := range studentAssociationAdmins { 340 userIds = append(userIds, admin.ID) 341 } 342 343 return 344}