class Driftwood::Slack
Public Class Methods
new(config)
click to toggle source
# File lib/driftwood/slack.rb, line 4 def initialize(config) @config = config @teams = {} @handlers = {} $logger.info "Started Slack bot" end
Public Instance Methods
all_channels()
click to toggle source
# File lib/driftwood/slack.rb, line 225 def all_channels @teams.keys.inject([]) do |channels, team_id| channels.concat(channels(team_id)) end end
all_messages(starting_from = 0)
click to toggle source
# File lib/driftwood/slack.rb, line 237 def all_messages(starting_from = 0) @teams.keys.inject([]) do |messages, team_id| messages.concat(messages(team_id, starting_from)) end end
all_users()
click to toggle source
# File lib/driftwood/slack.rb, line 231 def all_users @teams.keys.inject([]) do |users, team_id| users.concat(users(team_id)) end end
channel_info(team_id, channel_id)
click to toggle source
# File lib/driftwood/slack.rb, line 247 def channel_info(team_id, channel_id) @teams[team_id][:client].channels_info(channel: channel_id)['channel'] end
channel_name(team_id, channel_id)
click to toggle source
# File lib/driftwood/slack.rb, line 260 def channel_name(team_id, channel_id) channel_info(team_id, channel_id)['name'] rescue channel_id end
channels(team_id)
click to toggle source
# File lib/driftwood/slack.rb, line 175 def channels(team_id) preserve = ['team_id', 'channel_id', 'name', 'created', 'is_private', 'topic', 'purpose', 'num_members'] channels = @teams[team_id][:client].conversations_list(:types => 'public_channel, private_channel') channels = channels['channels'].reject{|i| i['is_archived']} channels.each do |row| row['team_id'] = team_id row['topic'] = row['topic']['value'] row['purpose'] = row['purpose']['value'] row['channel_id'] = row.delete('id') row.select! {|field| preserve.include? field} end end
create_slack_client(slack_api_secret)
click to toggle source
# File lib/driftwood/slack.rb, line 84 def create_slack_client(slack_api_secret) Slack.configure do |config| config.token = slack_api_secret fail 'Missing API token' unless config.token end Slack::Web::Client.new end
event(request_data)
click to toggle source
# File lib/driftwood/slack.rb, line 92 def event(request_data) # Check the verification token provided with the request to make sure it matches the verification token in # your app's setting to confirm that the request came from Slack. unless @config[:verification_token] == request_data['token'] $logger.warn "Invalid Slack verification token received: #{request_data['token']}" raise "Invalid Slack verification token received: #{request_data['token']}" end case request_data['type'] # When you enter your Events webhook URL into your app's Event Subscription settings, Slack verifies the # URL's authenticity by sending a challenge token to your endpoint, expecting your app to echo it back. # More info: https://api.slack.com/events/url_verification when 'url_verification' $logger.debug "Authorizing challenge: #{request_data['challenge']}" return request_data['challenge'] when 'event_callback' # Get the Team ID and Event data from the request object team_id = request_data['team_id'] event_data = request_data['event'] event_type = event_data['type'] user_id = event_data['user'] # Don't process events from our bot user unless user_id == @teams[team_id][:bot_user_id] if @handlers.include? event_type begin @handlers[event_type].each do |handler| handler.call(team_id, event_data) end rescue => e $logger.error "Handler for #{event_type} failed: #{e.message}" $logger.debug e.backtrace.join("\n") end else $logger.info "Unhandled event:" $logger.debug JSON.pretty_generate(request_data) end end end 'ok' end
messages(team_id, starting_from = 0)
click to toggle source
# File lib/driftwood/slack.rb, line 204 def messages(team_id, starting_from = 0) messages = [] channels = channels(team_id).map{|c| c['channel_id']} channels.each do |channel_id| oldest = starting_from data = { 'has_more' => true } while data['has_more'] do # note that we need the *user* scope here data = @teams[team_id][:user].channels_history(:channel => channel_id, :count => 1000, :oldest => oldest) oldest = data['messages'].last['ts'] rescue oldest messages.concat normalize_messages(team_id, channel_id, data['messages']) end end messages end
my_ims()
click to toggle source
# File lib/driftwood/slack.rb, line 307 def my_ims @teams.map do |team_id, team| team[:client].im_list['ims'].map { |im| im['id'] } end.flatten end
normalize_message(team_id, message)
click to toggle source
# File lib/driftwood/slack.rb, line 291 def normalize_message(team_id, message) preserve_fields = [ 'team_id', 'user_id', 'text', 'channel_id','ts' ] message['team_id'] = team_id message['user_id'] = message.delete('user') message['channel_id'] = message.delete('channel') message.select! {|field| preserve_fields.include? field} end
normalize_messages(team_id, channel_id, messages)
click to toggle source
# File lib/driftwood/slack.rb, line 300 def normalize_messages(team_id, channel_id, messages) messages.map do |message| message['channel'] = channel_id normalize_message(team_id, message) end end
normalize_user(user)
click to toggle source
# File lib/driftwood/slack.rb, line 268 def normalize_user(user) # Why slack? Why? return if user['deleted'] preserve_fields = [ 'team_id', 'user_id', 'name', 'real_name','display_name', 'updated', 'deleted', 'tz', 'tz_offset', 'is_owner', 'is_admin', 'status_text', 'status_emoji', 'image_72', 'image_192', 'title', 'phone', 'skype', 'email', ] user['user_id'] = user.delete('id') user['title'] = user['profile']['title'] user['phone'] = user['profile']['phone'] user['skype'] = user['profile']['skype'] user['email'] = user['profile']['email'] user['display_name'] = user['profile']['display_name'] user['status_text'] = user['profile']['status_text'] user['status_emoji'] = user['profile']['status_emoji'] user['image_72'] = user['profile']['image_72'] user['image_192'] = user['profile']['image_192'] user.select! {|field| preserve_fields.include? field} end
real_name(team_id, user_id)
click to toggle source
# File lib/driftwood/slack.rb, line 256 def real_name(team_id, user_id) user_info(team_id, user_id)['real_name'] rescue user_id end
register_handler(event, &block)
click to toggle source
# File lib/driftwood/slack.rb, line 72 def register_handler(event, &block) raise ArgumentError, "Handler (#{event}): no block passed" unless block_given? raise ArgumentError, "Handler (#{event}): incorrect parameters" unless block.parameters.length == 2 @handlers[event] ||= Array.new @handlers[event] << block $logger.info "Registered slack handler for #{event}" $logger.debug 'Current handlers:' $logger.debug @handlers.inspect end
send_response(team_id, channel, text, unfurl_links = false, attachment = nil, ts = nil)
click to toggle source
Send a response to an Event via the Web API.
# File lib/driftwood/slack.rb, line 137 def send_response(team_id, channel, text, unfurl_links = false, attachment = nil, ts = nil) # `ts` is optional, depending on whether we're sending the initial # welcome message or updating the existing welcome message tutorial items. # We open a new DM with `chat.postMessage` and update an existing DM with # `chat.update`. if ts @teams[team_id][:client].chat_update( as_user: 'true', channel: channel, ts: ts, text: text, attachments: attachment, unfurl_links: unfurl_links, ) else @teams[team_id][:client].chat_postMessage( as_user: 'true', channel: channel, text: text, attachments: attachment, unfurl_links: unfurl_links, ) end end
shell()
click to toggle source
# File lib/driftwood/slack.rb, line 318 def shell require 'pry' binding.pry end
team(team_id)
click to toggle source
# File lib/driftwood/slack.rb, line 162 def team(team_id) teams.select {|team| team[:team_id] == team_id }.first end
team_info(team_id)
click to toggle source
# File lib/driftwood/slack.rb, line 251 def team_info(team_id) @teams[team_id][:client].team_info()['team'] end
team_name(team_id)
click to toggle source
# File lib/driftwood/slack.rb, line 264 def team_name(team_id) team_info(team_id)['name'] rescue team_id end
teams()
click to toggle source
# File lib/driftwood/slack.rb, line 166 def teams() # munge into an array of hashes, easier for external tools to use. # ensure that the client object is removed to prevent serialization issues # This weird copy-like thing is to prevent mutation of the original object @teams.map do |team_id, team| {:team_id => team_id}.merge(team.reject { |key,value| [:client, :user].include? key }) end end
to_me?(event_data)
click to toggle source
# File lib/driftwood/slack.rb, line 313 def to_me?(event_data) return false unless event_data['channel_type'] == 'im' my_ims.include? event_data['channel'] end
user_info(team_id, user_id)
click to toggle source
# File lib/driftwood/slack.rb, line 243 def user_info(team_id, user_id) @teams[team_id][:client].users_info(user: user_id)['user'] end
users(team_id)
click to toggle source
# File lib/driftwood/slack.rb, line 188 def users(team_id) users = [] cursor = nil loop do data = @teams[team_id][:client].users_list(limit: 500, cursor: cursor) cursor = data['response_metadata']['next_cursor'] users.concat data['members'] break if (cursor.nil? or cursor.empty?) end users.each do |row| normalize_user(row) end.compact end