How to display sipgate phone calls in Slack.
I originally wrote this on the sipgate blog in English and also in German. In it I write a Slack integration for sipgate team using sipgate’s telephony API, sipgate.io.
Slack
Several teams at sipgate use Slack to help them manage their work and communicate in one place. Slack’s strapline is: “All your communication in one place, integrating with the tools and services you use every day.” I’ve heard similar claims before, only to be disappointed (I’m looking at you SharePoint and Google Wave). However, Slack is one of the first times the execution meets the promise.
A team may use multiple different SaaS apps but not all team members use all of them all of the time, or to the same extent. Without constantly switching between these apps, a team member may therefore miss important signals (from a customer or system). A Slack custom integration can help you tackle this problem by pulling information and activity from another tool and presenting it in a channel (a channel is like a thread). Each team member gets a high-level view of key events in each respective app and can decide whether to ignore, respond inline (i.e. in Slack) or switch to the app or service itself.
The sipgate UK support team uses many applications including Trello, Zendesk, Zopim Live Chat, Yammer and Twitter. As an example, we use the Twitter integration to post any mentions of our handles right into the support channel. We noticed, however, that we didn’t have an integration for our own SaaS app: sipgate team. As we run our business hotline through sipgate team (using a call queue), we thought it would be useful to see information about missed calls in our customer channel. That way we could easily coordinate phoning a customer back. If only we could write an integration?
Introducing sipgate.io
As it happens, some of our colleagues at sipgate have built just what we need. sipgate.io is a real-time telephony API, which can be used as a standalone service or with sipgate products. The API lets you pass information about incoming and outgoing phone calls to your own web server. This means you can integrate sipgate’s telephony with your own services, products or internal tools. As we wanted to be notified about incoming calls to our hotline, this was ideal.
Incoming WebHooks
In order to write an integration (rather than selecting one of the off-the-shelf integrations in Slack), you need to configure an ‘Incoming WebHook’. To do this, go to the App Directory in Slack, select ‘Configure’ and go to the Custom Integrations tab where you will see the Incoming Webhooks option.
To configure the webhook, select the channel into which you want to post and then, optionally, give the webhook a meaningful label, name and icon. Copy the webhook URL for the next step.
Some Code
Once you’ve set up your webhook you can get down to writing some code. I chose to write my integration in Ruby, in the Sinatra framework. (If there’s something here I haven’t explained, look in the GitHub documentation or in the sipgate.io cookbook.)
Firstly, before we can do anything we need to set some things up:
- Tell your application where to post in Slack. As I’m using the slack-notifier ruby gem, I need to instantiate that with the incoming webhook URL, which I copied from Slack.
- Create a data store. We need to (briefly) store some information about an incoming call so that we can access it when the call is answered. I used redis but of course you could use a sql database here instead.
- Enable testing locally. I used a service called ngrok to allow me to test my code out locally before deploying it to live.
We need to tell sipgate.io where our server is so that our code can run when a call is made to the hotline. This is done in sipgate team by going to the sipgate.io tab (you need to book sipgate.io first), selecting the group or user for whom you want to configure sipgate.io (in this case our UK Hotline group) and entering the URL of our server.
Once we’ve got this setup out of the way, let’s look at what happens when a call comes into our group. sipgate.io will make a post to the URL we told it about (above). At this point, we do two things:
- Store the phone number from which the call is coming so that our application can use this later.
- Tell sipgate.io (by means of some xml) two further URLs: one for when the call is answered and one for when the call is hung up.
Lastly, we need to determine what to do when sipgate.io sends us the answer and hangup events (for more information about events, see the GitHub documentation). We are interested in two scenarios:
- Missed calls when the hotline is on. During hotline hours (9:30 to 16:30 GMT, Monday to Friday) incoming calls stay in a call queue attached to a group until either the call is answered or the caller hangs up. If the caller hangs up before the call has been answered by a human, then a hangup event will be triggered with a hangup cause of “cancel”. When this type of event is triggered, we make a post to our Slack channel using the slack-notifier gem. We add an attachment to the notification to link to the sipgate team event list.
- Missed calls when the hotline is off. Outside of hotline hours, all incoming calls are forwarded to a voicemail. We can check for this scenario by looking at “answer” events and looking at which “user” has answered the phone call. When the user is equal to “voicemail”, then we know the hotline is off so we make an appropriate post to our Slack channel.
Not slacking off
This is what the missed call notifications look like in the Slack iPhone app. Neat, eh?