How do I get a user's Connect presence via script?

danawalsh
Kilo Contributor

So this might be a bit of a tricky one.

The whole story: I'm looking to automate new incident assignment (incidents are inbound via email and self-service) in a round-robin fashion to all members assigned to the group "Support", but only where they are currently online in ServiceNow.

I was hoping to do this by tapping into Connect somehow to obtain a person's presence. So for example:

Tech 1 - online

Tech 2 - offline

Tech 3 - online

If three new incidents are logged, my auto-assign script would assign the first incident to Tech 1, the second to Tech 3 and the third to Tech 1 again.

What I'm having trouble with is locating where in the DB that a user's presence is recorded. I've found some details around user sessions and transactions, even live profiles, but nothing that gives me a definitive flag of "online" or "true", etc.

Does anyone know how to script a function to accurately retrieve a user's current Connect presence?

Any help much appreciated!

7 REPLIES 7

Geoffrey2
ServiceNow Employee
ServiceNow Employee

Have you looked at the User Presence [sys_user_presence] table?



I think you're going to face a fundamental challenge in that it's hard to know for sure if someone is "offline". If you think about basic web architecture: servers (your ServiceNow instance) receive requests from clients (your User's browser) and respond to them. So "offline" is really just the amount of time it has been since the last request/activity. Someone could be offline and shutdown their computer 30 seconds after the last page load.   Or someone could still be reading a Knowledge Article, and "online", an hour after loading it. It's just guess-work. The only definitive evidence that someone is offline would be the logout event in the Event log. But how often does someone actually click the logout button? They usually just close the browser.


Hi geoffrey.sage, thanks for the feedback.



I agree, it's going to be a bit of guess work on my end to determine the presence of a user if I'm unable to retrieve it from the database as a flag.



Maybe what I should instead do is look at creating work schedules (i.e. 8am to 6pm) and relate those to the users in my Support group. Then use a two-handed approach: based on the ticket created date/time, find all Support members that are scheduled to be working, and of those, check who has had a recent transaction/session within the last five minutes (our Support techs live in ServiceNow, so the transactions should be very frequent).



Any holes or issues with that approach?



Cheers


hi Dan,



Some more googling and found this...


https://servicenowgems.com/2016/04/28/finding-logged-in-users/



perhaps you could try scheduling a 15 mins schedule job and populate a custom table to get the full login view on all nodes?



hope this helps.


hi Dan,



I did a quick one, create a custom table u_custom_session, 2 field, u_user, u_node.


add the following schedule script that runs 15 mins on all nodes.


Seems working for me.



function getCurrentNode() {


var logs = new GlideRecord('syslog_transaction');


var userID = gs.getUser().getName();


  logs.addQuery('sys_created_by', userID);


  logs.addQuery('sys_created_on', '>', gs.minutesAgo(15)); // This is arbitrary


  logs.orderBy('sys_created_on');


  logs.setLimit(1);


  logs.query();


  var retVal;


  if (logs.next())  


  {


  var node = logs.system_id.toString();


  var num = node.indexOf(':');


  var nodeName = node.substring(parseInt(num + 1), parseInt(node.length));  


  retVal = nodeName;


  }


return retVal;


}




var currentNodeName = getCurrentNode();


var gr3 = GlideRecord('u_custom_session');


gr3.addQuery('u_node',currentNodeName);


gr3.query();


while(gr3.next()){


gs.log(currentNodeName+': deleting... '+gr3.u_user);


gr3.deleteRecord();


}




var gr = GlideRecord('v_user_session');


gr.query();


while (gr.next()){


gs.log(currentNodeName+": Logged in user: " + gr.user);


var gr2 = GlideRecord('u_custom_session');


gr2.query('u_user',gr.user);


gr2.query();



var foundUser = gr2.next();


gs.log(currentNodeName+": Found =" + foundUser);


//Not Found, add to session


if(!foundUser)


{


gs.log(currentNodeName+": Not found, adding " + gr.user);


var newRequest = GlideRecord('u_custom_session');


newRequest.u_user = gr.user;


newRequest.u_node = currentNodeName;


newRequest.insert();


}


}



hope this helps.