diff --git a/src/constants.js b/src/constants.js
index 9fa3c75..140a1b4 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -44,6 +44,10 @@ module.exports = {
       COPILOT: 'copilot',
       MANAGER: 'manager',
       CUSTOMER: 'customer'
+    },
+    CHALLENGE_ROLES: {
+      COPILOT: 'Copilot',
+      MANAGER: 'Manager'
     }
   },
   VANILLA: {
diff --git a/src/modules/user_management/handler.js b/src/modules/user_management/handler.js
index 8720f24..11f0566 100644
--- a/src/modules/user_management/handler.js
+++ b/src/modules/user_management/handler.js
@@ -1,4 +1,5 @@
 const config = require('config')
+const _ = require('lodash')
 const util = require('util')
 const constants = require('../../constants')
 const logger = require('../../utils/logger.util')
@@ -6,6 +7,8 @@ const { manageRocketUser } = require('../../services/rokect')
 const { manageVanillaUser } = require('../../services/vanilla')
 const {
   getTopcoderUserHandle: getUserHandle,
+  getAllChallengeRolesForUser,
+  getProjectRoleForUser,
   processPayload
 } = require('./helpers')
 
@@ -34,6 +37,23 @@ function canProcessEvent (payload, topic) {
   return true
 }
 
+async function processPayloadItem (item, topic) {
+  const data = processPayload(item, topic)
+  try {
+    data.handle = data.handle || (await getUserHandle(data.userId))
+    data.projectRole = (await getProjectRoleForUser(data.challengeId, data.userId))
+    data.challengeRoles = (await getAllChallengeRolesForUser(data.challengeId, data.userId))
+  } catch (err) {
+    logger.error(util.inspect(err))
+  }
+  for (const service of services) {
+    await service(data)
+      .catch(err => {
+        logger.error(util.inspect(err))
+      })
+  }
+}
+
 /**
  * Handle a set of messages from the Kafka topic
  * @param {Array} messageSet
@@ -48,19 +68,12 @@ async function handler (messageSet, topic) {
     if (!canProcessEvent(item, topic)) {
       continue
     }
-
-    const data = processPayload(item, topic)
-    try {
-      data.handle = data.handle || (await getUserHandle(data.userId))
-    } catch (err) {
-      logger.error(util.inspect(err))
-      continue
-    }
-    for (const service of services) {
-      await service(data)
-        .catch(err => {
-          logger.error(util.inspect(err))
-        })
+    if (_.isArray(item)) {
+      for (const i of item) {
+        await processPayloadItem(i, topic)
+      }
+    } else {
+      await processPayloadItem(item, topic)
     }
   }
 }
diff --git a/src/modules/user_management/helpers.js b/src/modules/user_management/helpers.js
index ca57e3f..90d6a3b 100644
--- a/src/modules/user_management/helpers.js
+++ b/src/modules/user_management/helpers.js
@@ -61,7 +61,62 @@ async function getTopcoderUserHandle (userId) {
   return userHandle
 }
 
+/**
+ *  Get a list of role names for User
+ * @param challengeId
+ * @param userId
+ * @returns {Promise<*[]>}
+ */
+async function getAllChallengeRolesForUser (challengeId, userId) {
+  const { body: challengeRoles, status: challengeRolesStatus } = await topcoderApi.getAllChallengeRoles(challengeId)
+  if (challengeRolesStatus !== 200) {
+    throw new Error('Couldn\'t load Topcoder Challenge Roles', challengeRoles)
+  }
+  const roles = _.filter(challengeRoles, { memberId: userId })
+
+  const { body: resourceRoles, status: allRolesStatus } = await topcoderApi.getAllRoles()
+  if (allRolesStatus !== 200) {
+    throw new Error('Couldn\'t load Topcoder Resource Roles', resourceRoles)
+  }
+
+  if (_.isEmpty(resourceRoles)) {
+    throw new Error(`No Resource Roles for ${challengeId}`)
+  }
+
+  _.map(roles, function (obj) {
+    // add the properties from second array matching the roleId
+    return _.assign(obj, _.find(resourceRoles, { id: obj.roleId }))
+  })
+
+  // Get all role names
+  return _.map(roles, 'name')
+}
+
+async function getProjectRoleForUser (challengeId, userId) {
+  const { body: challenge, status: challengeStatus } = await topcoderApi.getChallenge(challengeId)
+  if (challengeStatus !== 200) {
+    throw new Error(`Couldn't load Topcoder Challenge by challengeId ${challengeId}`)
+  }
+  const { body: project, status: projectStatus } = await topcoderApi.getProject(challenge.projectId)
+
+  if (projectStatus !== 200) {
+    throw new Error(`Couldn't load Topcoder Project by projectId ${challenge.projectId}`)
+  }
+
+  // userId  - string , x.userId -  int
+  /* eslint-disable eqeqeq */
+  const member = _.filter(project.members, x => x.userId == userId)
+  // User doesn't have project roles
+  if (_.isEmpty(member)) {
+    return null
+  } else {
+    return member[0].role
+  }
+}
+
 module.exports = {
   getTopcoderUserHandle,
+  getAllChallengeRolesForUser,
+  getProjectRoleForUser,
   processPayload
 }
diff --git a/src/services/vanilla.js b/src/services/vanilla.js
index 6deaba2..c4f8d2f 100644
--- a/src/services/vanilla.js
+++ b/src/services/vanilla.js
@@ -11,20 +11,18 @@ const utils = require('../utils/common.util')
 const template = require(config.TEMPLATES.TEMPLATE_FILE_PATH)
 
 /**
- * Add/Remove a user to/from a category.
- *
+ * Add/Remove a user to/from a group.
  * @param {Object} data the data from message payload
  * @returns {undefined}
  */
 async function manageVanillaUser (data) {
-  const { challengeId, action, handle: username, role: projectRole } = data
-  logger.info(`Managing users for challengeID=${challengeId} ...`)
+  const { challengeId, action, handle: username, projectRole, challengeRoles } = data
+  logger.info(`Managing user for challengeID=${challengeId} [action=${action}, handle=${username}, projectRole=${JSON.stringify(projectRole)}, challengeRoles=${JSON.stringify(challengeRoles)}]...`)
   const { body: groups } = await vanillaClient.searchGroups(challengeId)
   const group = groups.length > 0 ? groups[0] : null
 
-  // Only members and copilots will receive notifications
-  const watch = (!projectRole || projectRole === constants.TOPCODER.PROJECT_ROLES.COPILOT) ? 1 : 0
-  const follow = 1
+  const watch = shouldWatchCategories(projectRole, challengeRoles)
+  const follow = shouldFollowCategories(projectRole, challengeRoles)
 
   if (!group) {
     throw new Error('The group wasn\'t not found by challengeID')
@@ -77,7 +75,7 @@ async function manageVanillaUser (data) {
 
     const { body: user } = await vanillaClient.addUser(userData)
     vanillaUser = user
-    logger.info(`New user with UserID=${vanillaUser.userID} was added.`)
+    logger.info(`New user [UserID=${vanillaUser.userID}, Name=${vanillaUser.name}] was added.`)
   } else {
     // Get a full user profile with roles
     const { body: user } = await vanillaClient.getUser(vanillaUser.userID)
@@ -90,6 +88,7 @@ async function manageVanillaUser (data) {
       roleID: [...currentVanillaRoleIDs, ...userTopcoderRoleIDs]
     }
     await vanillaClient.updateUser(vanillaUser.userID, userData)
+    // logger.info(`Roles were synchronized for User [UserID=${vanillaUser.userID}, Name=${vanillaUser.name}].`)
   }
 
   // Choose action to perform
@@ -100,12 +99,12 @@ async function manageVanillaUser (data) {
         watch: watch,
         follow: follow
       })
-      logger.info(`The user '${vanillaUser.name}' was added to the group '${group.name}'`)
+      logger.info(`User [UserID=${vanillaUser.userID}, Name=${vanillaUser.name} was added to Group [GroupID=${group.groupID}, Name=${group.name}, Watch=${watch}, Follow=${follow}]`)
       break
     }
     case constants.USER_ACTIONS.KICK: {
       await vanillaClient.removeUserFromGroup(group.groupID, vanillaUser.userID)
-      logger.info(`The user '${vanillaUser.name}' was removed from the group '${group.name}'`)
+      logger.info(`User [UserID=${vanillaUser.userID}, Name =${vanillaUser.name} was removed from Group [GroupID=${group.groupID}, Name=${group.name}]`)
       break
     }
     default:
@@ -256,7 +255,12 @@ async function createVanillaGroup (challenge) {
       }
 
       for (const member of members) {
-        await manageVanillaUser({ challengeId: challenge.id, action: constants.USER_ACTIONS.INVITE, handle: member.handle, role: member.role })
+        await manageVanillaUser({
+          challengeId: challenge.id,
+          action: constants.USER_ACTIONS.INVITE,
+          handle: member.handle,
+          projectRole: member.role
+        })
       }
 
       challengeDetailsDiscussion.url = `${challengeCategory.url}`
@@ -319,6 +323,44 @@ async function createDiscussions (group, challenge, templateDiscussions, vanilla
   }
 }
 
+/**
+ * Auto-watch categories
+ * @param projectRole string
+ * @param challengeRoles array
+ * @returns {boolean}
+ */
+function shouldWatchCategories (projectRole, challengeRoles) {
+  // New user
+  if (!projectRole && _.isEmpty(challengeRoles)) {
+    return true
+  }
+
+  // Project Copilots / Challenge Copilots
+  return (projectRole === constants.TOPCODER.PROJECT_ROLES.COPILOT ||
+    (_.isArray(challengeRoles) && _.includes(challengeRoles, constants.TOPCODER.CHALLENGE_ROLES.COPILOT))
+  )
+}
+
+/**
+ * Auto-follow categories
+ * @param projectRole string
+ * @param challengeRoles array
+ * @returns {boolean}
+ */
+function shouldFollowCategories (projectRole, challengeRoles) {
+  // New user
+  if (!projectRole && _.isEmpty(challengeRoles)) {
+    return true
+  }
+
+  // Project Copilots or Managers / Challenge Copilots and Managers
+  return projectRole === constants.TOPCODER.PROJECT_ROLES.COPILOT ||
+    projectRole === constants.TOPCODER.PROJECT_ROLES.MANAGER ||
+    (_.isArray(challengeRoles) && (_.includes(challengeRoles, constants.TOPCODER.CHALLENGE_ROLES.COPILOT) ||
+        _.includes(challengeRoles, constants.TOPCODER.CHALLENGE_ROLES.MANAGER))
+    )
+}
+
 module.exports = {
   manageVanillaUser,
   createVanillaGroup,
diff --git a/src/utils/topcoder-api.util.js b/src/utils/topcoder-api.util.js
index 58e436d..641a292 100644
--- a/src/utils/topcoder-api.util.js
+++ b/src/utils/topcoder-api.util.js
@@ -110,11 +110,29 @@ async function getProject (projectId) {
   return reqToAPI('GET', path)
 }
 
+/**
+ * Gets the list of Resource Roles by challengeId
+ */
+async function getAllChallengeRoles (challengeId) {
+  const path = `${config.TOPCODER.API_URL}/v5/resources?challengeId=${challengeId}`
+  return reqToAPI('GET', path)
+}
+
+/**
+ * Gets the list of All Resource Roles
+ */
+async function getAllRoles () {
+  const path = `${config.TOPCODER.API_URL}/v5/resource-roles`
+  return reqToAPI('GET', path)
+}
+
 module.exports = {
   getUserDetailsById,
   getUserDetailsByHandle,
   getChallenge,
   updateChallenge,
   getRoles,
+  getAllRoles,
+  getAllChallengeRoles,
   getProject
 }