From Slack Apps to HipChat Add-ons

So, you've built a Slack App -- nice. Now you'd like to add support for HipChat -- awesome! This guide will walk you through the similarities between the two API platforms and make it easier for you to add support for HipChat in your Slack App.

Level set

Slack's integration capabilities

Before we get too deep into it, let's step back and discuss what you can build in Slack. Roughly speaking, Slack Apps have the following capabilities:

  1. Your app can send messages into a channel or direct message using incoming webhooks.
  2. Your app can invoke actions outside of Slack using slash commands
  3. Your app can listen to and respond to conversations using a bot user.
  4. Your app can make calls back to Slack's APIs based on the set of permissions the user has authorized.

HipChat's integration capabilities

Generally, HipChat Add-ons can do most of what Slack Apps can do. HipChat Add-ons can:

  1. Send messages or notifications into rooms.
  2. Listen to messages inside of rooms via webhooks and respond to them. This is how slash commands are implemented inside of HipChat.
  3. Call the HipChat API based on the permissions the user has granted the add-on.

Those three capabilities roughly match up to Slack's App capabilities. The one missing capability you'll notice is the lack of bot support through the core API platform (that's coming soon). However, it is possible to build bots using plain old XMPP -- and we do support Hubot.

In addition, HipChat's add-ons are capable of a lot more through the platform we call HipChat Connect.

What is HipChat Connect?

HipChat Connect is a way to extend HipChat using a bundled "add-on." 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. HipChat Add-ons are just web apps. These web apps can also be embedded into the HipChat clients' UI making it possible to build highly engaging apps or integrations within HipChat that go beyond text based interactions. However, to keep things simple, let's focus on how to map out what you've built in Slack into a HipChat Add-on.

Breaking it down

Posting messages into a HipChat Room

In Slack, you can use incoming webhooks to send messages into a channel. In HipChat, you can use the HipChat send_notification API. There's not much of a difference here except that HipChat's APIs must be called with an OAuth access token. In contrast, Slack apps are provided with a randomly generated URL in which you can post a JSON body to without having to authenticate. For consistency across all of our APIs, we require an API token.

Room messages from add-ons in HipChat can be sent in three different ways:

  1. As plain text -- Plain text messages will be treated just like regular messages a user posts in a room. For example, if your add-on's message has an @mention or emoticon text in the message, those will be converted to the proper @mention and emoticon. @mentions will also be treated just like an @mention and will notify the mentioned user.
  2. As HTML -- Messages can be decorated using HTML. HipChat only allows a certain set of HTML tags (a, b, strong, i, em, br, img, ul, ol, li, pre, code, p, span, , table, thead, tbody, tr, th, td) and within these tags, only a subset of attributes are allowed.
  3. As Cards -- HipChat clients can render add-on messages using a "card" format that brings consistency within HipChat. Cards come in a variety of formats that support different message content such as links, images, and activities. Cards can also contain metadata that can be used to enable UI actions within your add-on.

For more information on sending messages in HipChat, check out our guide on the topic.

Invoke actions using slash commands

Slack gives you the ability to register slash commands. They also give you the ability to create outgoing webhooks. The only real difference between the two is that slash commands start with a "/" and can be auto-completed in the chat input. Slash commands in Slack can be used in channels (public or private) and direct messages – outgoing webhooks can only be used in public channels.

HipChat doesn't distinguish between slash commands and regular webhook triggers. In HipChat, they're just webhooks. HipChat webhooks allow you specify a regular expression to listen for or an event to bind to as a trigger for the webhook. HipChat's webhooks can bind to the following events:

  • room_archived
  • room_created
  • room_deleted
  • room_enter
  • room_exit
  • room_file_upload
  • room_message
  • room_notification
  • room_topic_change
  • room_unarchived

For the room_message event, you can specify a regular expression as a match trigger. So, to create a slash command in HipChat, all you have to do is provide the regular expression to match your slash command. Webhooks can be created dynamically via the API, however, most of the time you'll probably want to create a webhook as part of an add-on. To declare a webhook as part of an addon, you need to add a webhook capability in your add-on's set of capabilities:

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

Currently, HipChat's webhooks are only available in rooms.

Typically, slash commands are used to invoke actions. The results of those actions are usually reported back as a response message to the user. In Slack there are "ephemeral" messages or "in channel" messages. Ephemeral messages are messages you receive in a channel that only you can see. In channel messages are messages sent by an app that everyone in the channel can see. HipChat doesn't have the notion of an "ephemeral" message. All messages shown in a HipChat room are messages that all participants of that room can see. Instead of taking up space in the chat stream for messages only you can see, we opted to give add-on developers a different way to allow users to interact with add-ons. The best and most common mapping to a Slack ephemeral message is HipChat's glance and sidebar view. This gives an add-on developer a lot more flexibility in building a UI that's perfect for interacting with its user – rather than just a text based conversational interaction.

For example, there's a popular Uber integration for Slack that exposes a /uber command. This integration makes it possible to request an Uber ride with the following command:

/uber ride [origin] to [destination]

While this command is fairly easy to use, it's prone to error for a user. What if the user types the origin or destination address incorrectly? There's no autocomplete for the destinations.

A similar integration with Uber exists inside of HipChat. However, instead of relying on slash commands, Uber for HipChat utilizes a glance and sidebar view to allow the user to request an Uber ride:

As you can see, this approach is a lot more user friendly. Your users get the convenience of having their origin and destination autocompleted for them as well as being able to visually understand how to use the feature because it's familiar with the Uber mobile app.

How do you verify a webhook?

In Slack, you receive a verification token when you register a slash command. You can use this token to verify that the slash command you received from Slack is valid. In HipChat, you will receive a JWT token in the "Authorization" header. You can then verify this JWT token using the OAuth secret you received when the add-on was installed.

Installation and authentication

As you can tell from above, the two platforms are very similar. The differences between the two platforms are more pronounced when we look at HipChat's support for UI extensibility, but beyond that, one of the bigger differences we haven't covered yet is how Slack Apps are installed versus how HipChat Add-ons are installed. Because Slack is a cloud only application, it's possible for 3rd party developers to register their app (an OAuth consumer) in a single global registry and receive a client ID and secret in return. This is a common OAuth 2 style integration seen with other cloud based apps.

HipChat operates in the cloud and also on premises (HipChat Server). Because of this, HipChat doesn't have a global public OAuth consumer registry. Instead, we dynamically register OAuth Consumers when an add-on is installed. Here's how that looks:

While it may seem more complex for a developer building an integration, one benefit of this process is that each OAuth consumer is bound to the scope of the room or the group. This means that an installed add-on cannot access or mutate data beyond the scope it was installed in. More details about how HipChat's install flow works is documented in detail in the following guides:

  • Installation flow – Overview of how HipChat's installation flow works
  • Server-side installation – This is the most common installation flow used when your add-on is publicly available on the internet and HipChat to your add-on server communication is possible
  • Client-side installation – You can use this in a scenario where your add-on is behind a firewall or you're running HipChat Server. In this case, you're a bit more limited in what your add-on can do in that you'll need to to use the browser to as the medium to communicate between HipChat and your add-on server.
  • Installation triggers – Handy URLs to allow your users to install your add-on from wherever you want

Was this page helpful?

Have a question about this article?

See questions about this article

Powered by Confluence and Scroll Viewport