From 27b3c1dd4cdfbe5969cf08b2e1a504c36f99ad87 Mon Sep 17 00:00:00 2001 From: cookie-s Date: Fri, 28 Apr 2023 00:37:19 -0400 Subject: [PATCH 1/3] module SlackPatron --- lib/collector/events_api.rb | 146 ++++++++++++++++++------------------ lib/collector/rtm.rb | 106 +++++++++++++------------- logger/logger.rb | 2 +- 3 files changed, 129 insertions(+), 125 deletions(-) diff --git a/lib/collector/events_api.rb b/lib/collector/events_api.rb index 5cc5055..2376714 100644 --- a/lib/collector/events_api.rb +++ b/lib/collector/events_api.rb @@ -1,89 +1,91 @@ require 'rack' -module Collector - class EventsAPI - attr_reader :logger - - def initialize(team_id) - @team_id = team_id - raise ArgumentError unless @team_id and @team_id.start_with? 'T' - end - - def start!(logger) - @logger = logger - - Rack::Server.start( - app: lambda do |env| - req = Rack::Request.new(env) - - begin - Slack::Events::Request.new(req).verify! - process(req.body) - rescue Slack::Events::Request::MissingSigningSecret, - Slack::Events::Request::InvalidSignature, - Slack::Events::Request::TimestampExpired => e - warn 'bad request: %s' % e - [400, {}, ''] - end - end, - Port: 9293, - ) - end - - def process(body) - # https://api.slack.com/apis/connections/events-api +module SlackPatron + module Collector + class EventsAPI + attr_reader :logger + + def initialize(team_id) + @team_id = team_id + raise ArgumentError unless @team_id and @team_id.start_with? 'T' + end - data = JSON.parse(body.read) - type = data['type'] + def start!(logger) + @logger = logger + + Rack::Server.start( + app: lambda do |env| + req = Rack::Request.new(env) + + begin + Slack::Events::Request.new(req).verify! + process(req.body) + rescue Slack::Events::Request::MissingSigningSecret, + Slack::Events::Request::InvalidSignature, + Slack::Events::Request::TimestampExpired => e + warn 'bad request: %s' % e + [400, {}, ''] + end + end, + Port: 9293, + ) + end - case type - when 'url_verification' - [200, { 'content-type': 'text/plain' }, data['challenge']] - when 'event_callback' - process_event data['event'] if data['team_id'] == @team_id - [204, {}, ''] - else - [400, {}, ''] + def process(body) + # https://api.slack.com/apis/connections/events-api + + data = JSON.parse(body.read) + type = data['type'] + + case type + when 'url_verification' + [200, { 'content-type': 'text/plain' }, data['challenge']] + when 'event_callback' + process_event data['event'] if data['team_id'] == @team_id + [204, {}, ''] + else + [400, {}, ''] + end end - end - def process_event(event) - type = event['type'] - event.delete 'type' + def process_event(event) + type = event['type'] + event.delete 'type' - case type - when 'message' - # https://api.slack.com/events/message - puts 'new message' - logger.new_message(event) + case type + when 'message' + # https://api.slack.com/events/message + puts 'new message' + logger.new_message(event) - when 'team_join' - puts 'new user has joined' - logger.update_users + when 'team_join' + puts 'new user has joined' + logger.update_users - when 'user_change' - puts 'user data has changed' - logger.update_users + when 'user_change' + puts 'user data has changed' + logger.update_users - when 'channel_created' - puts 'channel has created' - logger.update_channels + when 'channel_created' + puts 'channel has created' + logger.update_channels - when 'channel_rename' - puts 'channel has renamed' - logger.update_channels + when 'channel_rename' + puts 'channel has renamed' + logger.update_channels - when 'emoji_changed' - puts 'emoji has changed' - logger.update_emojis + when 'emoji_changed' + puts 'emoji has changed' + logger.update_emojis - when 'reaction_added' - puts "reaction has added" - logger.new_reaction(event['item']['ts'], event['reaction'], event['user']) + when 'reaction_added' + puts "reaction has added" + logger.new_reaction(event['item']['ts'], event['reaction'], event['user']) - when 'reaction_removed' - puts "reaction has removed" - logger.drop_reaction(event['item']['ts'], event['reaction'], event['user']) + when 'reaction_removed' + puts "reaction has removed" + logger.drop_reaction(event['item']['ts'], event['reaction'], event['user']) + end end end end diff --git a/lib/collector/rtm.rb b/lib/collector/rtm.rb index 92d0c3f..b0fd922 100644 --- a/lib/collector/rtm.rb +++ b/lib/collector/rtm.rb @@ -1,56 +1,58 @@ -module Collector - class RTM - def start!(logger) - loop do - realtime = Slack::RealTime::Client.new - - realtime.on :message do |m| - puts 'new message' - logger.new_message(m) +module SlackPatron + module Collector + class RTM + def start!(logger) + loop do + realtime = Slack::RealTime::Client.new + + realtime.on :message do |m| + puts 'new message' + logger.new_message(m) + end + + realtime.on :team_join do |e| + puts "new user has joined" + logger.update_users + end + + realtime.on :user_change do |e| + puts "user data has changed" + logger.update_users + end + + realtime.on :channel_created do |c| + puts "channel has created" + logger.update_channels + end + + realtime.on :channel_rename do |c| + puts "channel has renamed" + logger.update_channels + end + + realtime.on :emoji_changed do |c| + puts "emoji has changed" + logger.update_emojis + end + + realtime.on :reaction_added do |c| + puts "reaction has added" + logger.new_reaction(c['item']['ts'], c['reaction'], c['user']) + end + + realtime.on :reaction_removed do |c| + puts "reaction has removed" + logger.drop_reaction(c['item']['ts'], c['reaction'], c['user']) + end + + # if connection closed, restart the realtime logger + realtime.on :close do + puts "websocket disconnected" + end + + realtime.start! + sleep 3 # なんかの理由で無限ループしても大丈夫なようにおきもち end - - realtime.on :team_join do |e| - puts "new user has joined" - logger.update_users - end - - realtime.on :user_change do |e| - puts "user data has changed" - logger.update_users - end - - realtime.on :channel_created do |c| - puts "channel has created" - logger.update_channels - end - - realtime.on :channel_rename do |c| - puts "channel has renamed" - logger.update_channels - end - - realtime.on :emoji_changed do |c| - puts "emoji has changed" - logger.update_emojis - end - - realtime.on :reaction_added do |c| - puts "reaction has added" - logger.new_reaction(c['item']['ts'], c['reaction'], c['user']) - end - - realtime.on :reaction_removed do |c| - puts "reaction has removed" - logger.drop_reaction(c['item']['ts'], c['reaction'], c['user']) - end - - # if connection closed, restart the realtime logger - realtime.on :close do - puts "websocket disconnected" - end - - realtime.start! - sleep 3 # なんかの理由で無限ループしても大丈夫なようにおきもち end end end diff --git a/logger/logger.rb b/logger/logger.rb index 67ecd24..52d3d31 100644 --- a/logger/logger.rb +++ b/logger/logger.rb @@ -6,5 +6,5 @@ config = YAML.load_file('./config.yml') -collector = config['slack']['use_events_api'] ? Collector::EventsAPI.new(config['slack']['team_id']) : Collector::RTM.new +collector = config['slack']['use_events_api'] ? SlackPatron::Collector::EventsAPI.new(config['slack']['team_id']) : SlackPatron::Collector::RTM.new SlackLogger.new.start collector From 076a90bb9a7737774166acc8bf8c21f93253f7c8 Mon Sep 17 00:00:00 2001 From: cookie-s Date: Fri, 28 Apr 2023 00:41:58 -0400 Subject: [PATCH 2/3] =?UTF-8?q?=E3=81=A9=E3=81=86=E3=81=A7=E3=82=82?= =?UTF-8?q?=E3=81=84=E3=81=84=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF=E3=82=BF?= =?UTF-8?q?=E3=83=AA=E3=83=B3=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/db.rb | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/db.rb b/lib/db.rb index 9560e50..3853b28 100644 --- a/lib/db.rb +++ b/lib/db.rb @@ -76,11 +76,10 @@ def replace_users(users) Channels = db['channels'] Channels.indexes.create_one({ :id => 1 }, :unique => true) def replace_channels(channels) - unless channels.nil? - ids = channels.map{ |channel| channel['id'] } - Channels.find(id: { '$in' => ids }).delete_many - Channels.insert_many(channels) - end + return if channels.nil? + ids = channels.map{ |channel| channel['id'] } + Channels.find(id: { '$in' => ids }).delete_many + Channels.insert_many(channels) end # Ims @@ -91,11 +90,10 @@ def replace_channels(channels) Emojis = db['emojis'] Emojis.indexes.create_one({ :name => 1 }, :unique => true) def replace_emojis(emojis) - unless emojis.nil? - emoji_data = emojis.map{ |name, url| { 'name' => name, 'url' => url } } - Emojis.find(name: { '$in' => emojis.keys }).delete_many - Emojis.insert_many(emoji_data) - end + return if emojis.nil? + emoji_data = emojis.map{ |name, url| { 'name' => name, 'url' => url } } + Emojis.find(name: { '$in' => emojis.keys }).delete_many + Emojis.insert_many(emoji_data) end Messages = db['messages'] @@ -148,4 +146,4 @@ def remove_reaction(ts, name, user) }, }, ) -end \ No newline at end of file +end From 66d6cc543cb6a0e86f29e63f27a13429d5c630e6 Mon Sep 17 00:00:00 2001 From: cookie-s Date: Fri, 28 Apr 2023 00:42:36 -0400 Subject: [PATCH 3/3] SlackPatron::SlackClient --- lib/slack.rb | 35 +++++++++++++++++++++++++++++++++++ lib/slack_logger.rb | 44 ++++++++++++++++++++------------------------ 2 files changed, 55 insertions(+), 24 deletions(-) diff --git a/lib/slack.rb b/lib/slack.rb index a008d1b..6b3ecd5 100644 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -15,3 +15,38 @@ Slack::Events.configure do |c| c.signing_secret = config['slack']['use_events_api'] ? config['slack']['signing_secret'] : nil end + +module SlackPatron + class SlackClient + attr_reader :client + + def initialize + @client = Slack::Web::Client.new + end + + def conversations_list + channels = [] + client.conversations_list({type: 'public_channel', limit: 1000}) do |response| + channels += response.channels + end + channels + end + + def users_list + members = [] + client.users_list do |response| + members += response.members + end + members + end + + def emoji_list + # paginationがないらしい + client.emoji_list.emoji + end + + def conversations_history(channel, count) + client.conversations_history({channel: channel, limit: count}).messages + end + end +end diff --git a/lib/slack_logger.rb b/lib/slack_logger.rb index 2af1c7c..721a238 100644 --- a/lib/slack_logger.rb +++ b/lib/slack_logger.rb @@ -3,10 +3,10 @@ require './lib/db' class SlackLogger - attr_reader :client + attr_reader :slack def initialize - @client = Slack::Web::Client.new + @slack = SlackPatron::SlackClient.new end def is_private_channel(channel_name) @@ -47,33 +47,31 @@ def drop_reaction(ts, name, user) end def update_users - users = client.users_list['members'] + users = slack.users_list replace_users(users) end def update_channels - channels = client.conversations_list({type: 'public_channel'})['channels'] + channels = slack.conversations_list replace_channels(channels) end def update_emojis - emojis = client.emoji_list['emoji'] rescue nil + emojis = slack.emoji_list replace_emojis(emojis) end - # log history messages - def fetch_history(target, channel) - messages = client.send( - target, - channel: channel, - count: 1000, - )['messages'] rescue nil - - unless messages.nil? - messages.each do |m| - m['channel'] = channel - insert_message(m) - end + def fetch_history(channel) + begin + messages = slack.conversations_history(channel, 1000) + rescue Slack::Web::Api::Errors::NotInChannel + return # どうしようもないね + end + return if messages.nil? + + messages.each do |m| + m['channel'] = channel + insert_message(m) end end @@ -85,12 +83,10 @@ def start(collector) update_users update_channels - Channels.find.each do |c| - puts "loading messages from #{c[:name]}" - if c[:is_channel] - fetch_history(:conversations_history, c[:id]) - end - sleep(1) + Channels.find.each do |channel| + puts "loading messages from #{channel[:name]}" + fetch_history channel[:id] + sleep 1 end # realtime event is joined and dont exit current thread