Name
global.ActivityDAO
Description
Gets installed as part of com.snc.activity_subscriptions plugin Activity Subscriptions Framework. Contains all the methods to perform Activity related operations.
Script
var ActivityDAO = Class.create();
ActivityDAO.prototype = {
initialize: function(activitySubContext) {
this.activitySubContext = activitySubContext;
this.subscriptionDAO = activitySubContext.getSubscriptionDAO();
this.ACTIVITY_STREAM_TABLE = "sn_actsub_activity_stream";
this.ACTIVITY_TYPE_TABLE = "sn_actsub_activity_type";
this.ACTIVITY_TABLE = "sn_actsub_activity";
this.STREAM_TABLE = "sn_actsub_user_stream";
this.ACTIVITY_FANOUT = "sn_actsub_activity_fanout";
this.ACTIVITY_RECORD_LIMIT = 50;
this.USER_STREAM_LIMIT = 2000;
this._isFanoutEnabled = 0;
this.ADVANCED_LEVEL_ACTIVITY_TYPE="65c47eca531332003760ddeeff7b125c";
this.VERB_MARK_AS_CORRECT_ANSWER = "mark_as_correct_ans";
this.VERB_MENTIONED = "mentioned";
this.activityStreamCache = new ActivityStreamCacheManager();
this.ENABLE_ACTIVITY_FANOUT_CONFIGURATION = gs.getProperty("com.snc.actsub.activity.enable_fanout_config") == "true";
},
getActivityJSON:function(activity)
{
var streamGr = new GlideRecord(this.ACTIVITY_STREAM_TABLE);
streamGr.addQuery('activity_id',activity.sys_id);
streamGr.addQuery('stream_id.user_id',activity.target_id);
streamGr.query();
if(streamGr.next()){
activity_json=JSON.parse(streamGr.activity_nl_string_json);
}
return activity_json;
},
getRelatedActivity: function(activity){
if(!activity) return;
var isUndo = activity.verb != activity.activity_type_id.verb;
var activity_type_id = activity.activity_type_id;
var relatedActivity = new GlideRecord(this.ACTIVITY_TABLE);
relatedActivity.addQuery('activity_type_id', activity_type_id.sys_id);
relatedActivity.addQuery('actor_id', activity.actor_id);
relatedActivity.addQuery('object_id', activity.object_id);
if(isUndo){
relatedActivity.addQuery('verb', activity_type_id.verb);
relatedActivity.addQuery('sys_created_on','<=', activity.sys_created_on);
relatedActivity.orderByDesc('sys_created_on');
}else {
relatedActivity.addQuery('verb',activity_type_id.undo_verb);
relatedActivity.addQuery('sys_created_on','>=', activity.sys_created_on);
relatedActivity.orderBy('sys_created_on');
}
relatedActivity.setLimit(1);
relatedActivity.query();
if(relatedActivity.next()){
return relatedActivity;
}
return;
},
getRelatedActivityById: function(activityId){
var activity = new GlideRecord(this.ACTIVITY_TABLE);
if(activity.get(activityId)){
return this.getRelatedActivity(activity);
}else return gs.getMessage("Either no activity available or not accessible.");
},
getActivity: function(activityId){
var cloneActivity = function(activity){
var _activity = {};
_activity.activity_type_id = '' + activity.activity_type_id;
_activity.actor_id = '' + activity.actor_id;
_activity.actor_name = '' + activity.actor_name;
_activity.additional_field1 = '' + activity.additional_field1;
_activity.additional_field1_name = '' + activity.additional_field1_name;
_activity.addl_sub_obj2 = '' + activity.addl_sub_obj2;
_activity.addl_sub_obj2_name = '' + activity.addl_sub_obj2_name;
_activity.addl_sub_obj3 = '' + activity.addl_sub_obj3;
_activity.addl_sub_obj3_name = '' + activity.addl_sub_obj3_name;
_activity.object_id = '' + activity.object_id;
_activity.object_name = '' + activity.object_name;
_activity.sys_created_by = '' + activity.sys_created_by;
_activity.sys_created_on = activity.sys_created_on;
_activity.sys_id = '' + activity.sys_id;
_activity.sys_updated_by = '' + activity.sys_updated_by;
_activity.sys_updated_on = activity.sys_updated_on;
_activity.target_id = '' + activity.target_id;
return _activity;
};
var activity = new GlideRecord(this.ACTIVITY_TABLE);
if(activity.get(activityId) && activity.canRead()){
var _activity = cloneActivity(activity);
_activity.isUndo = activity.verb != activity.activity_type_id.verb;
var activity_type_id = activity.activity_type_id;
var relatedActivity = new GlideRecord(this.ACTIVITY_TABLE);
relatedActivity.addQuery('activity_type_id', activity_type_id.sys_id);
relatedActivity.addQuery('actor_id', activity.actor_id);
if(_activity.isUndo){
relatedActivity.addQuery('verb', activity_type_id.verb);
relatedActivity.addQuery('sys_created_on','<=', activity.sys_created_on);
relatedActivity.orderByDesc('sys_created_on');
}else {
relatedActivity.addQuery('verb',activity_type_id.undo_verb);
relatedActivity.addQuery('sys_created_on','>=', activity.sys_created_on);
relatedActivity.orderBy('sys_created_on');
}
relatedActivity.setLimit(1);
relatedActivity.query();
if(relatedActivity.next() && relatedActivity.canRead()){
_activity.relatedActivity = cloneActivity(relatedActivity);
_activity.relatedActivity.isUndo = relatedActivity.verb != relatedActivity.activity_type_id.verb;
}
return _activity;
}else return gs.getMessage("Either no activity available or not accessible.");
},
flushStreamCacheForSubscribers : function(subscribers){
if (!subscribers)
return;
subscribers = subscribers.split(',');
this.activityStreamCache.flushStreams(subscribers);
},
getActivities: function(activity_count, streamID, start, end, before, actor, enableAggregation, isFirstLoad) {
try {
var _usr = "" + gs.getUserID();
var isCacheEnabled = gs.getProperty("com.snc.actsub.activity.stream.cache.enable") == "true";
start = parseInt(start);
end = parseInt(end);
before = before + "";
if (actor)
actor = actor + "";
var verbs = ['posted', 'advanced_a_level','content_moved_to'];
var liveProfileId = this.subscriptionDAO.getLiveProfileId(gs.getUserID());
var stream;
var sessionData;
var results = [];
if (isCacheEnabled) {
var _hasMore = true;
var reConstructStream = false;
var lastSynch = gs.getSession().getClientData('activity_stream_last_synch_time');
var hasNewUpdates = this.activityStreamCache.hasNewUpdates(_usr, lastSynch);
if (!hasNewUpdates) {
var _stream = gs.getSession().getClientData('activity_stream');
stream = JSON.parse(_stream);
}
var resetStream = function(){
stream = {};
stream.sys_id = "" + streamID;
stream.before = "" + before;
stream.actor = actor;
reConstructStream = true;
};
if (stream) {
_hasMore = stream.hasMoreRecords;
}
// Reset stream if there is no stream in cache
if (!stream || actor != stream.actor) {
resetStream();
}
if (!reConstructStream){
// If the request is from same origin and data exists in cache, return data from cache. OR
// If there are no new activities, return data from cache.
if (start < stream.data.length && (end <= stream.data.length || !_hasMore && end > stream.data.length )) {
return {
"activities": stream.data.slice(start, end),
"hasMoreRecords": stream.hasMoreRecords || end < stream.data.length,
"nextRecord": end,
"fromCache" : true
};
}
}
if (reConstructStream) {
stream.primaryContents = [];
stream.data = [];
}
} else {
var _sessionData = gs.getSession().getClientData('activity_stream_state');
sessionData = JSON.parse(_sessionData);
if(!sessionData || sessionData.before != before) {
sessionData = {};
sessionData.primaryContents = [];
sessionData.before = before + "";
}
}
var counter = 0;
var countToReturn = end - start;
var hasMoreRecords = true;
var limit = activity_count || this.ACTIVITY_RECORD_LIMIT;
var commActivityService, commUser;
if (this.activitySubContext.isCommunityPluginActive == true) {
commUser = new sn_communities.CommunityUserBase();
commActivityService = new sn_communities.CommunityActivityService(liveProfileId, true);
}
var from, to;
if (isCacheEnabled && stream) {
from = stream.nextWindowFrom;
to = stream.nextWindowTo;
}
// Find the window range based on requested limits.
// Case : 1 - No information available in cache
if (!from)
from = 0;
if (!to)
to = from;
if (isCacheEnabled && stream) {
//Case : 2 - Requesting more records
if (start > stream.data.length)
countToReturn = end - stream.data.length;
//Case : 3 - requesting existing records with unexpected start and end. It is similar to reload cache.
else if (start < stream.data.length) {
from = 0;
countToReturn = end;
}
}
else {
from = start;
}
// Interpret the offset based on the accuracy of previous fetch. This is a probability fetch.
// This will avoid extra round trips to DB
var getInterprettedOffset = function(requiredCount, probabilityRatio) {
var multiplier = 5;// expecting each activitity feed item duplicated 5 times w.r.t primary content
var getOffset = function(_offset) {
if (!_offset)
return 1;
else return _offset + 1;
};
if (!enableAggregation)
return getOffset(0);
if (!requiredCount)
requiredCount = countToReturn;
if (!probabilityRatio)
return getOffset(multiplier * requiredCount);
else {
if (!probabilityRatio || probabilityRatio < multiplier)
probabilityRatio = multiplier;
var offset = requiredCount * probabilityRatio;
// If offset is more, limit to some value to avoid fetching too many records from DB.
if (offset > multiplier * 100)
offset = multiplier * 100;
return getOffset(offset);
}
};
to = from + countToReturn + getInterprettedOffset(countToReturn);
var _previousTo;
// Reset from value to 0 if the no data available in session.
if (!isCacheEnabled && sessionData.primaryContents.length == 0) {
_previousTo = from;
from = 0;
}
if (isCacheEnabled) {
var longTime = (new GlideDateTime()).getNumericValue();
gs.getSession().putClientData('activity_stream_last_synch_time', ""+longTime);
this.activityStreamCache.streamLoaded(_usr, "" + longTime);
}
var currentRow = 0;
var disqualifiedContents = [];
var _nextRecord;
while ((counter <= countToReturn ) && hasMoreRecords) {
currentRow = from;
var activities = new GlideRecord(this.ACTIVITY_STREAM_TABLE);
activities.addQuery('stream_id', streamID);
if (actor) {
activities.addQuery('activity_id.actor_id', actor);
} else {
activities.addQuery('activity_id.actor_id', '!=', liveProfileId)
.addOrCondition('activity_id.verb', 'IN', verbs.join(','));
}
activities.addQuery('activity_id.active', true);
activities.orderByDesc("activity_id.sys_created_on");
if (before)
activities.addQuery('sys_created_on', '<=', before);
activities.chooseWindow(from, to);
activities.query();
var activitiesCount = 0;
while ((counter <= countToReturn) && activities.next()) {
currentRow++;
if (currentRow >= activities.getRowCount())
hasMoreRecords = false;
var activity = activities.activity_id.getRefRecord();
var aggAct;
var primaryContent;
if (commActivityService != null) {
aggAct = commActivityService.getContentInfo(activity);
// Check if already an activity processed for this activity's content
if (aggAct) {
primaryContent = aggAct.root + "";
if (!primaryContent) {
continue; // No primary or secondary content exists with this activity.
}
if (enableAggregation) {
if (disqualifiedContents.indexOf(primaryContent) != -1) {
continue;
}
if ( !isCacheEnabled && sessionData && sessionData.primaryContents.indexOf(primaryContent) != -1 ||
isCacheEnabled && stream && stream.primaryContents.indexOf(primaryContent) != -1) {
disqualifiedContents.push(primaryContent);
continue;
}
//aggAct.activity_stream = "" + activities.sys_id;
}
var moderatedContent = commActivityService.getModeratedContentId(aggAct);
if (moderatedContent) {
if (enableAggregation) {
disqualifiedContents.push(moderatedContent+"");
}
continue;
}
}
if (!commActivityService.canReadActivityStream(activities, commUser) ){
continue; //check for read access
}
}
else if (!activities.canRead()) {
continue; //check for read access with ACL evaluation.
}
if (counter >= countToReturn) {
counter++;
hasMoreRecords = true;
continue;
}
// Re-construct the previous pages primary content sys_ids.
if (!isCacheEnabled && currentRow <= _previousTo) {
if (primaryContent)
sessionData.primaryContents.push(primaryContent);
} else {
var activity_json;
if (activity.getElement('actor_id') &&
activity.getElement('object_id') &&
activity.getElement('target_id')) {
if (commActivityService != null) {
activity_json = commActivityService.getActivityStreamJSON(activity, '' + activities.activity_nl_string_json, {'actor': actor});
if(commActivityService.skipActivity){
var idx = disqualifiedContents.indexOf(primaryContent);
if(idx > -1) disqualifiedContents.splice(idx, 1);
continue;
}
}
if (activity_json && activity.activity_type_id.use_stream_json)
activity_json.streamJSON = activities.activity_nl_string_json;
if (activity_json) {
counter++;
if (counter == countToReturn) {
_nextRecord = 0 + currentRow;
}
if (enableAggregation) {
if (primaryContent){
if (isCacheEnabled && stream)
stream.primaryContents.push(primaryContent);
else if(sessionData)
sessionData.primaryContents.push(primaryContent);
}
}
if (isCacheEnabled && stream) {
stream.data.push(activity_json);
} else
results.push(activity_json);
activitiesCount++;
}
}
}
}
if (activities.getRowCount() == 0 || activities.getRowCount() <= from) {
hasMoreRecords = false;
}
var requiredCount = parseInt(countToReturn - counter);
var probabilityRatio = ((to - from)/(activitiesCount));
from = parseInt(to);
to = parseInt(to) + requiredCount + getInterprettedOffset(requiredCount, probabilityRatio);
}
var _activities;
if(isCacheEnabled) {
// Stream save point: Update the stream & put back into the cache.
stream.nextWindowFrom = _nextRecord;
stream.nextWindowTo = to + countToReturn;
stream.hasMoreRecords = hasMoreRecords;
gs.getSession().putClientData('activity_stream', JSON.stringify(stream));
_activities = stream.data.slice(start, end);
if(hasMoreRecords)
_nextRecord = end;
else
_nextRecord = null;
} else {
gs.getSession().putClientData('activity_stream_state', JSON.stringify(sessionData));
_activities = results;
if(!hasMoreRecords)
_nextRecord = null;
}
return {
"activities": _activities,
"hasMoreRecords": hasMoreRecords,
"nextRecord": _nextRecord
};
} catch (er) {
gs.info('Error while fetching activity stream: ' + er.message);
}
},
isFanoutEnabled: function(streamID){
var gr = new GlideRecord(this.STREAM_TABLE);
gr.addQuery('sys_id',streamID);
gr.query();
if(gr.next()){
this._isFanoutEnabled = gr.getValue('fanout_to_stream');
return this._isFanoutEnabled;
}
return 0;
},
initiateFanout: function(current) {
var encodedQuery;
if (this.ENABLE_ACTIVITY_FANOUT_CONFIGURATION) {
var activityTypeGr = new GlideRecord(this.ACTIVITY_TYPE_TABLE);
activityTypeGr.addActiveQuery();
activityTypeGr.addQuery('sys_id', current.activity_type_id);
activityTypeGr.query();
if (activityTypeGr.next())
encodedQuery = 'sys_idIN' + activityTypeGr.activity_fanouts;
}
var gr = new GlideRecord(this.ACTIVITY_FANOUT);
gr.addQuery('active', true);
if (encodedQuery)
gr.addEncodedQuery(encodedQuery);
gr.orderBy("order");
gr.query();
while (gr.next()) {
gs.eventQueue(gr.fanout_event.getDisplayValue(), current, '', '');
}
},
getActivityType: function(sourceTable, verb, module){
if(!sourceTable)return null;
var gr = new GlideRecord(this.ACTIVITY_TYPE_TABLE);
gr.addQuery('activity_source_table',sourceTable);
gr.addActiveQuery();
if(verb)
gr.addQuery('verb',verb);
if (module) {
gr.addQuery('module', module);
gr.addQuery('module.active', true);
}
gr.query();
if(gr.next())return gr;
return null;
},
getActivityTypeForAdmin: function(activityId){
var gr = new GlideRecord(this.ACTIVITY_TYPE_TABLE);
gr.addQuery('sys_id',activityId);
gr.query();
if(gr.next())return gr;
return null;
},
initializeActivity:function(){
var gr = new GlideRecord(this.ACTIVITY_TABLE);
gr.newRecord();
return gr;
},
createActivity: function(source, verb, isUndoActivity, activityGr, valueMap, module) {
var activityType = this.getActivityType(source.getTableName(), verb, module);
if(!activityType){
try{
var sourceTable = source.getTableName();
var parentTable = GlideDBObjectManager.get().getBase(sourceTable);
if(parentTable && parentTable != sourceTable){
activityType = this.getActivityType(parentTable, verb, module);
}
}
catch(er){
gs.info('Error while fetching activity type for parent table: ' + er.message);
}
}
try{
if(activityType && (!isUndoActivity || (isUndoActivity && activityType.undo_verb))){
var source_table = '' + source.getTableName();
var source_id = source.sys_id;
var actorField = '' + activityType.actor_field;
var objectField = activityType.object_field;
var targetField = activityType.target_field;
var additionalField1 = activityType.additional_field1;
var addlSubObj2 = activityType.addl_sub_obj2;
var addlSubObj3 = activityType.addl_sub_obj3;
var gr;
if(!activityGr){
gr = new GlideRecord(this.ACTIVITY_TABLE);
gr.initialize();
}
else{
gr=activityGr;
}
gr.activity_type_id = '' + activityType.sys_id;
var isReferenceField = this._isReferenceField(source,actorField);
if(isReferenceField){
gr.actor_name = '' + source.getElement(actorField).getED().getReference();
gr.actor_id = '' + source.getElement(actorField);
}
else{
gr.actor_name = '' + source.getTableName();
gr.actor_id = '' + source.getValue(actorField);
}
var isActorSessionUser = activityType.actor_is_session_user;
if(isActorSessionUser == true)
gr.actor_id = '' + this.subscriptionDAO.getLiveProfileId(gs.getUserID());
isReferenceField = this._isReferenceField(source,objectField);
if(isReferenceField){
gr.object_name = source.getElement(objectField).getED().getReference();
//For document_id field references
if(!gr.object_name)
gr.object_name = '' + source.getValue(source.getElement(objectField).getED().getDependent());
gr.object_id = '' + source.getElement(objectField);
}
else{
gr.object_name = '' + source.getTableName();
gr.object_id = '' + source.getValue(objectField);
}
if(targetField) {
isReferenceField = this._isReferenceField(source,targetField);
if(isReferenceField){
gr.target_name = source.getElement(targetField).getED().getReference();
//For document_id field references
if(!gr.target_name){
gr.target_name = '' + source.getValue(source.getElement(targetField).getED().getDependent());
}
gr.target_id = '' + source.getElement(targetField);
}
else{
gr.target_name = '' + source.getTableName();
gr.target_id = '' + source.getValue(targetField);
}
}
if(additionalField1){
isReferenceField = '' + this._isReferenceField(source,additionalField1);
if(isReferenceField){
gr.additional_field1_name = '' + source.getElement(additionalField1).getED().getReference();
if(!gr.additional_field1_name)
gr.additional_field1_name = source.getValue(source.getElement(additionalField1).getED().getDependent());
gr.additional_field1 = '' + source.getElement(additionalField1);
if(gr.additional_field1_name == 'sn_communities_topic'
&& !gr.additional_field1 && source.topics)
gr.additional_field1 = '' + source.topics;
}
else{
gr.additional_field1_name = '' + source.getTableName();
gr.additional_field1 = '' + source.getValue(additionalField1);
}
if (valueMap && valueMap.additional_field1)
gr.additional_field1 = '' + valueMap.additional_field1;
}
if(addlSubObj2){
isReferenceField = this._isReferenceField(source,addlSubObj2);
if(isReferenceField){
gr.addl_sub_obj2_name = source.getElement(addlSubObj2).getED().getReference() || source.getElement('reference_name');
gr.addl_sub_obj2_name = gr.addl_sub_obj2_name || source.getValue(source.getElement(addlSubObj2).getED().getDependent());
gr.addl_sub_obj2 = '' + source.getElement(addlSubObj2);
if(gr.addl_sub_obj2_name == 'sn_communities_content'
|| gr.addl_sub_obj2_name == 'kb_social_qa_comment'){
if(source.root_id){
gr.addl_sub_obj2_name = source.root_id.content_name;
gr.addl_sub_obj2 = source.root_id.content_id;
}else{
gr.addl_sub_obj2_name = source.content_name;
gr.addl_sub_obj2 = source.content_id;
}
if(source.getTableName() == 'kb_social_qa_comment'){
gr.addl_sub_obj2_name = source.content.root_id.content_name;
gr.addl_sub_obj2 = source.content.root_id.content_id;
}
}
}
else{
gr.addl_sub_obj2_name = '' + source.getTableName();
gr.addl_sub_obj2 = '' + source.getValue(addlSubObj2);
}
}
if(addlSubObj3){
isReferenceField = this._isReferenceField(source,addlSubObj3);
if(isReferenceField){
gr.addl_sub_obj3_name = source.getElement(addlSubObj3).getED().getReference();
gr.addl_sub_obj3_name = gr.addl_sub_obj3_name || source.getValue(source.getElement(addlSubObj3).getED().getDependent());
gr.addl_sub_obj3 = '' + source.getElement(addlSubObj3);
}
else{
gr.addl_sub_obj3_name = '' + source.getTableName();
gr.addl_sub_obj3 = '' + source.getValue(addlSubObj3);
}
}
if(isUndoActivity == true && gr.activity_type_id.undo_verb) {
gr.verb = gr.activity_type_id.undo_verb;
gr.active =false;
var parent = new GlideRecord(this.ACTIVITY_TABLE);
parent.addQuery('activity_type_id', gr.activity_type_id.sys_id);
parent.addQuery('verb', gr.activity_type_id.verb);
parent.addQuery('object_id', gr.object_id);
if(gr.activity_type_id.verb != this.VERB_MARK_AS_CORRECT_ANSWER)
parent.addQuery('actor_id', gr.actor_id);
parent.addQuery('active', true);
parent.orderByDesc('sys_created_on');
parent.setLimit(1);
parent.query();
if(parent.next()){
parent.active = false;
parent.update();
}
else
return;
}
else gr.verb = gr.activity_type_id.verb;
gr.insert();
}
}catch(err){
gs.info('ACTSUB-ERROR in createActivity:' + err.message);
}
},
_isReferenceField: function(source,fieldName){
return (fieldName && (fieldName.indexOf('.') != -1 || source.getElement(fieldName).getRefRecord())) ? true : false;
},
populateActivityStream: function(activity,subscribers,activityJSON, additionalAttributes){
subscribers = subscribers.split(',');
var streamCountMap = this.getStreamCountMap(subscribers);
for(var stream in streamCountMap){
var activitiesCount = streamCountMap[stream];
var userStreamLimit = parseInt(gs.getProperty('com.snc.actsub.activity.stream.user.limit', this.USER_STREAM_LIMIT));
if(activitiesCount >= userStreamLimit){
this._autoRotateActivityStream(stream);
}
var gr = new GlideRecord(this.ACTIVITY_STREAM_TABLE);
gr.initialize();
gr.activity_id = activity.sys_id;
gr.stream_id = stream;
var activity_json = {};
if(activityJSON!=null){
activity_json = activityJSON;
}
else if(activity.activity_type_id.sys_id==this.ADVANCED_LEVEL_ACTIVITY_TYPE){
if(!pm.isActive('com.snc.gamification'))
return;
var streamGr = new GlideRecord(this.ACTIVITY_STREAM_TABLE);
streamGr.addQuery('activity_id',activity.sys_id);
streamGr.addQuery('stream_id.user_id',activity.target_id);
streamGr.query();
if(streamGr.next()){
activity_json=JSON.parse(streamGr.activity_nl_string_json);
}
if(JSON.stringify(activity_json) == '{}'){
var validObjectNames = [];
validObjectNames.push(sn_gamification.GamificationConstants.MODULE_TABLE);
if(this.activitySubContext.isCommunityPluginActive == true){
validObjectNames.push(sn_communities.CommunityConstants.FORUM_TABLE);
if(sn_communities.CommunityConstants.ENABLE_TOPICS)
validObjectNames.push(sn_communities.CommunityConstants.TOPIC_TABLE);
}
activity_json = new sn_gamification.GamificationLevel().getLevelAdvancedJSON(activity.getValue('sys_created_on'), activity.getValue('actor_id'), activity.getValue('addl_sub_obj2'), validObjectNames);
}
if(activity_json == null || JSON.stringify(activity_json) == '{}'){
return;
}
}
else{
activity_json = {
"message": activity.activity_type_id.activity_nl_string.message+'',
"actor": activity.getElement('actor_id').getRefRecord().getDisplayValue(),
"object": activity.getElement('object_id').getRefRecord().getDisplayValue(),
"target": activity.getElement('target_id').getRefRecord().getDisplayValue()
};
}
if(additionalAttributes) {
for(var att in additionalAttributes) {
activity_json[att] = additionalAttributes[att];
}
}
gr.activity_nl_string_json = new global.JSON().encode(activity_json);
gr.insert();
}
},
getActivitiesCountByUserInStream: function(stream, profileId, fetchPrimary){
var ga = new GlideAggregate(this.ACTIVITY_STREAM_TABLE);
ga.addQuery('stream_id',stream);
//Activity Feed should be enabled when atleast 5 primary activities(post, advanced a level, badge awarded) are done
if(fetchPrimary)
ga.addQuery('activity_id.actor_id', '!=', profileId)
.addOrCondition('activity_id.verb','IN','posted,advanced_a_level');
ga.addAggregate('COUNT');
ga.query();
var activitiesCount = 0;
if(ga.next())
activitiesCount = ga.getAggregate('COUNT');
return activitiesCount;
},
//Invalidates the oldest record in the user's activity stream
_autoRotateActivityStream: function(stream){
var gr = new GlideRecord(this.ACTIVITY_STREAM_TABLE);
gr.orderBy('activity_id.sys_created_on');
gr.addQuery('stream_id',stream);
gr.setLimit(1);
gr.query();
//marking the stream as empty to invalidate the record, it will be deleted through scheduled job
if(gr.next()){
gr.setValue('stream_id', '');
gr.setWorkflow(false);
gr.autoSysFields(false);
gr.update();
}
},
getStreamID: function(stream,userId){
var gr = new GlideRecordSecure(this.STREAM_TABLE);
gr.addQuery('name',stream);
gr.addQuery('user_id',userId);
gr.query();
if(gr.next()){
this._isFanoutEnabled = gr.getValue('fanout_to_stream');
return gr.sys_id;
}
return null;
},
getStreamRecord: function(streamId){
var gr = new GlideRecord(this.STREAM_TABLE);
gr.addQuery('sys_id', streamId);
gr.query();
return gr;
},
_getStreamsforUser: function(userId){
var stream_ids = [];
var gr = new GlideRecord(this.STREAM_TABLE);
gr.addQuery('user_id.document',userId);
gr.addQuery('fanout_to_stream',true);
gr.query();
while(gr.next()){
stream_ids.push(gr.sys_id+'');
}
return stream_ids;
},
findNonZeroMinimum:function(){
var args = Array.prototype.slice.call(arguments);
args.sort(function(a, b){
if(a === null || isNaN(a) || a === 0) return 1;
if(b === null || isNaN(b) || b === 0) return -1;
return a-b;
});
return args[0];
},
_getRecentNthActivityCrDt: function(limitCount){
var activities = new GlideRecord(this.ACTIVITY_TABLE);
activities.orderByDesc('sys_created_on');
activities.setLimit(limitCount);
activities.setCategory('homepage');
activities.query();
if(activities.getRowCount() < limitCount)
return null;
activities.setLocation(limitCount-1);
return activities.getDisplayValue('sys_created_on');
},
getActivityInfo: function(activityId) {
if(!activityId)
return null;
var activity = new GlideRecord(this.ACTIVITY_TABLE);
if(activity.get(activityId)) {
var activityInfo = {};
activityInfo.active = activity.active + '';
activityInfo.activity_type_id = activity.activity_type_id + '';
activityInfo.actor_id = activity.actor_id + '';
activityInfo.object_id = activity.object_id + '';
activityInfo.object_name = activity.object_name + '';
activityInfo.target_id = activity.target_id + '';
activityInfo.target_name = activity.target_name + '';
activityInfo.verb = activity.verb+ '';
return activityInfo;
}
return null;
},
/*
* This function updates the access time of the given stream with current date time. This enables us to track
the usage of streams and enhance the system based on the usage
* @parameter - streamID: sys_id of the stream which has been accessed and last access time need to be updated
* @return - void
*/
updateLastAccessTime: function(streamID){
var dateTime = new GlideDateTime();
var stream_gr = new GlideRecord(this.STREAM_TABLE);
stream_gr.addQuery('sys_id', streamID);
stream_gr.query();
if(stream_gr.next()){
stream_gr.setValue('last_accessed_on', dateTime);
stream_gr.update();
}
else{
gs.error('ACTSUB-ERROR: Unable to update stream ' + streamID);
}
return dateTime;
},
getStreamCountMap: function(subscribers){
var ga = new GlideAggregate(this.ACTIVITY_STREAM_TABLE);
ga.addQuery('stream_id.user_id.document', 'IN', subscribers);
ga.addQuery('stream_id.fanout_to_stream', 'true');
ga.addAggregate('COUNT','stream_id');
ga.query();
var map = {};
while(ga.next()){
map[ga.stream_id + ''] = ga.getAggregate('COUNT','stream_id');
}
var gr = new GlideRecord(this.STREAM_TABLE);
gr.addQuery('user_id.document', 'IN', subscribers);
gr.addQuery('fanout_to_stream', 'true');
gr.query();
while(gr.next()){
map[gr.sys_id] = (map[gr.sys_id])?map[gr.sys_id]:0;
}
return map;
},
//Creates Activity without running workflow engines, and sets the system fields as per the system fields of the source
createActivityWithoutRunningEngines: function(source, verb, module) {
try {
var activityType = this.getActivityType(source.getTableName(), verb, module);
if (activityType) {
var source_table = '' + source.getTableName();
var source_id = source.sys_id;
var actorField = '' + activityType.actor_field;
var objectField = activityType.object_field;
var targetField = activityType.target_field;
var additionalField1 = activityType.additional_field1;
var addlSubObj2 = activityType.addl_sub_obj2;
var addlSubObj3 = activityType.addl_sub_obj3;
var gr = new GlideRecord(ActivityConstants.TABLE_ACTIVITY);
gr.initialize();
gr.activity_type_id = '' + activityType.sys_id;
var fieldObj = this._getFieldValues(source, actorField);
gr.actor_name = fieldObj.name;
gr.actor_id = fieldObj.id;
fieldObj = this._getFieldValues(source, objectField);
gr.object_name = fieldObj.name;
gr.object_id = fieldObj.id;
fieldObj = this._getFieldValues(source, targetField);
gr.target_name = fieldObj.name;
gr.target_id = fieldObj.id;
if (additionalField1) {
fieldObj = this._getFieldValues(source, additionalField1);
gr.additional_field1_name = fieldObj.name;
gr.additional_field1 = fieldObj.id;
}
if (addlSubObj2) {
fieldObj = this._getFieldValues(source, addlSubObj2);
gr.addl_sub_obj2_name = fieldObj.name;
gr.addl_sub_obj2 = fieldObj.id;
}
if (addlSubObj3) {
fieldObj = this._getFieldValues(source, addlSubObj3);
gr.addl_sub_obj3_name = fieldObj.name;
gr.addl_sub_obj3 = fieldObj.id;
}
gr.verb = activityType.verb;
gr.setValue("sys_created_on", source.getValue("sys_created_on"));
gr.setValue("sys_updated_on", source.getValue("sys_updated_on"));
gr.sys_created_by = source.sys_created_by + "";
gr.sys_updated_by = source.sys_updated_by + "";
gr.setWorkflow(false);
gr.autoSysFields(false);
gr.insert();
}
} catch (e) {
gs.info("ACTSUB-ERROR in createActivityWithoutRunningEngines for table: " + source.getTableName() + ", sys_id: "+source.sys_id);
}
},
_getFieldValues: function(source, fieldName) {
if (!fieldName) return {};
var result = {};
var isReferenceField = this._isReferenceField(source, fieldName);
if (isReferenceField) {
result.name = '' + source.getElement(fieldName).getED().getReference();
result.name = result.name || source.getValue(source.getElement(fieldName).getED().getDependent()) + '';
result.id = '' + source.getElement(fieldName);
} else {
result.name = '' + source.getTableName();
result.id = '' + source.getValue(fieldName);
}
return result;
},
updateFanoutToStream: function(streamId, valueToUpdate){
var gr = new GlideRecord(this.STREAM_TABLE);
gr.addQuery('sys_id', streamId);
gr.query();
if(gr.next()){
gr.setValue('fanout_to_stream', valueToUpdate);
gr.update();
return new GlideDateTime();
}
return null;
},
filterByFanoutFlag: function(subscribersList){
if(!subscribersList)
return [];
var filteredList = [];
var gr = new GlideRecord(this.STREAM_TABLE);
gr.addQuery('user_id.document', 'IN', subscribersList);
gr.addQuery('fanout_to_stream', true);
gr.query();
while(gr.next()){
if(gr.user_id && gr.user_id.document){
var subscriber = gr.user_id.document.toString();
if(filteredList.indexOf(subscriber) < 0)
filteredList.push(subscriber);
}
}
return filteredList;
},
getLatestActivityForStream: function(streamId){
var actStreamGr = new GlideRecord(this.ACTIVITY_STREAM_TABLE);
actStreamGr.addQuery('stream_id', streamId);
actStreamGr.orderByDesc('activity_id.sys_created_on');
actStreamGr.setLimit(1);
actStreamGr.query();
return actStreamGr;
},
getActivitiesForInterval: function(subscriptions, liveProfileId, fromTime, toTime, window){
var followingUsers = this.subscriptionDAO.getFollowedUsersByProfile(liveProfileId);
var activities = new GlideRecord(this.ACTIVITY_TABLE);
activities.addActiveQuery();
activities.addQuery('object_id', 'IN', subscriptions)
.addOrCondition('target_id', 'IN', subscriptions)
.addOrCondition('additional_field1', 'IN', subscriptions)
.addOrCondition('addl_sub_obj2', 'IN', subscriptions)
.addOrCondition('addl_sub_obj3', 'IN', subscriptions)
.addOrCondition('target_id', liveProfileId)
.addOrCondition('actor_id', 'IN', followingUsers)
.addOrCondition('verb', this.VERB_MENTIONED);
if(fromTime)
activities.addQuery('sys_created_on','>', fromTime);
if(toTime)
activities.addQuery('sys_created_on', '<=', toTime);
if(window && window.from && window.to){
activities.chooseWindow(window.from, window.to);
}
activities.orderByDesc("sys_created_on");
activities.query();
return activities;
},
getActivitiesFromEncodedQuery: function(encodedQuery, window){
var activities = new GlideRecord(this.ACTIVITY_TABLE);
activities.addEncodedQuery(encodedQuery);
if(window){
if(window.from && window.to)
activities.chooseWindow(window.from, window.to);
}
activities.query();
return activities;
},
resetFanoutForInactiveStreams: function(pullStreamTypes, referenceDate){
var streamGr = new GlideRecord(this.STREAM_TABLE);
streamGr.addQuery('name', 'IN', pullStreamTypes);
streamGr.addQuery('fanout_to_stream', true);
streamGr.addNullQuery('last_accessed_on').addOrCondition('last_accessed_on', '<', referenceDate);
streamGr.setValue('fanout_to_stream', false);
streamGr.updateMultiple();
},
getInactiveStreams: function(pullStreamTypes){
if(!pullStreamTypes)
return null;
var streamGr = new GlideRecord(this.STREAM_TABLE);
streamGr.addQuery('name', 'IN', pullStreamTypes);
streamGr.addQuery('fanout_to_stream', false);
streamGr.query();
return streamGr;
},
//Deletes records in the user's activity stream where stream_id is null
deleteInvalidRecords: function(){
try{
gs.info("ACTSUB-INFO: Deleting invalid records from activity stream table");
var gr = new GlideRecord(this.ACTIVITY_STREAM_TABLE);
gr.addNullQuery('stream_id');
gr.setWorkflow(false);
gr.deleteMultiple();
}
catch(er){
gs.info('ACTSUB-ERROR: Exception while deleting records from activity stream: ' + er.message);
}
},
type: 'ActivityDAO'
};
Sys ID
5faf7f43db403200fa9b32d8f0b8f547