require 'httparty' require 'json' require 'selenium-webdriver' module SlackMattermostEmoji class SlackClient def initialize(username:, password:, domain:, download_path: nil, headless: true, log: true) @username = username @password = password @domain = domain @download_path = File.expand_path(download_path || './slack-emoji') @log = log @authenticated = false if [@username, @password, @domain].any? { |el| el.nil? || el.empty? } raise 'Slack username, password, and domain are all required' end Dir.mkdir(@download_path) unless Dir.exist?(@download_path) options = Selenium::WebDriver::Chrome::Options.new options.headless! unless headless == false @driver = Selenium::WebDriver.for :chrome, options: options end def authenticate print "Logging into Slack at #{@domain} as #{@username}... " if @log @driver.navigate.to "https://#{@domain}" @driver.find_element(name: 'email').send_keys(@username) @driver.find_element(name: 'password').send_keys(@password) @driver.find_element(id: 'signin_btn').click begin @driver.find_element(css: 'p.alert.alert_error') raise 'Invalid Slack credentials' rescue Selenium::WebDriver::Error::NoSuchElementError nil end puts 'success' if @log @authenticated = true end def download_emoji print "Finding emoji... " if @log token = @driver.execute_script(<<~JS) const config = JSON.parse(window.localStorage.localConfig_v2); const teams = Object.values(config.teams); const team = teams.find((team) => team.url.match('#{@domain}')); if (!team) { return null; } else { return team.token; } JS @driver.navigate.to("https://#{@domain}/api/emoji.list?token=#{token}") body = @driver.find_element(tag_name: 'body') data = JSON.parse(body.text) emoji_count = data['emoji'].size digits = emoji_count.to_s.size puts "found #{emoji_count} emoji" if @log data['emoji'].each_with_index do |emoji, index| next if URI(image_url).scheme == 'alias' name, image_url = emoji puts "#{(index + 1).to_s.rjust(digits, ' ')}/#{emoji_count} :#{name}:" if @log extension = File.extname(image_url) file_name = "#{name}#{extension}" file_path = File.join(@download_path, file_name) File.open(file_path, "wb") do |f| image = HTTParty.get(image_url) f.write(image.body) end end data['emoji'] end def authenticated? @authenticated end end end