Add a watchlist widget to your Ticket form in Service Portal. Allow self service users to add email addresses to the watchlist.
This just allows watchlist users to get emails on the ticket. To allow watchlist users view the ticket in the Service Portal, you'll have to adjust your ACLs and SP configuration.
NOTE: This was updated on 10/27/2020 for the Paris release
Widget V1
This one doesn’t allow the user to view users in the system
Name: Ticket Watchlist User No View
ID: ticket_watchlist_user_no_view
HTML
<div class="panel panel-primary">
<div class="panel-heading">
<h4 class="panel-title"><fa ng-if="::options.glyph.length" name="" class="m-r-sm" />Add to Watchlist</h4>
</div>
<div class="panel-body">
<form ng-submit="server.update()">
${Enter an email address to follow}
<div class="textbox_space">
<input ng-model="data.watch_list" id="watch_list" class="form-control" type="email" maxlength="50" />
</div>
<div style="margin-top:15px; float: right;">
<button type="submit" class="btn btn-primary post-btn ng-scope">Add</button>
</div>
<div style="margin-right:250px;" ng-if="data.response" class="alert alert-success">{{::data.response}}</div>
</form>
</div>
</div>
CSS
.textbox_space {
margin-top: 10px;
margin-bottom: 10px;
}
Client Script
api.controller=function() {
/* widget controller */
var c = this;
};
Server Script
(function() {
data.submitMsg = gs.getMessage("Add");
if (input) {
data.sys_id = (input && input.sys_id) || options.sys_id || $sp.getParameter("sys_id");
data.table = (input && input.table) || options.table || $sp.getParameter("table");
data.watch_list = "";
var grTask = new GlideRecord(data.table);
grTask.query("sys_id", data.sys_id);
grTask.query();
//console.log('grTask Query: ' + grTask.getEncodedQuery() + ' = ' + grTask.getRowCount());
if (grTask.next()) {
var wList = grTask.watch_list;
var wEmail = input.watch_list;
var grUser = new GlideRecord('sys_user');
grUser.addQuery('email', wEmail);
grUser.query();
if (grUser.next()) {
// It's a user
if(wList != "") {
wList = (wList + "," + grUser.sys_id);
} else {
wList = grUser.sys_id;
}
} else {
//It's not a user either...so just add the address to the list...except instance email address
wList = (wList + "," + wEmail);
}
grTask.setValue("watch_list",wList);
data.response = 'Thank you, email was added.';
grTask.update();
}
}
})();
Widget V2
This is a different version allows a user to view users and select them. You might not want to use this version due to security reasons, but some companies only have employees use the service portal. You may need to adjust acls for viewing users
Name: Ticket Watchlist View Users
ID: ticket_watchlist_view_users
HTML
<div class="panel panel-primary" ng-if="data.canRead">
<div class="panel-heading">
<h4 class="panel-title pull-left">
${Watch list}
</h4>
<div class="clearfix"></div>
</div>
<div class="panel-body">
<form ng-submit="save()">
<div class="text-center text-italic text-muted">
<div>
<sn-record-picker field="watch_list" sn-disabled="!data.canWrite" table="'sys_user'" display-field="'email'" display-fields="'name'" search-fields="'email'" value-field="'sys_id'" default-query="'active=true^web_service_access_only=false^user_nameISNOTEMPTY^emailISNOTEMPTY'" page-size="10" multiple="true"></sn-record-picker> </div>
<div style="margin-top:15px; float: right;">
<button type="submit" class="btn btn-primary post-btn ng-scope">Save</button>
</div>
</div>
</form>
</div>
</div>
CSS
Client Script
api.controller=function($scope, spUtil, $http) {
var c = this;
$scope.watch_list = {
displayValue: c.data.displayValue,
value: c.data.value,
name: 'watch_list'
};
$scope.save = function(){
c.data.watchList = $scope.watch_list.value;
c.server.update().then(function() {
spUtil.recordWatch($scope, c.data.table, "sys_id=" + c.data.sys_id, function(name, data) {
if(name.name == 'record.updated' && data.operation == 'update'){
$scope.watch_list.value = data.record.watch_list.value;
$scope.watch_list.displayValue = data.record.watch_list.display_value;
$scope.$apply();
}
});
});
};
$scope.$on("field.change", function(evt, parms) {
if (parms.field.name == 'watch_list') {}
});
};
Server Script
(function() {
var gr;
if(input){
gr = new GlideRecord(input.table);
if(gr.get(input.sys_id)){
if(gr.watch_list.canWrite()){
gr.watch_list = input.watchList;
gr.update();
gs.addInfoMessage('Updated');
}
else{
gs.addErrorMessage("Update failed, you don't have the required access");
}
}
}
else{
var sys_id = (input && input.sys_id) || options.sys_id || $sp.getParameter("sys_id");
var table = (input && input.table) || options.table || $sp.getParameter("table");
gr = new GlideRecord(table);
if(gr.get(sys_id)){
data.table = table;
data.sys_id = sys_id;
data.canRead = gr.watch_list.canRead();
data.canWrite = gr.watch_list.canWrite();
if(data.canRead){
var dV = gr.getDisplayValue('watch_list');
var sV = gr.getValue('watch_list');
//data.displayValue = dV == '' ? [] : dV;
//data.value = sV == null ? [] : sV;
data.displayValue = dV;
data.value = sV;
}
}
}
})();
Fields: Bootstrap color, Glyph