Skip to content

Instantly share code, notes, and snippets.

@augustt198
Created September 21, 2014 12:18
Show Gist options
  • Save augustt198/71e1bf4ad30496400f40 to your computer and use it in GitHub Desktop.
Save augustt198/71e1bf4ad30496400f40 to your computer and use it in GitHub Desktop.
require './slackbot'
app = App.new
run app
require 'rack'
require 'json'
require 'ostruct'
require 'htmlentities'
require './utils'
class App
def initialize(folder = 'commands/*.rb')
@bot = Slack::Bot.new folder
end
def call(env)
request = Rack::Request.new env
# POST to "/"
if request.path_info == '/' and request.post?
status = 200
begin
response = @bot.handle request.params
rescue JSON::ParserError
response = {error: 'Malformed Request', status: 400}
status = 400
end
[status, {'Content-Type' => 'application/json'}, [response]]
else
response = 'You are entering a robot-only facility.'
[200, {'Content-Type' => 'text/plain'}, [response]]
end
end
end
module Slack
CONFIG = OpenStruct.new
class Bot
def initialize(folder)
@commands = {}
@html_entities = HTMLEntities.new
# Eval commands in this instance
Dir[folder].each do |file|
puts "Loading command file: #{file}"
self.instance_eval File.open(file, 'r').read
end
end
def handle(params)
return {error: 'Missing parameters'}.to_json if !params['text'] or !params['user_name']
#return {error: 'nop'}.to_json if params['token'] != 't9haQf1aOhTZmCTCEUMKjZW5'
response = {username: 'AugustBot', icon_emoji: ':diamond_shape_with_a_dot_inside:'}
args = @html_entities.decode params['text'][1, params['text'].length - 1]
args = args.split ' '
command_name = args.shift
unless command_name.chars[0].match /^[[:alpha:]]$/
response[:text] = ''
return response.to_json
end
command = nil
@commands.each_pair do |name, data|
if name == command_name or data[:aliases].include? command_name
command = data
end
end
if command == nil
response[:text] = 'Command not found.'
else
if command[:users]
unless command[:users].include? params['user_name']
response[:text] = "You don't have permission to use that command, #{params['user_name']}"
return response.to_json
end
end
puts "Running command #{command_name} for #{params['user_name']} with args: #{args}"
time = Time.at params['timestamp'].to_i
message = Message.new args, params['user_name'], time, command_name
begin
command[:proc].call message
response[:text] = message.response.join "\n"
rescue Exception => e
backtrace = upload_gist(e.backtrace.join("\n"), 'exception.txt')['html_url']
response[:text] = ["Error running command: `#{e.message} (#{e.class})`", "Backtrace: #{backtrace}"].join "\n"
end
end
response.to_json
end
def on_command(name, options = {}, &block)
command = options.merge proc: block
# Ensure :aliases is an array
unless command[:aliases].is_a? Array
command[:aliases] = command[:aliases] ? [command[:aliases]] : []
end
# Ensure :help is a string
command[:help] = command[:help].to_s if command[:help]
unless command[:users].is_a? Array
command[:users] = [command[:users]] if command[:users]
end
@commands[name] = command
end
alias_method :command, :on_command
end
class Message
attr_reader :joined, :args, :user, :time, :label
attr_accessor :response
alias_method :content, :joined
alias_method :body, :joined
alias_method :username, :user
def initialize(args, username, time, label)
@args, @user, @time, @label = args, username, time, label
@joined = args.join ' '
@response = []
end
def reply(text = nil)
if text
@response << text
end
@response
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment