Skip to content

Instantly share code, notes, and snippets.

@jorisroovers
Created April 21, 2022 07:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jorisroovers/3fd6242ffd8454838029b24561b2eb12 to your computer and use it in GitHub Desktop.
Save jorisroovers/3fd6242ffd8454838029b24561b2eb12 to your computer and use it in GitHub Desktop.
require "httparty"
require 'yaml'
require 'digest/sha1'
require 'slop'
########################################################################################################################
# CLI Parsing
# $varname = global variable (dollar sign = global var, accessible in functions)
$opts = Slop.parse do |o|
o.string '-d', '--dest', 'destination', default: "_data/shares.yml"
o.bool '-D', '--dry-run', "Do a dry-run (don't write to file)"
o.bool '--debug', "Print debug output"
o.on '-h', '--help' do
puts o
exit
end
end
if $opts.debug?
puts "DEBUG MODE"
end
if $opts.dry_run?
puts "DRY RUN"
end
########################################################################################################################
# Make sure all required env vars are set
required_env_vars = ['SLACK_API_TOKEN', 'SLACK_CHANNEL_ID']
required_env_vars.each do |env_var|
unless ENV.has_key?(env_var)
puts "Please set the '%s' environment variable." % [env_var]
puts "Exiting."
exit 1
end
end
########################################################################################################################
dst = $opts[:dest]
puts "Loading existing shares from #{dst}"
all_shares = YAML.load_file(dst)
all_ids = all_shares.map{|share| share['id']}
########################################################################################################################
# HELPER FUNCTIONS
def print_share(share)
puts "\tTITLE: #{share['title']}"
puts "\tURL: #{share['url']}"
puts "\tTIMESTAMP: #{share['timestamp']}"
puts "\tID: #{share['id']}"
puts "\t----"
end
def debug(msg)
if $opts.debug?
puts "DEBUG: #{msg}"
end
end
########################################################################################################################
puts "Making API Request to Slack"
url = "https://slack.com/api/conversations.history?token=%s&channel=%s" % \
[ENV["SLACK_API_TOKEN"], ENV["SLACK_CHANNEL_ID"]]
response = HTTParty.get(url, format: JSON)
# Basic response errpr handling
if response.code != 200
puts "ERROR: HTTP Reponse code: #{response.code} (#{url})"
exit 1
end
body = JSON.parse(response.body)
if body.has_key?('error')
puts "ERROR: API error: #{body['error']}"
exit 1
end
new_shares = []
messages = body['messages']
messages.each do |message|
debug(message)
# Skip messages that have a subtype, these are channel notifications like 'x joined channel'
unless message.has_key?('subtype')
# We will only parse slack messages that are of the format:
# text
# <url>
lines = message['text'].split("\n")
debug(lines)
# Messages where we have set an explicit title
if lines.length() == 2 and lines[0] != ""
share_url = lines[1][1..-2] # remove leading and trailing angular brackets
share_id = Digest::SHA1.hexdigest(share_url)
unless all_ids.include?(share_id)
title = lines[0]
puts "TITLELINE: #{title}"
['·',' - ',' – ', ' | '].each{|split_mark| title = title.partition(split_mark).first}
title = title.strip
share = {
'title' => title,
'url' => share_url,
'id' => share_id,
'timestamp' => message['ts']
}
print_share(share)
new_shares.push(share)
end
# Only URL is shared, determine title from attachment
elsif message.has_key?('attachments')
# Message is 2 lines, but title line is empty
if lines.length() == 2 and lines[0] == ""
lines.shift()
end
share_url = lines[0][1..-2] # remove leading and trailing angular brackets
share_id = Digest::SHA1.hexdigest(share_url)
unless all_ids.include?(share_id)
puts "URL ONLY"
title = message['attachments'][0]['title']
share = {
'title' => title,
'url' => share_url,
'id' => share_id,
'timestamp' => message['ts']
}
print_share(share)
new_shares.push(share)
end
end
end
end
########################################################################################################################
puts "Writing #{new_shares.length()} new share(s) to %s" % dst
all_shares = new_shares + all_shares # Prepend the new shares -> they are newer
unless $opts.dry_run?
File.open(dst, "w") { |file| file.write(all_shares.to_yaml) }
else
puts "DRY RUN: skipping filewrite"
end
puts "DONE"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment