Introduction
This is the last post of a series about how to write Slack Command APIs in Ruby. In the past post, we’ve finished the API by validating the input text and responding to callers with the correct outputs, based on requested actions.
In this last part of the tutorial we’re going to talk about the Chat API and how to use it to send direct messages to the congratulated user.
Sending direct messages to users
We’ve completed the application responsible for receiving, authorizing, validating and responding to an incoming Command API message.
Now, as a bonus, let’s use another API to send a direct message to the congratulated user. We’re going to use the chat.postMessage API method, but first we need to authorize it’s usage.
Authorizing the chat API
We need a new permission in order to be able to send a message as the a bot. This permission is called chat:write:bot
:
As you hit the “Save Changes” button on the Scopes box you will be asked to reinstall the application:
You’ll be redirected to the application authorization page. Authorize the new permission and we’re done here:
Testing the API via curl
Now we’ve authorized the new permissions to our application, we are able to test it via curl. Before that, we need the application’s OAuth Token to send the commands:
Replace the TOKEN with the value recently copied uppon and JOHN with a valid username in your team (perhaps yours):
curl --data "token=TOKEN&channel=%40JOHN&text=%40andersondias%20has%20congratulated%20you.&as_user=false&link_names=true" https://slack.com/api/chat.postMessage
And you should see a return like this:
{"ok":true,"channel":"D6543210","ts":"1503010047.000183","message":{"text":"@andersondias has congratulated you.","username":"command-app","bot_id":"B12345678","type":"message","subtype":"bot_message","ts":"1503010047.000183"}}
Access the Slack application with the channel username given upon and you will find a new message from @slackbot that should look like this:
Let’s dig in the params we’ve used in the curl call:
token
: it’s the OAuth Token from our Slack Application;channel
: who is going to receive the message; it’s the encoded version of @JOHN;text
: the encoded text to be sent; in this case “@andersondias has congratulated you.”;as_user
: when true it sends the message as the caller user; when false sends as the bot;link_names
: links user and channel names within text.
There are many other params that enables us to customize the chat messages as you can find in the chat.postMessage method documentation.
Now we know everything is working, let’s send direct messages from within our application.
Calling the API in our application via HTTPClient
Let’s begin by creating a new class that will deliver the messages. We will be using the most basic HTTP client in Ruby and we need to import it in the Gemfile:
# Gemfile
source 'https://rubygems.org'
ruby '2.4.1'gem 'sinatra'
gem 'httpclient'
Run bundle install
in the terminal to update the Gemfile.lock file.
Now, create a new file:
# app/slack_messenger.rbrequire 'httpclient'class SlackMessenger
SLACK_API_ENDPOINT = 'https://slack.com/api/chat.postMessage'.freeze def self.deliver(from, to, message)
new(from, to, message).deliver
end def initialize(from, to, message)
@from, @to, @message = from, to, message
end def deliver
client = HTTPClient.new
client.post(SLACK_API_ENDPOINT, params)
end def params
{
token: ENV['SLACK_OAUTH'],
channel: @to,
text: "@#{@from} has congratulated you: \"#{@message}\".",
as_user: false,
link_names: true
}
end
end
As you may notice, the OAuth token is now encapsulated in the SLACK_OAUTH
env var.
Next, we need to import this class and use it:
# app.rbrequire 'sinatra'
require_relative 'app/slack_authorizer'
require_relative 'app/slack_messenger'...post '/slack/command' do
case params['text'].to_s.strip
when VALID_CONGRATULATE_EXPRESSION
from, message = $1, $2
SlackMessenger.deliver(params['user_name'], from, message)
OK_RESPONSE % from
end
end
Note: I’ve removed all the unrelated code here and highlighted the code I’ve introduced inside the case statement. See the GitHub repository at the end of the post for more detailed codes.
We’re fetching the from
and message
variables from the regex captured results.
Before deploying it, we must setup the new environment variable:
Deploy and test it
Finally, we are able to deploy the new application version:
$ git add .
$ git commit -m 'Sending direct messages to users'
$ git push heroku master
Test it by sending this a new command:
/congratulate @andersondias you did a great job!
And you may see something like this:
Conclusion
We have come to the end of this series of posts on how to write Slack Command APIs in Ruby. Our application now receives the command message and sends a reply to the congratulated user.
There are many improvements to be made in a real world application:
- Do not allow users to send congratulations to themselves;
- Validates if the congratulated username is valid;
- Send the direct message asynchronously to prevent slow response times.
Probably, I’ll tackle each of these changes in the GitHub repository. Feel free to open pull requests with any improvements you may find useful.
Happy hacking!