Allow users to provide feedback directly from an email notification

Aparna Gurav
Tera Contributor

Hello Team, 


I have a requirement where users should be able to provide feedback directly from an email notification. The email should contain links (such as emojis) that, when clicked, immediately submit a response to the associated feedback survey.

I found a solution on the ServiceNow Community and tried it. I used the same setup and just changed the survey question sys_id in the inbound action. The email gets sent, and clicking the emoji triggers the inbound action, but the user’s response doesn’t show up in the survey results.

I’m not sure what’s wrong. Has anyone done something like this or knows what might be missing?



https://www.servicenow.com/community/developer-articles/embedding-emoticon-s-smiley-survey-in-email-...

I created below Email script

(function runMailScript(/* GlideRecord */ current, /* TemplatePrinter */ template,
          /* Optional EmailOutbound */ email, /* Optional GlideRecord */ email_action,
          /* Optional GlideRecord */ event) {

// current is asmt_assessment_instance
var incident = new GlideRecord('incident');
incident.get(current.trigger_id); // get incident record from trigger_id

var mail = gs.getProperty("instance_name") + "@service-now.com";
var subject = "Survey: " + current.number + " Incident: " + incident.number;

template.print('<br/>We would love to hear your thoughts!<br/>Please rate your experience<br/><br/>');

var bodyTemplate = 
    'In order to receive your satisfaction, please do not modify or delete the following items: satisfaction, survey, incident.%0A%0A' +
    'Satisfaction:{SATISFACTION}%0A' +
    'Survey:' + current.number + '%0A' +
    'Incident:' + incident.number + '%0A%0A' +
    'Please write a comment about your dissatisfaction. We\'ll really appreciate it in order to improve our quality of service.%0AComment:\n ';

var satisfactionLevels = [
    { label: "Very happy", img: "very_happy.png" },
    { label: "Happy", img: "happy.png" },
    { label: "Neutral", img: "neutral.png" },
    { label: "Unhappy", img: "sad.png" },
    { label: "Very Unhappy", img: "very_sad.png" }
];

for (var i = 0; i < satisfactionLevels.length; i++) {
    var level = satisfactionLevels[i];
    var body = bodyTemplate.replace("{SATISFACTION}", level.label);
    template.print('<a HREF="mailto:' + mail + '?subject=' + encodeURIComponent(subject) + '&body=' + body + '"><img src="' + level.img + '" width="50" height="50"/></a>');
}

})(current, template, email, email_action, event);


Inbound action
condition: email.subject.toLowerCase().includes("feedback makes us better")
Target table : Assessment instance
Action type : record action

(function runAction(/*GlideRecord*/ current, /*GlideRecord*/ event, /*EmailWrapper*/ email, /*ScopedEmailLogger*/ logger, /*EmailClassifier*/ classifier) {
 
 var body = email.body_text;
 var sender = email.origemail;
 var subject= email.subject;
 var satisfaction = email.body.satisfaction;
 var survey = email.body.survey;
 var incident = email.body.incident;
 var comment =email.body.comment;
 
 
 if (this.checkUser(sender)){
  this.saveResponse(survey,incident,this.getsatisfaction(satisfaction),comment);
  
 }else{
  
 }
  
})(current, event, email, logger, classifier);


function getsatisfaction(satisfaction){
 var response ='';
 if(satisfaction.indexOf("Very happy") != -1){
  response ='1';
 }else if(satisfaction.indexOf("Happy") != -1){
  response ='2';
 }else if(satisfaction.indexOf("Neutral") != -1){
  response ='3';
 }else if(satisfaction.indexOf("Unhappy") != -1){
  response ='4';
 }else if(satisfaction.indexOf("Very Unhappy") != -1){
  response ='5';
 }
 return response;
}

function checkUser(email){
 var response =true;
 var gr = new GlideRecord('sys_user');
 gr.addQuery('email', email);
 gr.query();
 if (gr.hasNext()) {
  gr.next();
  gs.log("user " +email+" "+ gr.name + " existe !","CMA" );
  response = true;
 }else{
  response = false;
  gs.log("user "+email+" dont existe !","CMA" );
 }
 return response;
}

function saveResponse(survey,incident,response,comment){
 if(response!='0'){
  
  gs.log("Saving : " +survey+incident+response+comment,"CMA");
  
  var queryString="metric_type.evaluation_method=survey^number="+survey;
  var ins = new GlideRecord('asmt_assessment_instance');
  ins.addEncodedQuery(queryString);
  ins.query();
  ins.next();
  
  var question = new GlideRecord('asmt_assessment_instance_question');
  question.addQuery('instance', ins.sys_id);
  question.query();
  
  while(question.next()){
   
   if(question.metric=="ae467a5e1bc01610cc3b997e0d4bcb92"){
    gs.log("satisfaction","CMA");
    question.value=response;
   }
   
   else{
    gs.log("comment","CMA");
    question.string_value=comment;
       }
   question.update();
  }
  ins.state="complete";
  ins.update();
 }
 this.updatePreviousSurvey(survey,incident,comment);
}

function updatePreviousSurvey(survey,incident,comment,response){
 if(response!='0'){
  
 gs.log("Saving : " +survey+incident+comment,"CMA");
  
  var queryString="asmt_metric_result.instance.task_idISNOTEMPTY^asmt_metric_result.instance.task_id.number="+incident;
  var prev = new GlideRecord('asmt_metric_result');
  prev.addEncodedQuery(queryString);
  prev.query();
  prev.next();
  gs.log(queryString.toString(),"Query");
  
  while(prev.next()){
   
   if(prev.metric=="ba467a5e1bc01610cc3b997e0d4bcbc5" && prev.instance.task_id.number==incident)//comment sys_id
   {
    prev.string_value=comment;
    prev.u_survey_worknotes=comment;
    gs.log("  metric    "+prev.metric+"  Instance    "+prev.instance.number+"    Sys_id  "+prev.sys_id + "   Related Incident"+prev.instance.task_id.number,"Update CMA2 LOG OK");
   }
   
   else{
    gs.log("comment"+comment+"  "+"Incident"+"  "+incident+"   "+"Survey"+"   "+survey,"CMA");
    gs.log("  metric    "+prev.metric+"  Instance    "+prev.instance.number+"    Sys_id  "+prev.sys_id + "   Related Incident"+prev.instance.task_id.number,"Update CMA2 LOG NOK");
   } 
  prev.update();  
  }  
}
}

AparnaGurav_0-1747049054288.png

AparnaGurav_1-1747049405552.png

Output:

AparnaGurav_2-1747049665523.pngAparnaGurav_3-1747049768964.png

 

AparnaGurav_5-1747049854540.png

 



1 REPLY 1

Masha H
ServiceNow Employee
ServiceNow Employee

Hi Aparna, 

It is difficult to know exactly where your code is failing. I would suggest that you review your Inbound email action, since everything else seems to be working as expected. You should be able to see the email coming into the system and see if it is getting processed or erroring out in he email logs. You can also add logging to each of the functions to see what is being passed in and maybe see where the script stops processing.
One thing that jumps out at me is that you are referencing 'satisfaction' as an attribute of the body (var satisfaction = email.body.satisfaction;) of the incoming email, but it seems that the body of the email is a string.

var bodyTemplate = 
    'In order to receive your satisfaction, please do not modify or delete the following items: satisfaction, survey, incident.%0A%0A' +
    'Satisfaction:{SATISFACTION}%0A' +
    'Survey:' + current.number + '%0A' +
    'Incident:' + incident.number + '%0A%0A' +
    'Please write a comment about your dissatisfaction. We\'ll really appreciate it in order to improve our quality of service.%0AComment:\n ';


There is a lot of complexity to this Inbound action. I would simplify and see if you can get a static (always 'happy') response recorded from the incoming email, and then expand to reading in the passed-in values.