diff --git a/website/server/models/group.js b/website/server/models/group.js index ec6b47fcbd..a2383b15f6 100644 --- a/website/server/models/group.js +++ b/website/server/models/group.js @@ -12,10 +12,7 @@ import * as Tasks from './task'; import validator from 'validator'; import { removeFromArray } from '../libs/collectionManipulators'; import payments from '../libs/payments/payments'; -import { - groupChatReceivedWebhook, - questActivityWebhook, -} from '../libs/webhook'; +import { groupChatReceivedWebhook } from '../libs/webhook'; import { InternalServerError, BadRequest, @@ -651,24 +648,20 @@ schema.methods.startQuest = async function startQuest (user) { removeFromArray(nonUserQuestMembers, user._id); // remove any users from quest.members who aren't in the party - // and get the data necessary to send webhooks - const members = []; - - await User.find({ - _id: {$in: Object.keys(this.quest.members)}, - }) - .select('party.quest party._id items.quests auth preferences.emailNotifications preferences.pushNotifications pushDevices profile.name webhooks') - .lean() - .exec() - .then(partyMembers => { - partyMembers.forEach(member => { - if (!member.party || member.party._id !== this._id) { - delete this.quest.members[member._id]; - } else { - members.push(member); + let partyId = this._id; + let questMembers = this.quest.members; + await Promise.all(Object.keys(this.quest.members).map(memberId => { + return User.findOne({_id: memberId, 'party._id': partyId}) + .select('_id') + .lean() + .exec() + .then((member) => { + if (!member) { + delete questMembers[memberId]; } + return; }); - }); + })); if (userIsParticipating) { user.party.quest.key = this.quest.key; @@ -677,23 +670,20 @@ schema.methods.startQuest = async function startQuest (user) { user.markModified('party.quest'); } - const promises = []; - // Remove the quest from the quest leader items (if they are the current user) if (this.quest.leader === user._id) { user.items.quests[this.quest.key] -= 1; user.markModified('items.quests'); - promises.push(user.save()); } else { // another user is starting the quest, update the leader separately - promises.push(User.update({_id: this.quest.leader}, { + await User.update({_id: this.quest.leader}, { $inc: { [`items.quests.${this.quest.key}`]: -1, }, - }).exec()); + }).exec(); } // update the remaining users - promises.push(User.update({ + await User.update({ _id: { $in: nonUserQuestMembers }, }, { $set: { @@ -701,9 +691,7 @@ schema.methods.startQuest = async function startQuest (user) { 'party.quest.progress.down': 0, 'party.quest.completed': null, }, - }, { multi: true }).exec()); - - await Promise.all(promises); + }, { multi: true }).exec(); // update the users who are not participating // Do not block updates @@ -715,45 +703,38 @@ schema.methods.startQuest = async function startQuest (user) { }, }, { multi: true }).exec(); + // send notifications in the background without blocking + User.find( + { _id: { $in: nonUserQuestMembers } }, + 'party.quest items.quests auth.facebook auth.local preferences.emailNotifications preferences.pushNotifications pushDevices profile.name' + ).exec().then((membersToNotify) => { + let membersToEmail = _.filter(membersToNotify, (member) => { + // send push notifications and filter users that disabled emails + return member.preferences.emailNotifications.questStarted !== false && + member._id !== user._id; + }); + sendTxnEmail(membersToEmail, 'quest-started', [ + { name: 'PARTY_URL', content: '/party' }, + ]); + let membersToPush = _.filter(membersToNotify, (member) => { + // send push notifications and filter users that disabled emails + return member.preferences.pushNotifications.questStarted !== false && + member._id !== user._id; + }); + _.each(membersToPush, (member) => { + sendPushNotification(member, + { + title: quest.text(), + message: `${shared.i18n.t('questStarted')}: ${quest.text()}`, + identifier: 'questStarted', + }); + }); + }); const newMessage = this.sendChat(`\`Your quest, ${quest.text('en')}, has started.\``, null, { participatingMembers: this.getParticipatingQuestMembers().join(', '), }); + await newMessage.save(); - - const membersToEmail = []; - const pushTitle = quest.text(); - const pushMessage = `${shared.i18n.t('questStarted')}: ${quest.text()}`; - - // send notifications and webhooks in the background without blocking - members.forEach(member => { - if (member._id !== user._id) { - // send push notifications and filter users that disabled emails - if (member.preferences.emailNotifications.questStarted !== false) { - membersToEmail.push(member); - } - - // send push notifications and filter users that disabled emails - if (member.preferences.pushNotifications.questStarted !== false) { - sendPushNotification(member, { - title: pushTitle, - message: pushMessage, - identifier: 'questStarted', - }); - } - } - - // Send webhooks - questActivityWebhook.send(member, { - type: 'questStarted', - group: this, - quest, - }); - }); - - // Send emails in bulk - sendTxnEmail(membersToEmail, 'quest-started', [ - { name: 'PARTY_URL', content: '/party' }, - ]); }; schema.methods.sendGroupChatReceivedWebhooks = function sendGroupChatReceivedWebhooks (chat) { @@ -772,14 +753,15 @@ schema.methods.sendGroupChatReceivedWebhooks = function sendGroupChatReceivedWeb query.guilds = this._id; } - User.find(query).select({webhooks: 1}).lean().exec().then((users) => { + /* User.find(query).select({webhooks: 1}).lean().exec().then((users) => { users.forEach((user) => { - groupChatReceivedWebhook.send(user, { + let { webhooks } = user; + groupChatReceivedWebhook.send(webhooks, { group: this, chat, }); }); - }); + }); */ }; schema.statics.cleanQuestProgress = _cleanQuestProgress; @@ -925,31 +907,6 @@ schema.methods.finishQuest = async function finishQuest (quest) { })); } - // Send webhooks in background - // @TODO move the find users part to a worker as well, not just the http request - User.find({ - _id: {$in: participants}, - webhooks: { - $elemMatch: { - type: 'questActivity', - 'options.questFinished': true, - }, - }, - }) - .select('_id webhooks') - .lean() - .exec() - .then(participantsWithWebhook => { - participantsWithWebhook.forEach(participantWithWebhook => { - // Send webhooks - questActivityWebhook.send(participantWithWebhook, { - type: 'questFinished', - group: this, - quest, - }); - }); - }); - return await Promise.all(promises); }; @@ -1537,4 +1494,4 @@ if (!nconf.get('IS_TEST')) { privacy: 'public', }).save(); }); -} +} \ No newline at end of file