- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-31-2018 10:38 AM
Ok, I have a problem and could use a little help. I have been pulling my hair out!! Any direction would be awesome!
I have created:
- Portal (Public)
- Portal Page (Public)
- Catalog and category (role public)
- Record producer (Public)
- Cloned widget (Public) (From SC Catalog Item widget)
- Added the necessary pages to the public list
- Variables write, create and read roles are public
Current state
- Portal, portal page and widget is working as public https://ouitservicesdev.service-now.com/scc_sr?id=sr&sys_id=036cd49c4f96d3407b92d49f0310c7d2
Problem
- The description and form name are showing but Variables cannot be seen
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-31-2018 10:59 AM
Even if you get the form to render, the problem you're going to run in to is that you can not submit a record producer in Service Portal with an unauthenticated user.
The form posts to a processor called /angular.do which lives on the filesystem, and does not support unauthenticated users.
What you can do is build a custom widget which either processes the data using the server script or by posting to the REST API. I'd also recommend that you implement a Captcha to ensure submission by real users.
We've built many such custom forms for our customers, but it's probably not the answer you were hoping for.
Thanks,
Nathan Firth
Founder and ServiceNow Architect
NewRocket, Inc.
nathan.firth@newrocket.com
http://serviceportal.io
http://newrocket.com
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-16-2021 12:20 PM
From what I can tell, this is all about security and API's are the only way to create tickets outside the platform since authentication of some kind is required. You can use an external system if you feel it's more secure. Otherwise, there shouldn't be any other way around it.
Assuming these are users in the system and they just can't login for whatever reason, then to get around the "Guest" entry is to have them provide their 'work' email address (which should be unique on their user profile or use some other unique value like an employee ID). Then have a 'before' business rule on the table to check that email address on the user table and if it exist, create the ticket and plug the user into the "Requested for" field and generate the ticket, if it doesn't then ignore the insert action to prevent the ticket from being created at all and run a registered event that you can also create to email the user that it couldn't be created due to invalid email address or the like. Problem with this method is it doesn't prevent Jane from submitting a request for John using his email address, but a good approval process can be a good way to combat this.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-13-2021 05:20 AM
Could you please provide me some inputs here?
what are all things i need to look for?
we have one record producer and we want guest/visitors to access it without logging in.
Please provide some inputs. Thanks in advance.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-07-2018 12:34 PM
Hey Jason,
I just got tasked to do the same thing. Variables are not showing up when my page loads, what needs to be made public and where do i set that value?
Thanks,
Mike

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-29-2019 03:05 PM
Hey Jason,
It looks like you figured it out. What was the answer?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-30-2019 07:30 AM
nathanfirth answered correctly. You have to build a custom widget that uses REST API to create a record. Took me some time to learn how to do it and still need to learn more, but I was able to build a simple custom widget to do this. My code isn't clean, per se, but perhaps others here can help clean it up. Even added Google Captcha to help reduce bot attacks **not included in this code**. I can provide some code here to help others get started making their own widgets. I advise using this with caution as it does provide a way for attackers to generate tickets when they want to so you might want to add more security using the captcha, maybe a whitelist/blacklist for IP addresses, etc. This widget here simply gives the user a means to submit an incident ticket when they can't login the system. The ticket generated goes to the service desk (user your own values in server script) with their information in the problem description:
HTML:
<div class="panel panel-default">
<div class="panel-body m-b-n">
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; text-align: right; font: 12.0px Helvetica}
p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
table.t1 {border-collapse: collapse}
td.td1 {width: 133.0px; height: 37.0px; padding: 0.0px 5.0px 0.0px 5.0px}
td.td2 {width: 117.0px; height: 37.0px; padding: 0.0px 5.0px 0.0px 5.0px}
td.td3 {width: 27.0px; height: 37.0px; padding: 0.0px 5.0px 0.0px 5.0px}
td.td4 {width: 400.0px; height: 37.0px; padding: 0.0px 5.0px 0.0px 5.0px}
td.td5 {width: 133.0px; padding: 0.0px 5.0px 0.0px 5.0px}
td.td6 {width: 117.0px; padding: 0.0px 5.0px 0.0px 5.0px}
td.td7 {width: 27.0px; padding: 0.0px 5.0px 0.0px 5.0px}
td.td8 {width: 400.0px; padding: 0.0px 5.0px 0.0px 5.0px}
td.td9 {width: 200.0px; padding: 0.0px 5.0px 0.0px 5.0px}
td.td10 {width: 200.0px; padding: 0.0px 5.0px 0.0px 5.0px}
td.td11 {width: 200.0px; height: 80.0px; padding: 0.0px 5.0px 0.0px 5.0px}
td.td12 {width: 300.0px; height: 200.0px; padding: 0.0px 10.0px 0.0px 10.0px}
</style>
<p class="p1"><br/></p>
<p class="p1"><br/></p>
<p class="p1" style="font:bold 40px Helvetica;">   Login Issues Form</p>
<p class="p1"><br/></p>
<table cellspacing="0" cellpadding="0" class="t1">
<tbody>
<!-- Users First and Last name -->
<tr>
<td valign="middle" class="td1">
<p class="p2">First Name:</p>
</td>
<td valign="middle" class="td2">
<input type="text" ng-model="c.data.user_first_name" id="user_first_name" name="user_first_name" size="25"/>
</td>
<td valign="right" class="td1">
<p class="p2">Last Name:</p>
</td>
<td valign="middle" class="td2">
<input type="text" ng-model="c.data.user_last_name" id="user_last_name" name="user_last_name" size="25"/>
</td>
</tr>
<!-- Users employee number -->
<tr>
<td valign="middle" class="td1">
<p class="p2">Employee Number:</p>
</td>
<td valign="middle" class="td2">
<input type="text" ng-model="c.data.user_emp_num" id="user_emp_num" name="user_emp_num" size="25"/>
</td>
</tr>
<!-- Users location -->
<tr>
<td valign="middle" class="td1">
<p class="p2">Building Name:</p>
</td>
<td valign="middle" class="td2">
<input type="text" ng-model="c.data.user_loc" id="user_loc" name="user_loc" size="25"/>
</td>
</tr>
<!-- Users phone number -->
<tr>
<td valign="middle" class="td1">
<p class="p2">Phone # if we have questions:</p>
</td>
<td valign="middle" class="td2">
<input type="text" ng-model="c.data.user_phone" id="user_phone" name="user_phone" size="25"/>
</td>
</tr>
<!-- Users login credential -->
<tr>
<td valign="middle" class="td1">
<p class="p2">Enter the Login/Username that has been tried:</p>
</td>
<td valign="middle" class="td2">
<input type="text" ng-model="c.data.user_login" id="user_login" name="user_login" size="25"/>
</td>
</tr>
<!-- Users alternate email -->
<tr>
<td valign="middle" class="td11">
<p class="p2">Please enter an alternate email address if you're not able to get organization email messages:</p>
</td>
<td valign="middle" class="td11">
<input type="text" ng-model="c.data.user_email" id="user_email" name="user_email" size="25"/>
</td>
</tr>
<!-- Users problem description -->
<tr>
<td valign="middle" class="td12">
<p class="p2">Describe the problem you are having:</p>
</td>
<td valign="middle" class="td2">
<textarea name="user_prob" ng-model="c.data.user_prob" id="user_prob" cols="40" rows="5"></textarea>
</td>
</tr>
<!-- OK/Cancel Buttons -->
<tr id="buttons">
<td colspan="8" align="right">
<div class="modal-footer">
<button type="submit" class="btn btn-default" id="cancel_popup" name="cancel_popup" ng-click="c.submitCancel();">${Clear Form}</button>
<button type="submit" class="btn btn-primary" id="submit_popup" name="submit_popup" ng-click="c.submitData(user_first_name, user_last_name, user_emp_num, user_loc, user_phone, user_login, user_email, user_prob);">${Submit}</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
Client Script:
function(spUtil) {
/* widget controller */
var c = this;
c.submitData = function(){
c.data.action = "addData";
//Check Log to make sure data is stored in client
//console.log(c.data.user_first_name);
c.server.update().then(function(){
//reset callback function so it doesn't repeat
c.data.action = undefined;
c.data.user_first_name = "";
c.data.user_last_name = "";
c.data.user_emp_num = "";
c.data.user_loc = "";
c.data.user_phone = "";
c.data.user_login = "";
c.data.user_email = "";
c.data.user_prob = "";
spUtil.addInfoMessage("A ticket has been submitted to the Service Desk.")
})
}
c.submitCancel = function(){
c.server.update().then(function(){
//reset callback function so it doesn't repeat
c.data.action = undefined;
c.data.user_first_name = "";
c.data.user_last_name = "";
c.data.user_emp_num = "";
c.data.user_loc = "";
c.data.user_phone = "";
c.data.user_login = "";
c.data.user_email = "";
c.data.user_prob = "";
spUtil.addInfoMessage("Form has been cleared.")
})
}
}
Server Script:
(function() {
data.stuff = [];
if (input) {
if (input.action == "addData") {
data.stuff = input.stuff;
var first = input.user_first_name;
var last = input.user_last_name;
var empnum = input.user_emp_num;
var loc = input.user_loc;
var phone = input.phone;
var login = input.login;
var em = input.user_email;
var prob = input.user_prob;
//Generate Problem description using variables combined into one variable
var prob_desc = 'Login Issues Ticket Submitted. Here are the entries:' + "\r\n" + 'First Name: ' + first + "\r\n" + 'Last Name: ' + last + "\r\n" + 'Employee Number: ' + empnum + "\r\n" + 'Location: ' + loc + "\r\n" + 'Phone Number: ' + phone + "\r\n" + 'Username: ' + login + "\r\n" + 'Email: ' + em + "\r\n" + 'Problem Description: ' + prob;
//gs.log('Variable for problem description is: ' + prob_desc);
//Create the Request Body so we can plug in sys_id's and the problem description variable and let servicenow build the JSON code from values
//In short, this auto-fills some fields for your generated ticket by using sys_id values
var ag = "*********************";
var cid = "*********************";
var bs = "*********************";
var utl = "*********************";
var cat = "service";
var requestBody = {};
requestBody.assignment_group = ag;
requestBody.caller_id = cid;
requestBody.business_service = bs;
requestBody.u_ticket_location = utl;
requestBody.category = cat;
requestBody.short_description = prob_desc;
//Encode as JSON
var rBody = new global.JSON().encode(requestBody);
gs.log("This is the request body: " + rBody);
//REST API to Create incident
var request = new sn_ws.RESTMessageV2();
request.setEndpoint('https://*your-instance-name*/api/now/table/incident');
request.setHttpMethod('POST');
//Eg. UserName="UserName", Password="password" for this code sample.
var user = 'UserName';
var password = 'password';
request.setBasicAuth(user,password);
request.setRequestHeader("Accept","application/json");
request.setRequestHeader('Content-Type','application/json');
request.setRequestBody(rBody);
var response = request.execute();
gs.log(response.getBody());
}
}
})();