Zendesk Help Center, also known as Zendesk Guide, is online help documentation and request management software offered as part of the Zendesk Suite. It acts as a modern and interactive self-service portal for end-users in an organization where they can log maintenance requests for items in their custody.
AssetSonar now integrates with Zendesk Help Center to streamline the request management workflows for your IT teams. It bridges the gap between the ITAM database, Zendesk ticketing system, and Zendesk Help Center to bring all your IT information in one place.
Without the need for switching between different applications and rummaging for relevant information, Agents can easily access IT Assets that are checked out to Requesters (end users) and link them to tickets. Our new integration greatly reduces ticket processing time, accelerates service delivery, and ensures a seamless Agent and end-user experience.
This article outlines how you can successfully integrate your AssetSonar account with Zendesk Help Center for streamlined request management.
Note: If you have Zendesk Sunshine enabled in your Zendesk account, please use this PDF to integrate AssetSonar with the Zendesk Help Center.
For customers using JWT API, let’s get started!
1. Enable Zendesk Help Center integration
The first step is to enable the Zendesk Help Center integration in your AssetSonar account. For this purpose, go to Settings → Add Ons → Integrate Zendesk, select the ‘Integrate with Zendesk Help Center’ option.
Click ‘Proceed’ and hit ‘Update’.
You will get the following message upon successful integration.
Note: Please note that only the customers with access to Zendesk JWT API will be able to use the integration.
2. Configuration in Zendesk Support
Now, you need to configure the Asset field and preferred ticket forms in your Zendesk Support account so they can appear to end-users on the Zendesk Help Center portal when they submit requests.
2.1. Create Ticket Field
In your Zendesk Support account, click on the ‘Admin’ icon as shown.
From the sidebar, go to Manage → Ticket Fields.
Click on the ‘Add Field’ button on the top right.
Now, add a text-based Asset field as illustrated, and hit ‘Save’.
Note: Remember to select the ‘Editable for end users’ option under the Permissions section.
Copy the Field ID of the Assets field for further steps.
The newly created Assets field will enable you to pull IT Asset information from AssetSonar to Zendesk Help Center forms.
2.2. Create Ticket Forms
Now, create custom Ticket Forms that end-users can use to place their requests on the Zendesk Help Center portal.
Ticket Forms can be used to place requests for use cases including but not limited to:
- Troubleshooting and configuring issues in IT Assets
- Servicing hardware components
- Installing software on selected IT Assets
To create a new Ticket Form, go to Manage → Ticket Forms → Add Form.
Name the form and drag and drop relevant fields to it. Remember to add the Assets field to your Ticket Forms and make the forms editable by end-users!
Hit ‘Save’ once done.
Note: Only the Ticket Forms that have the Assets field embedded in them can be used for the integration to work.
2.3. Zendesk Activity logs
You can view records of every action users perform on a ticket, such as linking items, creating a purchase order, or checking out items. After any action or activity is performed, the activity log, as internal notes, is added to the ticket. It provides the user name, email, and activity details performed by the user.
Here’s how you can enable activity logs in Zendesk:
1. When you log in to your Zendesk account, go to Settings and then click ‘Go to Admin Center’
2. You will be redirected to the Admin Center page. Click on ‘Apps and Integrations’ from the sidebar and then select ‘Zendesk Support apps’ from the dropdown. Click on AssetSonar to view settings.
3. On the AssetSonar settings page, scroll down to check ‘Activity Logs’ settings and click Update.
4. Now let’s go over an example of an activity log internal note added to a ticket. John has checked in a laptop from Tony in the ‘Broke my Macbook’ ticket shown below. As soon as the laptop is checked in, an activity log internal note is added.
5. Here’s a list of actions for which activity log messages appear in your Zendesk account:
Action | Activity log message |
Link an item | John (john@gmail.com) linked Asset#401-MacBook Pro from this ticket. |
Unlink an item | John (john@gmail.com) unlinked Asset#402-MacBook Pro from this ticket. |
Create a purchase order | John (john@gmail.com) created PO#58 for this ticket. |
Link a purchase order | Emily (emily@gmail.com) linked PO#45 to this ticket. |
Unlink a purchase order | Paul (paul@gmail.com) unlinked PO#48 to this ticket. |
Check out an item | Paul (paul@gmail.com) checked out Asset#51-Headphones to Emily (emily@gmail.com). |
Extend check out | Paul (paul@gmail.com) extended check out for Asset#51-Headphones to Emily (emily@gmail.com). |
Start service of an item | Emily (emily@gmail.com) started service of Asset#91 – Logitech Keyboard. |
Schedule service of an item | John (john@gmail.com) scheduled service of Asset#43 – SteelSeries mouse. |
Complete service of an item | John (john@gmail.com) completed service of Asset#03 – HP Printer. |
Link work order | Emily(emily@gmail.com) linked WO#2 to this ticket. |
Unlink work order | Joe(joe@gmail.com) unlinked WO#3 to this ticket. |
3. Editing code in Zendesk Help Center
The next step is to edit the code of the theme within the Zendesk Help Center.
Note: We recommend creating a sandbox instance in your Zendesk account to test the code changes before you implement them.
Learn more about creating a sandbox here.
3.1. Clone the live theme
Traverse to the Zendesk Guide platform from the Products icon, as shown.
This leads you to the Zendesk Help Center knowledge base. Click on the ‘Guide Admin’ button at the top.
Now, click the ‘Customize’ icon in the sidebar.
This directs you to the Themes page. Clone the currently live theme within your Zendesk Help Center account by clicking on the ellipsis icon, and selecting ‘Copy’.
You can now take action on the clone of the live theme.
3.2. Edit the cloned theme
Now that you’ve copied the live theme, you can make changes to it and preview the copy for testing purposes.
To edit the copied theme, click on ‘Customize’ as shown below.
Follow the pathway: Edit Code → Access Code.
This shall lead you to the Templates folder.
The Zendesk Help Center integration requires you to add a code in three primary files from the given templates:
- document_head.hbs
- new_request_page.hbs
- request_page.hbs
From the left sidebar, open the document_head.hbs
Paste the following code at the end of document_head.hbs:
<script>
var ezoFieldId = 'ASSET_FIELD_ID'; // enter id of field created for linked assets
var ezoSubdomain = 'SUBDOMAIN.assetsonar.com'; // enter SUBDOMAIN
function getScript(url, success) {
var script = document.createElement('script');
script.src = url;
var head = document.getElementsByTagName('head')[0],
done = false;
// Attach handlers for all browsers
script.onload = script.onreadystatechange = function() {
if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) {
done = true;
// callback function provided as param
success();
script.onload = script.onreadystatechange = null;
head.removeChild(script);
};
};
head.appendChild(script);
};
</script>
This is how your file will look after you paste the code.
In the code you just pasted, enter the following values:
In place of ASSET_FIELD_ID, add the Assets Field ID value from Section 2.1.
In place of SUBDOMAIN, enter your AssetSonar subdomain with the host.
Now, open the new_request_page.hbs file.
Paste the following code at the end of new_request_page.hbs
<!-- Insert this at the end of new_request_page.hbs file -->
<script>
function initAssetsField() {
var ezoField = customFieldElement(ezoFieldId);
if (isRequestFormSelected()) {
getTokenAndFetchAssignedAssets();
}
function renderSelect2PaginationForUsers(element, url, options) {
const parentElementSelector = 'body';
element.select2({
dropdownParent: element.parents(parentElementSelector),
ajax: {
url: url,
dataType : 'json',
delay : 250,
headers: options.headers,
data: function (params) {
var query = {
search: params.term,
page: params.page || 1,
include_blank: $(element).data('include-blank')
}
return query;
},
processResults: function(data, params) {
var results = $.map(data.assets, function(asset) {
var objHash = { id: asset.sequence_num, text: `Asset # ${asset.sequence_num} - ${asset.name}` };
return objHash;
});
return {
results : results,
pagination : {
more: data.page < data.total_pages
}
};
}
},
});
}
function populateAssignedAssets(url, options) {
fetch(url, options).then(response => response.json()).then(data => {
var assetsData = { data: [] };
if (data.assets) {
$.each(data.assets, function (index, asset) {
assetsData.data[index] = { id: asset.sequence_num, text: `Asset # ${asset.sequence_num} - ${asset.name}` }
});
}
ezoField.hide();
ezoField.after("<select multiple='multiple' id='ezo-asset-select' style='width: 100%;'></select>");
renderSelect2PaginationForUsers($('#ezo-asset-select'), url, options);
$('#ezo-asset-select').next().css('font-size', '15px');
$('form.request-form').on('submit', function () {
var selectedIds = $('#ezo-asset-select').val();
if (selectedIds.length > 0) {
let data = assetsData.data.filter(asset => selectedIds.includes(asset.id.toString()));
data = data.map((asset) => {
let assetObj = { [asset.id]: asset.text };
return assetObj;
}
);
ezoField.val(JSON.stringify({assets: data}));
}
});
});
}
function getTokenAndFetchAssignedAssets() {
var options = { method: 'GET', headers: { } };
return withToken(token => {
if (token) {
options.headers['Authorization'] = 'Bearer ' + token;
var url = 'https://' + ezoSubdomain + '/webhooks/zendesk/get_assigned_assets.json';
return populateAssignedAssets(url, options);
}
})
}
function withToken(callback) {
return $.getJSON('/hc/api/v2/integration/token').then(data => {
var token = data.token;
return callback(token);
})
}
function isRequestFormSelected() {
const oldTemplateSelector = $('.nesty-input');
const newTemplateSelector = $('#downshift-0-input');
if (oldTemplateSelector.length) {
return oldTemplateSelector.text() !== '-';
} else if (newTemplateSelector.length) {
return newTemplateSelector.val().trim().length > 0;
}
return false;
}
function customFieldElement(customFieldId) {
const idSelector = `#request_custom_fields_${customFieldId}`;
const nameSelector = `[name='request[custom_fields][${customFieldId}]']`;
return $(idSelector).length
? $(idSelector)
: $(nameSelector);
}
};
function loadJqueryAndInitIntegration() {
function loadSelect2AndInitAssetField() {
getScript('https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/js/select2.min.js', function () {
initAssetsField();
});
}
if (typeof jQuery == 'undefined') {
getScript('https://code.jquery.com/jquery-3.6.0.min.js', function () {
loadSelect2AndInitAssetField();
});
} else { // jQuery was already loaded
loadSelect2AndInitAssetField();
};
}
document.addEventListener('DOMContentLoaded', loadJqueryAndInitIntegration);
</script>
<link href="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/css/select2.min.css" rel="stylesheet" />
Click’ Save’ when you’re done.
Now, open the last file i.e. request_page.hbs file for editing.
Paste the code below at the end of the request_page.hbs file and hit ‘Save’.
<!-- Insert this at the end of request_page.hbs file -->
<input type="hidden" id="request-id-hidden-field" value="{{request.id}}">
<script>
function ezoIntegrationInit() {
var requestId = $('#request-id-hidden-field').val();
var requestUrl = '/api/v2/requests/' + requestId;
hideAssetsCustomField();
$.getJSON(requestUrl).done(function (data) {
var ezoFieldData = data.request.custom_fields.find(function (e) { return e.id == ezoFieldId });
if (!ezoFieldData || !ezoFieldData.value) { return true; }
var options = { method: 'GET', headers: { } };
return withToken(token => {
if (token) {
options.headers['Authorization'] = 'Bearer ' + token;
let parsedEzoFieldValue = JSON.parse(ezoFieldData.value);
assetSequenceNums = parsedEzoFieldValue.assets.map(asset => Object.keys(asset)[0]);
let assetNames = parsedEzoFieldValue.assets.map(asset => Object.values(asset)[0]);
if (!assetSequenceNums || assetSequenceNums.length == 0) { return true; }
if (parsedEzoFieldValue.linked != 'true') {
linkAssets(assetSequenceNums);
}
if (assetNames) {
addEZOContainer();
assetNames.map(name => {
showLinkedAsset(name);
});
}
}
})
});
function addEZOContainer() {
$('dl.request-details').last().after('<dl class="request-details" id="ezo-assets-container"><dt>AssetSonar Assets</dt><dd><ul></ul></dd></dl>');
}
function linkAssets(assetSequenceNums) {
$.ajax({
url: 'https://' + ezoSubdomain + '/webhooks/zendesk/sync_tickets_to_assets_relation.json',
type: 'POST',
data: { "ticket": { "ticket_id": requestId, "assets_field_id": ezoFieldId } }
});
}
function withToken(callback) {
return $.getJSON('/hc/api/v2/integration/token').then(data => {
var token = data.token;
return callback(token);
})
}
function showLinkedAsset(assetName) {
var assetUrl = getAssetUrl(assetName);
var ezoContainerBody = $('#ezo-assets-container dd ul');
if (assetUrl) {
ezoContainerBody.append("<li><a target='_blank' href='" + assetUrl + "'>" + assetName + "</a></li>");
} else {
ezoContainerBody.append("<li>" + assetName + "</li>");
}
}
function hideAssetsCustomField() {
const valueToFind = '{'+'"assets":' + '[{'; // value to find dd element
const ddElement = $("dd:contains('" + valueToFind + "')"); // find dd element by
if (ddElement['0']) {
ddElement['0'].style.display = 'none';
ddElement['0'].previousElementSibling.style.display = 'none';
}
}
function getAssetUrl(assetName) {
if (!assetName) { return null; }
assetName = assetName.trim();
var matchData = assetName.match(/^(Asset|Asset Stock) # (\d+) /);
if (matchData) {
var type = matchData[1];
var id = matchData[2];
return 'https://' + ezoSubdomain + getAssetPath(type, id);
}
return null;
}
function getAssetPath(type, id) {
if (type === 'Asset') {
return '/assets/' + id;
} else {
return '/stock_assets/' + id;
}
}
};
function loadJqueryAndInitIntegration() {
if (typeof jQuery == 'undefined') {
getScript('https://code.jquery.com/jquery-3.6.0.min.js', function () {
ezoIntegrationInit();
});
} else { // jQuery was already loaded
ezoIntegrationInit();
};
}
document.addEventListener('DOMContentLoaded', loadJqueryAndInitIntegration);
</script>
You are now ready to preview the changes.
3.3. Preview the edited theme
Click the ‘Preview’ button in the code editor.
This opens the preview in a new tab. Select ‘End user’ from the Preview role dropdown.
Now, select the Request Page and New Request Page from the Templates dropdown to test the changes from an end user’s perspective.
As you can see, the Assets field has been populated on both the New Request and the Request pages.
Note: Only the assets that are checked out to the requesters will be visible to them when they place requests. Assets will not show up if they have been checked back in or the Zendesk Requester does not exist as a member in AssetSonar.
Click on the ‘Close Preview’ button once you’re done testing the preview for syntax errors.
4. Publish the Zendesk Help Center theme
You can now publish the edited theme for use by end-users.
Go to Guide Admin → Customize (eye icon) → Preferred theme → Options (ellipsis icon) → Set as live theme to publish the finalized theme.
Once the theme has been published, it appears at the top of the page. This ensures that the integration is successful and changes have been applied to your Zendesk Help Center account.