npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

zendesk-helpers

v1.0.0

Published

Grab all tickets without paging or generate analytics

Downloads

5

Readme

Zendesk-Helpers

Build Status

Components
  • Authorization generator for use in headers.
  • TicketGetter to retrieve tickets.

Use Case

Zendesk-Helpers has two parts. The use cases are:

AUTHORIZATION GENERATOR

  1. I want to generate a authorization header to send along with my Zendesk API call.

TICKETGETTER

  1. I want to grab my tickets from the Zendesk API without having to deal with implementing pagination.
  2. I want to easily store the returned tickets in a JSON file to do some map/reduce functions on them for analytics.
  3. I want to persist those records to a database.
  4. I want to force a response as an array and return them as part of a application API request.

Installation

npm i zendesk-helpers --save

For convenience add the following constants to your .env file (process.env)

  • ZENDESK_URL - Url for your Zendesk. Ex: https://obscura.knowledgeanywhere.com (not needed if your only using the authorization generator)
  • ZENDESK_USER - The administrator (email) to be used in conjunction with the API key. Ex: [email protected]
  • ZENDESK_TOKEN - The API key from Zendesk. You can obtain this by going to Settings > Channels Section > API and clicking new.

Having this constants as environment variables are optional, but convenient and secure. They will need to be passed into the class constructor otherwise.

Usage

Authorization

Use the generator to grab the base 64 string to be passed along with the Authorization header to the Zendesk REST API.

'use strict'; // long live arrow functions and lexical this.
let zh = require('zendesk-helpers');
let request = require('request')
let req = require('request-promise');
// The below assumes process.env.ZENDESK_USER and process.env.ZENDESK_TOKEN are defined.   Otherwise you must pass them in.
let auth = zh.auth();

//or manually pass them in.
let auth = zh.auth('[email protected]', 'sjdxxxxxxxxxx');


        let options = {
            method: 'GET',
            url: 'https://obscura.zendesk.com/api/v2/search.json',
            qs: {
                include: 'comment_count,groups',
                query: 'type:ticket tags:priority_normal',
            },
            headers: {
                'Content-Type': 'application/json',
                authorization: auth, // use the auth variable in a request.
                'User-Agent': 'Request-Promise'
            },
            json: true
        };
        req(options)
        .then((res) => console.log(res))
        .catch((err) => console.log('doh'));

TicketGetter

The Zendesk RESTful API is pretty well designed all things considered. The challenge Zendesk has is dealing with the unkown size of the response when it grabs the tickets. Some Zendesk instances might return a thousand tickets, not that big of a deal. Others, might return 30,000. Whoah. Hence, Zendesk implements pagination to its API for every 100 tickets. This can be a challenge to deal with on a recurring basis. It also presents a challenge to you on how best to work with that data and mold it if you are wishing to report on it and do advanced analytics.

The TicketGetter class built in Zendesk-Helpers makes this task a little bit easier by doing some of the grunt work for you. it makes the call to the Zendesk API, figures out how many pages it needs to get, and will iterate through all of them for you.

When it has succesfully grabbed all the tickets, it will by DEFAULT write them to a file, unless you force a response with the array of tickets. The latter is not recommended unless you are dealing with smaller buckets of tickets.

Sideloads and Queries

The TicketGetter constructor optionally accepts query and sideloads properties. You can provide the properties as the Zendesk API would normally accept it.

If BOTH query and sideloads properties are passed to the constructor, it will throw an error since the search.json endpoint does not support sideloads.

Options

TicketGetter is a Class and takes a constructor with the following options.

IMPORTANT: If a query is not provided, TicketGetter will use the tickets.json API endpoint. If a query IS provided, it will use the search.json endpoint.

//All options are technically optional as far as the constructor is concerned.   The first three constants can be present as environment variables.
let options = {
    url: 'obscura.knowledgeanywhere.com' //Url for your Zendesk.  OR process.env.ZENDESK_URL if its defined (recommended).  No trailing slash!
    token: 'xxxxxxx' //API token from Zendesk.  OR process.env.ZENDESK_TOKEN if its defined (STRONGLY recommended)
    user: '[email protected]' //Email address for the adminstrator that owns the token.  OR process.env.ZENDESK_USER (recommended).
    filename: 'ticket.data.json' //OPTIONAL. filename of the outputted tickets.  Defaults to 'tickets.data.json'.
    forceResponse: false //OPTIONAL Defaults to false.  If true will return an array of tickets under the 'payload' property.
    query: 'type:tickets status:open tags:priority_normal' // OPTIONAL. Query to be used with the search.json endpoint.    See note above.
    sideloads: 'comment_count,metric_events,users' // OPTIONAL. Sideloads related records.
};

Usage

Once you have built your options object, you're all set! Create a new instance of the TicketGetter class and call the populate method. Returns a promise with a response object containing metadata and the filename OR ticket array.

let tg = new TicketGetter();
tg.populate(options)
    .then()
    .catch();

Example

# .env file.  Make sure you add this to .gitignore
ZENDESK_URL="https://obscura.zendesk.com" # No trailing slash!
ZENDESK_USER="[email protected]"
ZENDESK_TOKEN="xxxxx"
'use strict';
let zh = require('zendesk-helpers');
let tg = new TicketGetter(); // construct with default options.
zd.populate() //Use default options
    .then((res) = {
        makeAnalytics(res);
        /*
        {
            "metadata": {
                "timestamp": "2017-02-22T20:40:45-08:00",
                "closedTicketsPeriod": "2016-10-25T20:40:45-07:00"
            },
            "data": [{
                "id": .......
            }]
        }
        */
    })
    .catch((err) => handleError(err));

Another Example

If you have a dashboard, you can use an interval to constantly refresh the data.


tg.populate(); // Initial population of ticket.data.json
setInterval(() => {
tg.populate()
.then((res) => {
//emit an event over websockets the data has been refreshed.
})
.catch();
}, 10000)