EZO Logo

Asset Intelligence, Reimagined

AssetSonar Blogs Zendesk Help Center Integration 91f3e2de0ed5

Streamline Request Management With AssetSonar’s Zendesk Help Center Integration

Streamline Request Management With AssetSonar’s Zendesk Help Center Integration
Share:

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.

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.

Zendesk Support account

From the sidebar, go to Manage → Ticket Fields.

go to Manage

Click on the ‘Add Field’ button on the top right.

Add Field’ button on the top right

Now, add a text-based Asset field as illustrated, and hit ‘Save’.

text-based Asset field as illustrated

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.

Ticket Fields

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.

new Ticket 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!

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.

Traverse to the Zendesk Guide platform

This leads you to the Zendesk Help Center knowledge base. Click on the ‘Guide Admin’ button at the top.

Zendesk Help Center knowledge base

Now, click the ‘Customize’ icon in the sidebar.

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’.

live theme within your Zendesk Help Center

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.

To edit the copied theme

Follow the pathway: Edit Code → Access Code.

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:

  1. document_head.hbs
  2. new_request_page.hbs
  3. 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.

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.

select the Request Page and New Request Page from the Templates dropdown to test the changes

As you can see, the Assets field has been populated on both the New Request and the Request pages.

Assets field has been populated on both the New Request and the Request pages
Laptop not working

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.

publish the edited theme for use by end-users

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.

Was this helpful?

Thanks for your feedback!

Powerful IT Asset Management Tool - at your fingertips

Empower your teams, streamline IT operations, and consolidate all your IT asset management needs through one platform.
G2 leader summer 2024
Index

Personalized Demo For You

Please share your details below & let our Product Specialist get back to you