Skip to content
Merged
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions connect/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
3 changes: 3 additions & 0 deletions connect/constants.js
Original file line number Diff line number Diff line change
@@ -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 * * * *',
Expand Down
5 changes: 4 additions & 1 deletion connect/notificationServices/email.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down Expand Up @@ -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,
},
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion emails/src/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
<td class="footer-space"></td>
<td class="footer-content" align="center">
<table>
<tr><td>Connect is the world’s first project management crowdsorcing platform utilizing the power of Topcoder communities</td></tr>
<tr><td>Connect is the world’s first project management crowdsourcing platform utilizing the power of Topcoder communities</td></tr>
<tr class="empty-10"><td></td></tr>
<tr><td>201 S Capitol Ave #1100</td></tr>
<tr><td>Indianapolis, IN 46225 United States</td></tr>
Expand Down
25 changes: 20 additions & 5 deletions src/common/broadcastAPIHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []
Expand Down Expand Up @@ -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}`)
}
}

Expand Down Expand Up @@ -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
Expand Down