Skip to content

Instantly share code, notes, and snippets.

@serradura
Last active October 19, 2017 06:02
Show Gist options
  • Save serradura/ef3885d6ba736757150c to your computer and use it in GitHub Desktop.
Save serradura/ef3885d6ba736757150c to your computer and use it in GitHub Desktop.
Simple Slack Slash Command (https://api.slack.com/slash-commands) example.
######################################
# 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
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