Skip to content

Instantly share code, notes, and snippets.

@akshaysasidrn
Last active September 18, 2017 09:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akshaysasidrn/1d9bb260be8caf4ffb718e5a0e01c510 to your computer and use it in GitHub Desktop.
Save akshaysasidrn/1d9bb260be8caf4ffb718e5a0e01c510 to your computer and use it in GitHub Desktop.
Implementing slash commands in HipChat

Slash commands in HipChat can be implemented by making use of Add-ons. HipChat Add-ons are web apps which can be integrated to the HipChat client.

As the doc states:

'A HipChat add-on is just a set of "capabilities" that implement an OAuth based authentication flow, a set of REST APIs, and JavaScript APIs.'

Installation flow

  • User begins installation of add-on in the HipChat server.
  • HipChat server then retrieves hosted add-on's capabilities descriptor via GET.
  • HipChat server registers the consumer and then posts OAuth consumerID/secret via POST to the Add-on.
  • This info has to be saved as it will be required to make calls to the HipChat REST API.
  • Add-on requests access token using the client-id and secret
  • Upon success, Add-on is installed.

If using HipChat libraries, then the installation flow is taken care of.

Creating Add-on

You can create a simple add-on using a wizard or build your own Add-on.

Building your own Add-on

Expose a capability descriptor which is a JSON-encoded document that describes the integration and what its capabilities are. You can validate your descriptor here.

{
  "name": "My Integration",
  "description": "An integration that does wonderful things",
  "key": "com.example.myintegration",
  "links": {
    "homepage": "https://example.com/myintegration",
    "self": "https://example.com/myintegration/capabilities"
  },
  "capabilities": {
    "hipchatApiConsumer": {
      "scopes": [
        "send_notification"
      ]
    }
  }
}

Data to store

  • Installation data
  • Capabilities token
  • API access token (Short lived token to be stored for HipChat REST API).
  • Addon specific data (config/user-specific-data)
Installation Data:

Your add-on will need to store data. HipChat sends the add-on the following request for each installation:

{ oauthId: 'cba74fbc-1b26-407e-811d-b9e377e4c440',
  capabilitiesUrl: 'https://api.hipchat.com/v2/capabilities',
  roomId: 100,
  groupId: 1,
  oauthSecret: 'NothWQ2HtSdsidQxxxkmMUzsACNzPSR' }
  • oauthId is unique for each installation and can be indexed upon storing.
  • capabilitiesUrl gives the URL to the capabilites document for the installation.
Capabilities Document:

This data gives you a list of endpoints your add-on should use to invoke the HipChat REST API.

{
 "capabilities": {
   ...
   "oauth2Provider: {
     "authorizationUrl": "https://www.hipchat.com/users/authorize", 
     "tokenUrl": "https://api.hipchat.com/v2/oauth/token"
   }, 
   "hipchatApiProvider": {
     "availableScopes": [list of scopes granted to the addon],
     "url": "https://api.hipchat.com/v2/" 
   },
   ...
}
  • oauth2Provider/tokenUrl: The endpoint you use to generate an add-on access token to invoke any REST API endpoint.
  • hipchatApiProvider/url: The base URL for any HipChat REST API endpoint.
  • oauth2Provider/authorizationUrl: The endpoint you use to ask a user permission to act on their behalf with a User token.

Handling the installation flow:

Need to specify, in the capabilities descriptor:

  • A REST endpoint for HipChat to POST the installation data to when your add-on is installed: capabilities/installable/callbackUrl
  • A REST endpoint for HipChat to POST to when your add-on is uninstalled: capabilities/installable/uninstalledUrl.
  • Whether the add-on can be installed globally (all rooms for a HipChat group), in specific HipChat rooms, or both.
"capabilities": {	
	...,	
	"installable": {
    	"allowGlobal": true,
        "allowRoom": true,
        "callbackUrl": "${host}/installed",
        "uninstalledUrl": "${host}/uninstalled"
    },
	...
}

Add-on Security

Make a POST request to the tokenUrl with oauthId & oauthSecret obtained from the capabilities document. This will respond with an access token (1 hr validity) which must be used for all subsequent requests to the HipChat REST API.

JWT token will be present in the POST requests from the HipChat Server to the Add-on and can be verified.

  1. Extract the token. Depending on the call:
    • from the HTTP header "Authorization"
    • from the request parameter: "signed_request"
  2. Decode the base64-encoded token
  3. Extract the oauthId which is in the 'iss' (issuer) parameter from the JWT token
  4. Lookup the installation data for this oauthId
  5. Use the sharedSecret from the installation data to validate the signature of the token

Making use of webhooks for slash commands

HipChat triggers a webhook for slash commands. These webhook allows you to specify a regular expression to match or an event to bind to. Webhooks can be bound to many events. You'd would have to make use of room_message_event with the regex as the trigger for slash commands.

To declare webhook as part of of an add-on, you need to add a webhook capability in your add-on's set of capabilities within the capability descriptor. Which will typically be something like:

"webhook": {
  "url": "https://addon.example.com/echo",
  "pattern": "^/[eE][cC][hH][oO]",
  "event": "room_message",
  "authentication": "jwt",
  "name": "Echo"
}

POST requests from HipChat Server to webhook endpoint will include JWT token for verification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment