Manage attachments on public record producer in Service Portal
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-06-2020 04:26 PM
Hi,
I have created a record producer to capture some information from the user who does not have any role on the instance. It is available for the public. I am rendering it through Service Portal. Have also created some widgets on the portal page. Everything is working fine except attachments. User with some role can easily add/remove attachments on the page but when user without any role (public user) is trying to attach, nothing is happening. In the console i see an error
Has anyone encountered this error ? If yes, can you please advise some workaround.
I am using attachment widget to manage attachments:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-07-2020 07:44 AM
Hi Gaurav,
Can you check following system properties once:
glide.security.file.mime_type.validation system property is set to true by default in instance. When you set it to false then it will allow those type of attachments into instance.
Description about property from ServiceNow docs:
glide.security.file.mime_type.validation:Must be set to activate MIME type checking for uploads (all version Eureka and up). Enables (Yes) or disables (No) mime type validation for file attachments. File extensions configured via glide.attachment.extensions are checked for MIME type during upload.
for additional info please refer below link:
https://hi.service-now.com/kb_view.do?sysparm_article=KB0718011
Please mark as correct answer if it is helpful
Thanks,
Usmaan.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-08-2020 06:03 PM
Hi Usmaan,
Unfortunately, it didn't help. My issue is that platform is not allowing a public user to upload the attachment through their OOB attachment widget. As i mentioned in the screenshot, angular.do is a kind of firewall which is restricting the attachments from a public user. Regards - Gaurav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-10-2021 11:37 PM - edited ‎07-20-2025 12:22 AM
Edit 20. July 2025:
The new way of solving this is described in:
https://github.com/kr4uzi/ServiceNow-Public-Catalog-Item-Attachments/wiki
Advantages of this app:
- I keep it maintained
- respects your sys_attachment ACLs
- only depends on the attachment endpoint
Edit 19. July 2021:
table: scope.field.recordTableName, -> scope.getRecordTableName()
sys_id: scope.field.recordSysId, -> scope.getRecordId()
Hello, this thread on the top when searching google for "ServiceNow RecordProducer Public Attachment" and therefore i present you my solution which is using:
- The ServiceNow OOTB Styling (and therefore Branding)
- Works by Wrapping the OOTB Handling (so should be upgrade safe - at least to some degree)
To get public (and mandatory) attachments working with a public record producer, do the following steps:
- Create a public Variable with the following attributes:
Type: "Custom with Label"
Question: <your label>
Name: <variable name> - Go to the "Permission" Section and set Read/Write/Create/Delete to "public"
- Go to "Type Specification" Section and set the following attributes:
Widget: "Public RP Attachment" (see below) - When the user submits the Record Producer Form, all attachments will get copied to the resulting record
Public RP Attachment
- Create a new ServicePortal Widget (sp_widget.list)
- Name it "Public RP Attachment"
- HTML:
<!-- Steps if this widget stops functioning: 1.) Check HTML Template: a) Open a record producer that has an attachment item option: /item_option_new_list.do?sysparm_query=type%3D33 b) Copy the sys_id of the record producer c) /sp?id=sc_cat_item&sys_id=<RP sys_id> c) Inspect the Upload Button onclick handler (here: 'openAttachmentSelector') d) Code Search for the onclick function and make sure that all elements are correctly bound --> <sp-variable-attachment ng-init="injectSWTOverride()" field="field" attachment-guid="formModel._attachmentGUID || formModel.sys_id" g-form="getGlideForm()" />​
- Server Script:
(function(input, data) { // original scripts for the OOTB Attachment Variable Widget/Directive // /scripts/app.$sp/directive.spVariableAttachment.js // angular.do?sysparm_type=get_partial&name=sp_variable_attachment.xml if (input && input.action == "upload") { if (input.table && input.sys_id && input.file_name && input.data) { var contentType = input.data.substring(input.data.indexOf(':') + 1, input.data.indexOf(';')); var content = input.data.substring(input.data.indexOf(',') + 1); // our target record does not exist yet, but this doesnt matter as long as gr.sys_id returns the expected sys_id var gr = new GlideRecord(input.table); gr.get(input.sys_id); data.sys_id = new GlideSysAttachment().writeBase64(gr, input.file_name, contentType, content); data.state = "pending"; data.file_name = input.file_name; } } })(input, data);​
- Client Controller:
api.controller=function($scope, $http, $timeout, spAriaUtil, i18n, snAttachmentHandler) { /* widget controller */ var c = this; var parentScope = $scope.$parent.$parent; for (var attr in parentScope) { if (attr.indexOf('$') == 0) { continue; } $scope[attr] = parentScope[attr]; } $scope.field.attributes = { allowed_extensions: "csv;txt" }; var override = false; $scope.injectSWTOverride = function () { c.childScope.$watch('onAttachmentSelect', function(newValue, oldValue, scope) { if (override) { return; } override = true; scope.$$childHead.onAttachmentSelect = uploadAttachment.bind(null, scope.$$childHead); }); }; function uploadAttachment(scope, $files) { if ($files.length == 0) return; var file = { name: $files[0].name, size: $files[0].size }; if (scope.validateAttachment(file)) { scope.uploading = true; scope.field.isInvalid = true; var reader = new FileReader(); reader.readAsDataURL($files[0]); reader.onload = function() { c.server.get({ action: "upload", file_name: $files[0].name, table: scope.getRecordTableName(), sys_id: scope.getRecordId(), data: reader.result }).then(function (response) { spAriaUtil.sendLiveMessage(i18n.getMessage('Attachment successfully uploaded')); scope.uploading = false; scope.field.state = response.data.state; scope.gForm().setValue(scope.field.name, response.data.sys_id, response.data.file_name); }, function(error) { scope.uploading = false; scope.field.isInvalid = false; }); $files[0] = ''; }; reader.onerror = function (err) { $files[0] = ''; scope.uploading = false; scope.field.isInvalid = false; }; // // original upload function that fails for public role: // // snAttachmentHandler.create('ZZ_YY' + scope.getRecordTableName(), scope.getRecordId()).uploadAttachment($files[0]).then(function(response) { // spAriaUtil.sendLiveMessage(i18n.getMessage('Attachment successfully uploaded')); // scope.uploading = false; // scope.field.state = response.state; // scope.gForm().setValue(scope.field.name, response.sys_id, response.file_name); // }, function(error) { // scope.uploading = false; // scope.field.isInvalid = false; // }); } } };​
- Link:
function link(scope, element, attrs, controller) { controller.childScope = element.children().first().scope(); }​
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-17-2022 03:25 AM
Hi Markus,
I was trying to work through this on CSM portal.
Created the widget with the configuration provided but it is not working on record producer. When I upload the file it does nothing.
Any suggestions?