Matrix Slack App

Nebo uses an internal communications and scheduling tool called “the Matrix” that we built in house to meet our specific requirements. Over time, this tool has grown and now almost all our daily tasks live here, in the form of “to-dos”. At their most basic, a to-do is a short task description with an assignee, grouped into to-do lists within projects. Most of us spend much of our day with a Matrix tab open, keeping track of ongoing to-dos. We are also avid users of Slack, and often a conversation in Slack prompts a to-do — but that means switching to your browser, opening a Matrix tab, finding the appropriate project, and creating a to-do. Here’s an example:

What if instead, you could create a to-do directly from Slack?

The Build

Slack kindly provides functionality to build apps. A Slack “app” is a somewhat generous term. When I think of an “app”, I usually think of a proprietary platform or custom language that is required to deploy an app on someone’s device. Slack apps, by contrast, consist of nothing more than a few pages of settings in Slack’s web UI, and the code you write in whatever language you prefer that talks to Slack’s API. Since the Matrix is written in Ruby on Rails, we took advantage of the Slack Ruby Client to handle the underlying API communication.

We chose to create a Slack action, which adds a new option to the “more actions” button that’s available for each Slack message. When our API gets a request from Slack, we initialize a dialog:

One of the main limitations we ran into was the configuration of this dialog, since Slack has a limited set of dialog options. Our original idea was to have a “project” selector, and after the project was selected, we’d show you the to-do lists associated with that project. Unfortunately, that’s beyond the scope of this project, plus we discovered that you can only show up to 100 elements in a select box at a time. Instead, we decided to combine projects and to-do lists into a nested select, and used text filtering to dynamically populate the project/to-do list selector as you begin to type a project name.

@dialog = {
  "callback_id": "matrix-#{SecureRandom.urlsafe_base64(32)[0..16]}",
  "title": "Create To-Do",
  "submit_label": "Create",
  "elements": [
      "type": "text",
      "label": "Title",
      "name": "title",
      "value": message.truncate(146) # this value is limited to 150 characters
      "type": "textarea",
      "label": "Description",
      "name": "description",
      "value": description, # we’re setting this to the full message value if truncated
      "optional": true
      "type": "select",
      "label": "Project/To-Do List (search by project name)",
      "name": "ticket_list_id",
      "min_query_length": 2,
      "data_source": "external"
      "type": "select",
      "label": "Assign to",
      "name": "assignee_id",
      "min_query_length": 2,
      "data_source": "external",
      "optional": true

@client.dialog_open(dialog: @dialog, trigger_id: @payload['trigger_id']) 

We ended up using the same dynamic populate for the “assign to” field, because Slack limits you to 100 select options. We’re pushing that number of employees, so instead of a list of all employees returned with the dialog options, we set up our app as an external data source in order to dynamically populate the assignee list as you begin typing.

The Execution

My first thought on starting this project was “how in the world am I going to test this?” I’m doing all my development locally, but Slack needs to be able to communicate with a web-available server. Fortunately, one of their help docs introduced me to ngrok, which allows you to set up a tunnel to your localhost. After creating my app in Slack, I fired up ngrok and used my temporary ngrok URL for the Slack configuration. As an added “bonus”, anyone in my workplace could help me test my app, since installing the app meant installing it for our whole workspace. Slack doesn’t give you much room for a “sandbox” app that wouldn’t be immediately available to your entire workspace while under development. Our company doesn’t use actions much, or at least no one mentioned seeing the new action in the two months this was under development.

Next Steps

Now that we’ve ironed out the basic Slack authentication and Slack’s unique way of handling user interaction, we’re dreaming up all sorts of ways to connect Slack to the Matrix — time tracking, asking for a list of your to-dos that are due today, notifications when you have new messages…At some point we’ll be using Slack 100% of the time and never have to open a browser window.

Take Over the World With Us

Work With Us

See how our ideas, insights and know-how can help you tackle your next project — or build a human-centered experience for your brand.


Join the Team

Want to build something you believe in? See what it takes to become part of our fast-paced team of dreamers and innovators.

Open Jobs