Last active
October 19, 2017 06:02
-
-
Save serradura/ef3885d6ba736757150c to your computer and use it in GitHub Desktop.
Simple Slack Slash Command (https://api.slack.com/slash-commands) example.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
###################################### | |
# Ruby doc: http://ruby-doc.org/core # | |
###################################### | |
######### | |
# Setup # | |
######### | |
# | |
# Install the gems: | |
# ================= | |
# gem install sinatra pry shotgun --no-ri --no-rdoc | |
# | |
# Run the server: | |
# =============== | |
# shotgun app.rb | |
# | |
# Examples using HTTPie: https://github.com/jkbrzt/httpie | |
# ======================================================= | |
# | |
# http -F http -f POST localhost:9393 command="/calc" text="add 1 1" | |
# http -F http -f POST localhost:9393 command="/calc" text="sum 1 2" | |
# http -F http -f POST localhost:9393 command="/calc" text="sub 2 1" | |
# http -F http -f POST localhost:9393 command="/calc" text="minus 3 1" | |
# | |
# Tip: | |
# ==== | |
# Use the ngrok (https://ngrok.com/) to expose the server to the internet. | |
# | |
# Plus: | |
# ==== | |
# https://pt.wikipedia.org/wiki/Filosofia_Unix | |
# http://www.sinatrarb.com/ | |
# http://pryrepl.org/ | |
require "sinatra" | |
require "pry" | |
class CommandData | |
attr_reader :name | |
def initialize(params) | |
@data = params["text"].split | |
@name = @data[0] | |
end | |
def num_1 | |
num(1) | |
end | |
def num_2 | |
num(2) | |
end | |
private | |
def num(index) | |
Integer(@data[index]) | |
end | |
end | |
class CommandBase | |
attr_reader :data | |
def initialize(params) | |
@data = CommandData.new(params) | |
end | |
def operation | |
fail NotImplementedError | |
end | |
def invoke? | |
@data.name =~ pattern | |
end | |
def result | |
String(operation) | |
end | |
def pattern | |
self.class.const_get(:PATTERN) | |
end | |
end | |
class CommandSum < CommandBase | |
PATTERN = /sum|add/i | |
def operation | |
data.num_1 + data.num_2 | |
end | |
end | |
class CommandSub < CommandBase | |
PATTERN = /sub(tract)?|minus/i | |
def operation | |
data.num_1 - data.num_2 | |
end | |
end | |
COMMANDS = [CommandSum, CommandSub] | |
post "/" do | |
commands = COMMANDS.map {|command| command.new(params) } | |
command = commands.detect(&:invoke?) | |
command.result | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "sinatra" | |
require "pry" | |
# Standard library | |
require "forwardable" | |
class CommandData | |
attr_reader :command_name | |
def initialize(params) | |
@data = params["text"].split | |
@command_name = @data[0] | |
end | |
def num_1 | |
num(1) | |
end | |
def num_2 | |
num(2) | |
end | |
private | |
def num(index) | |
Integer(@data[index]) | |
end | |
end | |
class CommandBase | |
extend Forwardable | |
def_delegators :@data, :command_name, :num_1, :num_2 | |
def initialize(data) | |
@data = data | |
end | |
def operation | |
fail NotImplementedError | |
end | |
def result | |
String(operation) | |
end | |
def invoke? | |
command_name =~ pattern | |
end | |
def names | |
self.class.const_get(:NAMES) | |
end | |
private | |
def pattern | |
Regexp.new(names.join("|"), Regexp::IGNORECASE) | |
end | |
end | |
class CommandSum < CommandBase | |
NAMES = ["sum", "add"] | |
def operation | |
num_1 + num_2 | |
end | |
end | |
class CommandSub < CommandBase | |
NAMES = ["sub", "minus"] | |
def operation | |
num_1 - num_2 | |
end | |
end | |
class Commands | |
LIST = [CommandSum, CommandSub] | |
AVAILABLE_OPTIONS = "Available options: %{options}" | |
def initialize(params) | |
@data = CommandData.new(params) | |
end | |
def execute | |
command = detect | |
if command | |
command.result | |
else | |
available_options | |
end | |
end | |
private | |
def available_options | |
options = all.map(&:names).flatten.join(", ") | |
AVAILABLE_OPTIONS % {options: options} | |
end | |
def detect | |
all.detect(&:invoke?) | |
end | |
def all | |
LIST.map {|command| command.new(@data) } | |
end | |
end | |
get "/" do | |
execute_command | |
end | |
post "/" do | |
execute_command | |
end | |
private | |
def execute_command | |
Commands.new(params).execute | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment