Overview
To stand up our first requested survey, Yale opted to use the Best Practice - Task Survey Management Plugin because of the way it simplifies notification conditions.
Customer Satisfaction Survey (Incident)
This is our first survey. It is described here as reference for future implementations.
Original Stories
- the normal resolution email notification should offer the contact a (prominent) link to an optional survey (this notification is not fired for incidents tagged as invalid or duplicate)
- (in spite of SSO) anyone, even non-authN'd contacts should be able to use the survey
- responses need to refer descriptively to the original incident (so the user doesn't have to drill down just to decide whether or not to care about the notification)
- if the respondent requests a follow-up, explicitly alert the manager of the original assignment group
- data about responses should be made available to all managers for ad hoc reporting
- a number of a la carte reports were requested (detail omitted for brevity)
Survey Master
The first step was to create a new survey master "Customer Satisfaction Survey" with appropriate questions. In our case, we made the survey public via the provided UI action.
SSO Changes
When SSO is on, "public" pages are still not available by default – the user hits the auth wall. A modification to the SAML Login Script provides an exception for surveys; summary of change below:
process : function() { var saml_passed = true; + + var qs = request.getQueryString(); + this.logDebug('qs = ' + qs); + if(qs) { + if(qs.match(/survey_take.do/g)) { + return this.loginUser('guest'); + } + } var samlResponse = request.getParameter("SAMLResponse"); var relayState = request.getParameter("RelayState");
...YMMV. In our instance, the resulting behavior is that for surveys, the user is logged in as guest and given access to the survey. A minor downside to this is that you really don't know who filled out the survey; in any case, it's done on behalf of the original incident contact (and likely, it is actually the contact). Subsequent attempts to log in hit the authN wall, as you would hope.
Survey Conditions
The plugin provides "Survey Conditions" – a set of table filters relating to a particular master. For any table (task, incident, etc) and exactly one user field in that table, we defined:
- the conditions in the table under which the survey should be offered
- the user who should be offered the survey (we used a custom field we call
Contact
)
If the conditions match, an event will fire (with the user as the first parameter and the nav_to URL of the survey as the second parameter) per a business rule included with the plugin.
Keep in mind that there is some opportunity for a sort of "defense of depth" or just plain confusion, depending on what side you want to err on (more notifications or fewer notifications): any email notification triggered by this event could contain overlapping conditions.
Email Notification
We had an existing resolution notification which we replaced. The new notification fires upon receipt of the plugin's canned event "task.send_survey". We included conditions which match (overlap) with those of the survey conditions, since future state could conceivably include this event being fired for other tasks.
This notification includes a mail_script hack that modifies the second parameter in-flight in order to break the survey out of the standard frameset; the resulting URL is presented in a prominent CSS "button":
<mail_script> // bw - since this survey is meant to be frameless, strip the nav_to part of the url. var url = event.parm2.replace("nav_to.do?uri=", ""); url = url.replace(/%20/g, '+'); url = url.replace(/%26/g, '&'); template.print('<table><tr><td align="center" width="300" bgcolor="#0F4D92" style="background: #0F4D92; padding-top: 6px; padding-right: 10px; padding-bottom: 6px; padding-left: 10px; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; color: #fff; font-weight: bold; text-decoration: none; font-family: Helvetica, Arial, sans-serif; display: block;"><a href="' + url + '" style="color: #fff; text-decoration: none;">Click here to take the survey</a></td></tr></table>'); </mail_script>
Manager Data Access for Reporting
- A number of reports were requested and provided as gauges, then added to Survey->Overview
- The
survey_reader
role was granted to a new role group called "SURVEY_READER"; all current assignment group managers added to this role group. - The Survey application was tweaked to limit visibility of Masters, Conditions, etc to hide them from
survey_reader
. - For convenience, an "Incident Responses" view was created with interesting dot-walks for this survey's data (
task_survey
table) - For even more convenience, a CSV download link was created to enable quick download of this survey's data.
Follow-Up Alert
It was decided that to implement this feature, a task would be created whenever a respondent requests a follow-up (as offered in the survey). This was accomplished by an "after" business rule on the survey_response
table. The condition is supposed to ensure that a task is created only for a matching survey, question, and answer combination:
- Rule Type: run on server after Insert or Update
- Condition:
current.instance.survey.name.match(/Customer Satisfaction Survey/g) != null && current.question.question_text.match(/follow up/g) != null && current.answer.match(/Yes/g) != null
- Script:
// // open a task (grab instance name, then get the task survey, then the incident, then the assignment group) var instance = current.instance.sys_id; var survey = new GlideRecord('task_survey'); survey.addQuery('instance', instance); survey.query(); if(survey.next()) { newtask = new GlideRecord('task'); newtask.short_description = 'Customer Satisfaction Survey Follow-Up' newtask.parent = survey.task; newtask.assigned_to = survey.task.assignment_group.manager; newtask.cmdb_ci = survey.task.u_component; newtask.description = 'A follow-up has been requested for a resolved incident. Please liaise with the Contact of the Parent task.' newtask.insert(); }