Building a pipedrive add-on with Atlassian Connect Express for HipChat

02.05.2016
Daniel Meisen

Here at kreuzwerker we use HipChat a lot in our day-to-day communication. Along the obligatory youtube links and "lunch is ready"-messages, one type of information we share quite often is pipedrive deal URLs.

pipedrive is quite a powerful tool to manage active sales deals and potential sales opportunities in configurable pipelines and is used for all things "sales".

The pattern of these URLs follow the form of <user>.pipedrive.com/deal/<id>. They do not contain any "human readable parts" - so it's hard to tell what the deal is actually about. On the desktop just clicking the link and switching between the native HipChat client and the browser is usually painless - on the go however this is quite annoying.

To avoid unnecessary context switches, we wanted additional contextual information inside HipChat, if a pipedrive URL is being posted. Luckily HipChat already offers a facility for this: HipChat cards. By default HipChat already renders additional contextual information for certain types of URLs using cards. For example pasting the URL https://www.kreuzwerker.de to a chat room will render a small preview of the page.

hipchat-card

This only works for URLs that are publicly availably, requiring no additional form of authentication. Viewing pipedrive deal URLs is only possible if your are logged in. We also wanted custom cards with the most important information for the deal: the title and description, the owner (person responsible) and the current status. All of which is already available within the details view of a deal in pipedrive.

pipedrive-deal

HipChat allows to extend the core functionality easily using add-ons or integrations. Along the plethora of already available HipChat integrations, creating your own integration is easy. HipChat integrations can be built using all sorts of development stacks by utilizing the HipChat libraries. In addition to the two stacks supported by the HipChat team:

Also third party libraries can be used, such as:

Atlassian maintains a list of active stacks on the HipChat libraries page. For simple integrations the build your own wizard can be used.

Let's start building a simple HipChat add-on that talks to the pipedrive API to collect this information and displays it in a card inside the room, whenever a pipedrive deal URL is being posted.

Our add-on will be based on Node.js. Using Atlassian-Connect-Express (ACE), a template for the add-on can be generated. Assuming Node.js and atlas-connect is already installed, we simply execute:

atlas-connect new -t hipchat pipedrive-hipchat-addon

This will generate an application template (or scaffold), that will function as a base for any type of add-on.

The Atlassian tutorial Getting started with atlassian-connect-express (Node.js) will get you up and running quickly if you have not installed Node.js or atlas-connect and is also a good reference.

To test-drive the add-on during development ngrok can be used, to make the local add-on accessible from the internet. A new ngrok tunnel can be opened using:

ngrok http 3000

We need to make our add-on aware of it's external URL: the localBaseUrl is configured in config.json and will be set to the forwarding URL displayed in the ngrok output (i.e. http://08df211e.ngrok.io). Now it's time to build and start the add-on:

npm install
node app.js

The add-on can now be installed from the integrations configuration page in HipChat via "Install an integration from a descriptor URL" from the bottom of the page. During development the descriptor URL will be the forwarding URL provided by ngrok. The HipChat configuration page simply renders additional content - such as add-on configuration - of the add-on within an iframe. To avoid mixed content warnings the descriptor url should support SSL.

The add-on is installed in HipChat now but isn't very useful at this time. In order to provide the functionality to display contextual deal information for pipedrive deal URLs in a HipChat room, the add-on needs to listen to messages that are being sent to the room. This can be done using a Webhook. The Webhook is registered in the add-ons so called capability descriptor in atlassian-connect.json - the public contract of your add-on:

"webhook": {
  "url": "{{localBaseUrl}}/webhook",
  "pattern": ".*",
  "event": "room_message",
  "name": "pipedrive URL parsing webhook",
  "authentication": "jwt"
},

The endpoint of this Webhook will be implemented in the add-on descriptor in routes/index.js - the backend of you add-on:

app.post('/webhook',
addon.authenticate(),
  function (req, res) {

    // retrieve the add-on configuration
    addon.settings.get('configData',req.clientInfo.clientKey).then(function(data){

        var options = {
            pd_api_token: data.pd_api_token,
            pd_url: data.pd_url,
        };

        // check if the message in the chat room is a pipedrive URL
        if(!isValidPipedriveURL(req.body.item.message.message))
            return;

        var pipedriveUrl = parsePipedriveUrl(req.body.item.message.message);

        http('https://api.pipedrive.com/v1/deals/'+pipedriveUrl.dealId+':(id,title,status,user_id)?api_token='+options.pd_api_token, function (error, response, body) {
            // errror handling
            // ...
            //
            renderCard(body, hipchat, req, res, options);
        });
    });
}
);

The card itself is being assembled in renderCard(). A HipChat card can have different types (i.e. Application, Activity, Image, Link or Media). The card's look and feel can be customized. For our pipedrive card we'll use an application card:

var card = {
    "style": "application",
    "url": 'https://' + options.pd_url + '.pipedrive.com/deal/' + deal.id,
    "format": "medium",
    "id": "db797a68-0aff-4ae8-83fc-2e72dbb1a707",
    "title": "" + deal.title,
    "icon": {
        "url": iconURL + "/pipedrive_32x32.png"
    },
  "attributes": [
    {
      "label": "Contract ID",
      "value": {
          "label": deal.contract_id
      }
    },
    {
      "label": "Owner",
      "value": {
          "icon": { "url": "" + gravatar.url(deal.user_id.email, {s: '16', r: 'pg', d: '404'}) },
          "label": deal.user_id.name
      }
    },
    {
      "label": "Status",
      "value": {
        "label": deal.status,
        "style": statusStyle
      }
    }

  ],
  "activity": {
    "html": '<img src="' + iconURL + "/pipedrive_16x16.png" + '""/> <b>' + deal.title + "</b>"
  }
}

This will render a card within the HipChat room with the desired information for any posted pipedrive deal URL:

hipchat-pipedrive-card

The card is collapsed by default, only displaying the title of the deal. Additional information is available when expanding the card.

All in all creating this simple add-on took not more than a couple of hours - including all steps necessary to deploy it on Heroku for use in production. We have some additional features in mind, that we want to add before releasing this add-on and will most likely release it in the Atlassian Marketplace.

We are your Atlassian Partner for HipChat and other Atlassian products

Do you have questions regarding HipChat or other Atlassian products? Do you need additional information on using HipChat in the cloud or on premise? We are your Atlassian Enterprise Expert and Authorized Training Partner. We are happy to help: License Management, Consulting, Custom Development, Support & Maintenance or Training. For a complete overview of our Atlassian related service offerings please have a look at our Atlassian partner page or directly get in touch with us.

Daniel Meisen

For more than a decade Daniel has been a keen software developer, consultant and a coach. In addition to excursions into the development of embedded systems and model-driven development, he takes an agile, object-oriented approach using Ruby and Java. After completing his…

Read More ...
comments powered by Disqus