diff --git a/.circleci/config.yml b/.circleci/config.yml index 8a72aa0..6c2bee9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -102,7 +102,7 @@ workflows: context : org-global filters: branches: - only: [dev, 'bug/community-notification'] + only: [dev, 'feature/broadcast2'] - "build-prod": context : org-global filters: diff --git a/config/default.js b/config/default.js index 9563efe..9d426a7 100644 --- a/config/default.js +++ b/config/default.js @@ -34,6 +34,9 @@ module.exports = { API_CONTEXT_PATH: process.env.API_CONTEXT_PATH || '/v5/notifications', TC_API_BASE_URL: process.env.TC_API_BASE_URL || '', + // CloudFront CDN URL. It's used to host and resize images like user avatars. + TC_CDN_URL: process.env.TC_CDN_URL || '', + // Configuration for generating machine to machine auth0 token. // The token will be used for calling another internal API. AUTH0_URL: process.env.AUTH0_URL, diff --git a/connect/config.js b/connect/config.js index 48751c7..ec7304b 100644 --- a/connect/config.js +++ b/connect/config.js @@ -37,4 +37,5 @@ module.exports = { CONNECT_URL: process.env.CONNECT_URL || 'https://connect.topcoder-dev.com', ACCOUNTS_APP_URL: process.env.ACCOUNTS_APP_URL || "https://accounts.topcoder-dev.com", + TC_CDN_URL: process.env.TC_CDN_URL, }; diff --git a/connect/constants.js b/connect/constants.js index 3768ac5..4022ef1 100644 --- a/connect/constants.js +++ b/connect/constants.js @@ -1,4 +1,7 @@ module.exports = { + // size for user photos in emails + EMAIL_USER_PHOTO_SIZE: 80, + // periods of time in cron format (node-cron) SCHEDULED_EVENT_PERIOD: { every10minutes: '*/10 * * * *', diff --git a/connect/notificationServices/email.js b/connect/notificationServices/email.js index 3d608fc..3b50afe 100644 --- a/connect/notificationServices/email.js +++ b/connect/notificationServices/email.js @@ -13,6 +13,7 @@ const { SCHEDULED_EVENT_PERIOD, SETTINGS_EMAIL_SERVICE_ID, ACTIVE_USER_STATUSES, + EMAIL_USER_PHOTO_SIZE, } = require('../constants'); const { EVENT_BUNDLES } = require('../events-config'); const helpers = require('../helpers'); @@ -236,7 +237,6 @@ function handler(topicName, messageJSON, notification) { projectId: messageJSON.projectId, authorHandle: notification.contents.userHandle, authorFullName: notification.contents.userFullName, - photoURL: notification.contents.photoURL, type: notificationType, emailToAffectedUser: notification.contents.userEmail === userEmail, }, @@ -250,6 +250,9 @@ function handler(topicName, messageJSON, notification) { }; eventMessage.data[eventMessage.data.type] = true; _.assign(eventMessage.data, notification.contents); + // set `photoURL` after we already applied `notification.contents`, so `photoURL` doesn't get overwritten + eventMessage.data.photoURL = `${config.TC_CDN_URL}/avatar/${encodeURIComponent(notification.contents.photoURL)}` + + `?size=${EMAIL_USER_PHOTO_SIZE}`; // message service may return tags // to understand if post notification is regarding phases or no, we will try to get phaseId from the tags diff --git a/emails/src/template.html b/emails/src/template.html index 14c2a4a..51c2b7b 100644 --- a/emails/src/template.html +++ b/emails/src/template.html @@ -87,7 +87,7 @@ - + diff --git a/src/common/broadcastAPIHelper.js b/src/common/broadcastAPIHelper.js index 0ac38c6..1feb73d 100644 --- a/src/common/broadcastAPIHelper.js +++ b/src/common/broadcastAPIHelper.js @@ -118,11 +118,13 @@ async function callApi(url, machineToken) { * @param {Object} m memberInfo * */ -async function checkUserSkillsAndTracks(userId, bulkMessage, m) { +async function filterOnMemberCondition(userId, bulkMessage, m) { try { const skills = _.get(bulkMessage, 'recipients.skills') const tracks = _.get(bulkMessage, 'recipients.tracks') - let skillMatch, trackMatch = false // default + const countryCodes = _.get(bulkMessage, 'recipients.countryCodes') + + let skillMatch, trackMatch, countryCodeMatch = false // default if (skills && skills.length > 0) { const ms = _.get(m[0], "skills") // get member skills const memberSkills = [] @@ -166,10 +168,23 @@ async function checkUserSkillsAndTracks(userId, bulkMessage, m) { } else { trackMatch = true // no condition, means allow for all } - const flag = (skillMatch && trackMatch) ? true : false + + if (countryCodes.length > 0) { + const mcc = _.get(m[0], 'competitionCountryCode') // get member country code + countryCodeMatch = false + if (_.indexOf(countryCodes, mcc) >= 0) { + countryCodeMatch = true + logger.info(`BroadcastMessageId: ${bulkMessage.id},` + + ` '${mcc}' country code matached for user id ${userId}`) + } + } else { + countryCodeMatch = true // no codition on country code + } + + const flag = (skillMatch && trackMatch && countryCodeMatch) ? true : false return flag } catch (e) { - throw new Error(`checkUserSkillsAndTracks() : ${e}`) + throw new Error(`filterOnMemberCondition() : ${e}`) } } @@ -232,7 +247,7 @@ async function checkUserGroup(userId, bulkMessage, userGroupInfo) { async function checkBroadcastMessageForUser(userId, bulkMessage, memberInfo, userGroupInfo) { return new Promise(function (resolve, reject) { Promise.all([ - checkUserSkillsAndTracks(userId, bulkMessage, memberInfo), + filterOnMemberCondition(userId, bulkMessage, memberInfo), checkUserGroup(userId, bulkMessage, userGroupInfo), ]).then((results) => { let flag = true // TODO need to be sure about default value
Connect is the world’s first project management crowdsorcing platform utilizing the power of Topcoder communities
Connect is the world’s first project management crowdsourcing platform utilizing the power of Topcoder communities
201 S Capitol Ave #1100
Indianapolis, IN 46225 United States