Primal Data Advent Calendar #7: Building a Slack app for ticketing system

Michal Koláček
Slido developers blog
7 min readDec 17, 2020

This piece is a part of the Primal Data Advent Calendar, a series of miscellaneous articles written by the Slido Data Team. We release one on each Advent day that happens to be a prime (like 17 for the 17th of December). Enjoy!

(image source, edited)

Emily works in a back office for a small business. In the morning, William messages her that his laptop has been in dire need of repair for at least a month. Over lunch, Sophie laments that printing paper is running out and she is to prepare twelve copies of a 10-page memo for tomorrow's meeting. And then Jane rushes to Emily's desk in the afternoon to share what a great idea would it be to get some fluffy biscuits for tea time.

And the next day? It happens again; just with different people and different requests. Emily gets overwhelmed and wishes there was a better way.

Well, maybe your name isn't Emily and you don't work in a back office. You could, however, still end up in a situation where you need to handle multiple demands from your colleagues. Or you just want to be able to help Emily. In any case, you probably also wonder if there is “a better way”.

And there certainly is! Let's set up a ticketing system that will help you optimise such a flood of shopping (or any other) requests. It might seem like a daunting task at first, yet it is surprisingly easy to get it up and running whilst using nothing else but Slack and G Suite. In particular, by utilising Slack API and Google Apps Script (based on JavaScript), you can build a simple Slack app that lets you control the incoming inquiries, rather than the other way around.

Here is what the optimal flow could look like:
Slack command that initiates a modal for filing a request
Slack channel that stores the submissions in a form of a ticket message
Slack messages that notify requestors about any updates
Google Sheet that keeps a list of approved requests

Ticketing system in action

Considering its desired functionality, your app needs to:
1. Have the necessary setup in Slack and Google Apps Script
2. Process data sent by a Slack command
3. Build a Slack modal and display it back to the user
4. Process a response to the modal and create a ticket in a Slack channel
5. Handle interaction with the ticket and transfer data to a spreadsheet

We know what to do. Let's tackle these steps one by one!

Setting up Slack and Google Apps Script

To start with building the Slack app, head to Your Apps, Create New App, and install it to your Slack Workspace. Make sure to give the app a fitting name, description, and logo, because this bot appears to do all the magic for your colleagues.

Next, switch to the environment of Google Apps Script and create a New project. This is where all the magic truly happens – this is where your app actually gets built, where it handles the data from Slack, processes it, and sends it back.

Once you play around a bit, feel free to deploy your first draft via Deploy–New deployment whilst selecting Web app as Deploy type. Set the app to execute as Me and make it accessible to Anyone.

Keep in mind to always make a new deployment after changing the code.

Deployment in Google Apps Script

Done? Then copy the app’s URL in the next step, you’ll need it right away.

Working with a Slack command

Let's create a new Slack command /shopping-request by going to your Slack app's settings under Features–Slash Commands–Create New Command. Insert the URL you just copied into Request URL and consider adding ?call=command at the end of it to easily identify command calls in the code.

Slack command settings

When someone runs the command, Slack sends an HTTP POST request to this address. Your app then receives an interaction payload with type='command' parameter. The data is sent in a neat JSON format, which is easy to process and work with in Google Apps Script.

Building a Slack modal

To build a Slack modal for your colleagues to fill in, let's start with getting its design ready. When you're happy with it, use UrlFetchApp() class in your app to send an HTTP POST request back to Slack by calling views.open from its API.

Carefully follow Slack's instructions for the method and especially don't forget to:
• Obtain an authentication token from your Slack app’s settings under Features–OAuth & Permissions– Bot User OAuth Access Token and include it in the Authorization header of your POST request
• Extract the trigger_id parameter from the POST request from Slack and add it to your payload

If everything goes well, this successfully displays your modal to the user who runs the command in Slack and enables them to include all the details you specified.

Slack modal window

Creating a ticket

Before your colleague can hit Submit, you also need to instruct Slack where it should wait for the submission. Head to FeaturesInteractivity & Shortcuts and insert your app’s URL into Interactivity–Request URL. Again, I’d recommend adding something similar to ?call=interaction at the end of it for easier referencing.

After receiving and extracting data from the submission payload, you can start designing a ticket message whilst including interaction elements for approving or declining the shopping requests. For each of the elements, you should use clear action_id names (to ease distinguishing them) and store the modal response information into the value attributes (to make it accessible for later).

Consider whether to utilise attachments, given it is a legacy functionality.

To have one place where all the tickets are handled, let's create a new public channel in your Slack Workspace or use an already existing one. To post the ticket message into it, you might find it easiest to activate a webhook for it in your Slack app's settings under Features–Incoming Webhooks. This creates a URL that can be put into your HTTP POST request.

sendToSlack("https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXXXX/xxxxxxxxxxxxxxxxxxxxxxxx", result)

All worked well? Then voilà!

New ticket in Slack channel

If you'd also like to send a confirmation to the requestor, you may further call chat.postMessage method from Slack API to do exactly that. However, keep in mind that you might need to keep your message short to avoid text wrapping and it requires you to add chat:write scope to Features–OAuth & Permissions– Bot Token Scopes.

User notification in Slack direct message

Handling interactions

The ticket message is now in the channel, waiting for someone to interact with it, namely to either Accept or Decline the particular shopping request.

When any of the buttons gets clicked, Slack delivers an interaction payload with the type='block_actions' parameter to your app. Based on that, the app can then react by updating the ticket message.

Closed ticket in Slack channel

If you wish, you can also send a notification about such change to the requestor by calling the chat.postMessage method again.

By taking advantage of other Slack API methods, your app can obtain further information via an HTTP GET request and then present it to the user, e.g. a direct URL link to the ticket message or more details about the person who updated it. Bear in mind though that these methods might not accept application/json as a request's content type and you might need to add extra bot scopes.

If the shopping request gets approved, you might also find it handy to have it stored in a more accessible way to better plan the actual shopping. Let's create a new spreadsheet in your Google Drive (or use an existing one) and pass it all the necessary details through classes available for working with Google Sheets, e.g. by using a sequence of openById(), getSheetByName(), getRange(), and setValues().

Below is what you are presented with. You're ready to go shopping!

Google Sheet with approved requests

Conclusion

In the world full of distractions and scattered information, optimising the workflow for yourself (or Emily) has never been more important. If you value your time and energy, setting up a simple app is exactly for you. And with tools like Slack and G Suite at hand, it can be done surprisingly easily without spending an extra penny of your company's budget.

Full code is available here.

--

--