@@ -18,7 +18,6 @@ import {
1818 AttendeeWriteSchema ,
1919 DEFAULT_MARK_DURATION ,
2020 type Event ,
21- type GroupType ,
2221 type Membership ,
2322 type TaskId ,
2423 type User ,
@@ -27,6 +26,7 @@ import {
2726 getMembershipGrade ,
2827 hasAttendeePaid ,
2928 isAttendable ,
29+ findFirstHostingGroupEmail ,
3030} from "@dotkomonline/types"
3131import { createAbsoluteEventPageUrl , createPoolName , getCurrentUTC , ogJoin , slugify } from "@dotkomonline/utils"
3232import {
@@ -258,6 +258,8 @@ export interface AttendanceService {
258258 mergeTime : TZDate | null
259259 ) : Promise < TaskId | null >
260260 executeMergeEventPoolsTask ( handle : DBHandle , task : InferTaskData < MergeAttendancePoolsTaskDefinition > ) : Promise < void >
261+
262+ notifyAttendees ( handle : DBHandle , attendanceId : AttendanceId , message : string ) : Promise < void >
261263}
262264
263265export function getAttendanceService (
@@ -1438,12 +1440,7 @@ export function getAttendanceService(
14381440 return
14391441 }
14401442
1441- const validGroupTypes : GroupType [ ] = [ "COMMITTEE" , "NODE_COMMITTEE" ]
1442-
1443- const hostingGroupEmail =
1444- event . hostingGroups . filter ( ( group ) => group . email && validGroupTypes . includes ( group . type ) ) . at ( 0 ) ?. email ??
1445- "bedkom@online.ntnu.no"
1446-
1443+ const hostingGroupEmail = findFirstHostingGroupEmail ( event ) ?? "bedkom@online.ntnu.no"
14471444 logger . info (
14481445 "Sending feedback form email for Event(ID=%s) to %d attendees from email %s" ,
14491446 event . id ,
@@ -1613,6 +1610,59 @@ export function getAttendanceService(
16131610 await attendanceRepository . updateAttendeeAttendancePoolIdByAttendancePoolIds ( handle , mergeablePoolIds , pool . id )
16141611 await attendanceRepository . deleteAttendancePoolsByIds ( handle , mergeablePoolIds )
16151612 } ,
1613+ async notifyAttendees ( handle , attendanceId , message ) {
1614+ const attendance = await this . getAttendanceById ( handle , attendanceId )
1615+ const event = await eventService . getByAttendanceId ( handle , attendanceId )
1616+ if ( isBefore ( getCurrentUTC ( ) , attendance . registerStart ) ) {
1617+ throw new IllegalStateError ( `Cannot send message to attendees for Attendance(ID=${ attendance . id } ) before start` )
1618+ }
1619+
1620+ const hostingGroupEmail = findFirstHostingGroupEmail ( event )
1621+ if ( hostingGroupEmail === null ) {
1622+ logger . warn (
1623+ "Notification email sent for Event(ID=%s, Name=%s) did not have sufficient organizer email so %s was used." ,
1624+ event . id ,
1625+ event . title ,
1626+ DEFAULT_EMAIL_SOURCE
1627+ )
1628+ }
1629+ const sourceEmail = hostingGroupEmail ?? DEFAULT_EMAIL_SOURCE
1630+
1631+ // In order to keep email sizes relatively small, and to prevent spam detection we batch the emails with 25 BCC recipients at a time
1632+ const batchSize = 25
1633+ for ( let batchStartIndex = 0 ; batchStartIndex < attendance . attendees . length ; batchStartIndex += batchSize ) {
1634+ const attendees = attendance . attendees . slice ( batchStartIndex , batchStartIndex + batchSize )
1635+ const attendeeEmails = attendees . map ( ( a ) => a . user . email ) . filter ( ( e ) => e !== null )
1636+
1637+ const currentBatchIndex = Math . floor ( batchStartIndex / batchSize ) + 1
1638+ const totalBatches = Math . ceil ( attendance . attendees . length / batchSize )
1639+
1640+ logger . info (
1641+ "Scheduling emails %s..%s in batch %s/%s for notification for Event(ID=%s, Name=%s)" ,
1642+ batchStartIndex + 1 ,
1643+ batchStartIndex + attendees . length ,
1644+ currentBatchIndex ,
1645+ totalBatches ,
1646+ event . id ,
1647+ event . title
1648+ )
1649+
1650+ await emailService . send (
1651+ sourceEmail ,
1652+ [ sourceEmail ] ,
1653+ [ ] ,
1654+ [ ] ,
1655+ attendeeEmails ,
1656+ `Viktig melding om ${ event . title } ` ,
1657+ emails . EVENT_MESSAGE ,
1658+ {
1659+ eventName : event . title ,
1660+ eventLink : createAbsoluteEventPageUrl ( configuration . WEB_PUBLIC_ORIGIN , event . id , event . title ) ,
1661+ message,
1662+ }
1663+ )
1664+ }
1665+ } ,
16161666 }
16171667}
16181668
0 commit comments