11"use strict" ;
22const { DateTime } = require ( "luxon" ) ;
33const conf = require ( "simple-configure" ) ;
4+ const R = require ( "ramda" ) ;
45const logger = require ( "winston" ) . loggers . get ( "application" ) ;
56
67const groupsService = require ( "../groups/groupsService" ) ;
@@ -16,6 +17,7 @@ const Group = require("../groups/group");
1617const misc = require ( "../commons/misc" ) ;
1718
1819const mailtransport = require ( "./mailtransport" ) ;
20+ const statusmessage = require ( "../commons/statusmessage" ) ;
1921
2022async function sendMail ( message , type ) {
2123 return mailtransport . sendMail ( message , type , conf . get ( "sender-address" ) , conf . get ( "include-footer" ) ) ;
@@ -37,10 +39,40 @@ function activityMarkdown(activity, language) {
3739 return markdown ;
3840}
3941
42+ function createChunkedSendingReportMessage ( statusmessages , subject , message ) {
43+ const isError = R . any ( statusmessage . isErrorMessage , statusmessages ) ;
44+ const markdown = isError
45+ ? `Fehler: ${ statusmessages . map ( ( s ) => s . contents ( ) . additionalArguments . err ) . join ( " " ) } `
46+ : "E-Mails erfolgreich versendet" ;
47+
48+ return message . cloneWithBody ( {
49+ subject : `${ isError ? "ERROR" : "SUCCESS" } ${ subject } ` ,
50+ markdown,
51+ sendCopyToSelf : true ,
52+ } ) ;
53+ }
54+
55+ async function sendMailInChunks ( maxMailSendingChunkSize , allMembers , message , type ) {
56+ const membersInChunks = R . splitEvery ( maxMailSendingChunkSize , allMembers ) ;
57+
58+ try {
59+ const statusmessages = await Promise . all (
60+ membersInChunks . map ( ( bccs ) => {
61+ message . setBccToMemberAddresses ( bccs ) ;
62+ return sendMail ( message , type ) ;
63+ } ) ,
64+ ) ;
65+ const resultMessage = createChunkedSendingReportMessage ( statusmessages , `Report "${ message . subject } "` , message ) ;
66+ await sendMail ( resultMessage , type ) ;
67+ } catch ( err ) {
68+ logger . error ( err ) ;
69+ }
70+ }
71+
4072module . exports = {
4173 activityMarkdown,
4274
43- dataForShowingMessageForActivity : async function ( activityURL , language ) {
75+ dataForShowingMessageForActivity : async function dataForShowingMessageForActivity ( activityURL , language ) {
4476 const [ activity , groups ] = [
4577 activitiesService . getActivityWithGroupAndParticipants ( activityURL ) ,
4678 groupstore . allGroups ( ) ,
@@ -105,7 +137,11 @@ module.exports = {
105137 }
106138 try {
107139 groups . forEach ( groupsAndMembersService . addMembersToGroup ) ;
108- message . setBccToGroupMemberAddresses ( groups ) ;
140+ const allMembers = R . uniqBy (
141+ ( member ) => member . email ( ) ,
142+ groups . flatMap ( ( group ) => group . members ) ,
143+ ) ;
144+
109145 let activity ;
110146 try {
111147 activity = activitystore . getActivity ( activityURL ) ;
@@ -115,7 +151,17 @@ module.exports = {
115151 if ( activity ) {
116152 message . setIcal ( icalService . activityAsICal ( activity ) . toString ( ) ) ;
117153 }
118- return sendMail ( message , type ) ;
154+
155+ const maxMailSendingChunkSize = conf . get ( "maxMailSendingChunkSize" ) ;
156+ if ( allMembers . length > maxMailSendingChunkSize ) {
157+ // noinspection ES6MissingAwait - we explicitly don't want to wait because that could cause timeouts
158+ sendMailInChunks ( maxMailSendingChunkSize , allMembers , message , type ) ;
159+
160+ return mailtransport . statusmessageForSuccess ( type ) ;
161+ } else {
162+ message . setBccToMemberAddresses ( allMembers ) ;
163+ return sendMail ( message , type ) ;
164+ }
119165 } catch ( err1 ) {
120166 return mailtransport . statusmessageForError ( type , err1 ) ;
121167 }
@@ -142,8 +188,11 @@ module.exports = {
142188 sendMailToAllMembers : async function sendMailToAllMembers ( message ) {
143189 const type = "$t(mailsender.notification)" ;
144190 const members = memberstore . allMembers ( ) ;
145- message . setBccToMemberAddresses ( members ) ;
146- return sendMail ( message , type ) ;
191+
192+ // noinspection ES6MissingAwait - we explicitly don't want to wait because that could cause timeouts
193+ sendMailInChunks ( conf . get ( "maxMailSendingChunkSize" ) , members , message , type ) ;
194+
195+ return mailtransport . statusmessageForSuccess ( type ) ;
147196 } ,
148197
149198 sendMagicLinkToMember : async function sendMagicLinkToMember ( member , token ) {
0 commit comments