Writing Command APIs in Ruby — Part 3

Anderson Dias
Little programming joys
4 min readAug 16, 2017

--

Command validation and responses

Introduction

This is the third part of this tutorial about creating Slack Command APIs with Ruby. In the past post, we’ve authorized slack command requests using a Rack Middleware.

In this post, we’re going to talk about command validation and responses.

Command validation

Once the Sinatra application has received a POST message from Slack, we must validate the command params and respond according to the specified interface.

As we design in the first post of this series, the command should look like this:

The congratulate command structure: /congratulate @user message.

And this is the POST params structure sent by Slack Command API:

{
"token"=>"XXXXX",
"team_id"=>"YYYY",
"team_domain"=>"ZZZZ",
"channel_id"=>"UUUU",
"channel_name"=>"directmessage",
"user_id"=>"U1234567",
"user_name"=>"anderson",
"command"=>"/congratulate",
"text"=>"@john for his new product release! It's brilliant!",
"response_url"=>"https://hooks.slack.com/commands/YYYY/DDDDD/HASH"
}

For the purpouse of this tutorial we will validate the following params: user_name, command and text.

There are three expected outputs:

  1. A usage hint output when text starts with “help ”;
  2. An “OK” response when the message is valid;
  3. An error message with usage hint when anything else is given.

The help action

Slack Commands’ Best Practices recommends us to: “provide a help action that explains your command’s usage”.

Let’s start by tackling this issue. That’s simple:

require 'sinatra'
require_relative 'app/slack_authorizer'
use SlackAuthorizerHELP_RESPONSE = 'Use `/congratulate` to send a congratulation message to someone. Example: `/congratulate @anderson for design the new API`'.freezepost '/slack/command' do
HELP_RESPONSE
end

Sure we’ll need to change it later, for now, it’s ok.

Congratulating someone else

A valid congratulate command should have two distinct parts in the following order:

  • a nickname (@someone);
  • a message.

All these data will be sent in the text param, so we must validate it and then return an “OK” message if everything is fine.

require 'sinatra'
require_relative 'app/slack_authorizer'
use SlackAuthorizerVALID_CONGRATULATE_EXPRESSION = /^(@[\w\.\-_]+) (.+)/HELP_RESPONSE = 'Use `/congratulate` to send a congratulation message to someone. Example: `/congratulate @anderson for design the new API`'.freezeOK_RESPONSE = "Thanks for sending this! I'll share it with %s.".freezeINVALID_RESPONSE = 'Sorry, I didn’t quite get that. Perhaps try the words in a different order? This usually works: `/congratulate [@someone] [message]`.'.freezepost '/slack/command' do
case params['text'].to_s.strip
when 'help', '' then HELP_RESPONSE
when VALID_CONGRATULATE_EXPRESSION then OK_RESPONSE % $1
else INVALID_RESPONSE
end

end

As you may see above we validated the text param via regex and use its first capture (the nickname part) to append it to the OK_RESPONSE message.

Deploy and test it

Lets deploy a new version of the application to:

$ git add .
$ git commit -m 'Command handling'
$ git push heroku master

Once the application has been deployed, we can trigger the command to see if everything is ok.

First, lets test the help message:

/congratulate
/congratulate help
Help action response.

Now, let’s test the congratulate action:

/congratulate @anderson for sharing this with us!

And, we get:

Valid congratulate action triggered.

Finally, an incorrect command call:

/congratulate anderson for sharing this with us!

And:

Usage hint after an invalid action call.

Great! Our API is done.

Conclusion

The proposed solution is very simple but it works as expected. Sure we can add more validations to the command param, or use the user_name to save who have called the command, but that’s fine for now.

With that said you’ll be able to validate your commands and do anything you want with the text given by Slack Commands API.

As a bonus, in the next post, I’m going to talk about how to use the Slack’s Chat API to send the congratulation message to the specified user.

Follow the step by step coding at:

--

--