Skip to content

Instantly share code, notes, and snippets.

@jasoncrawford
Created September 6, 2020 01:04
Show Gist options
  • Save jasoncrawford/681f3fe367d67f1f725a73c9575fb988 to your computer and use it in GitHub Desktop.
Save jasoncrawford/681f3fe367d67f1f725a73c9575fb988 to your computer and use it in GitHub Desktop.
Twitter utilities
These are some Twitter utilities, written directly against their API.
Credentials are required. Sign up for a Twitter developer account.
To run these scripts, ensure the BEARER_TOKEN is in the environment. E.g., put it in a .env file and run with foreman.
#!/usr/bin/env ruby
require 'net/http'
require 'json'
require 'csv'
TOKEN = ENV['BEARER_TOKEN']
def twitter_uri(path)
URI.parse("https://api.twitter.com/#{path}")
end
def twitter_request(uri, request)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request['Authorization'] = "Bearer #{TOKEN}"
response = http.request(request)
raise "HTTP error #{response.code}: #{response.message}" if response.code.to_i >= 400
JSON.parse(response.body)
end
def twitter_get(path)
uri = twitter_uri(path)
request = Net::HTTP::Get.new(uri.request_uri)
twitter_request(uri, request)
end
def twitter_post(path, params)
uri = twitter_uri(path)
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data(params)
twitter_request(uri, request)
end
username = ARGV[0]
cursor = -1
ids = []
while cursor != 0
response = twitter_get("1.1/followers/ids.json?screen_name=#{username}&cursor=#{cursor}")
ids += response['ids']
cursor = response['next_cursor']
puts "got #{ids.count} follower IDs"
end
puts "done getting follower IDs"
puts
count = 100
offset = 0
users = []
while offset < ids.length
ids_block = ids.slice(offset, count)
response = twitter_post("1.1/users/lookup.json", {user_id: ids_block.join(","), include_entities: false})
users += response
offset += count
puts "got #{users.count} followers"
end
puts "done getting followers"
puts
top_users = users.select {|u| u['followers_count'] >= 10000}.sort_by {|u| -u['followers_count']}
keys = [
"followers_count",
"screen_name",
"name",
"description",
"url",
"location",
"verified",
"friends_count",
"statuses_count",
"favourites_count",
"listed_count",
"created_at",
"id",
]
CSV.open("top-followers.csv", "wb") do |csv|
csv << (keys + ["profile_url"])
top_users.each do |user|
values = keys.map {|k| user[k]}
profile_url = "https://twitter.com/#{user['screen_name']}"
csv << (values + [profile_url])
end
end
#!/usr/bin/env ruby
require 'net/http'
require 'json'
require 'csv'
TOKEN = ENV['BEARER_TOKEN']
def twitter_uri(path)
URI.parse("https://api.twitter.com/#{path}")
end
def twitter_request(uri, request)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request['Authorization'] = "Bearer #{TOKEN}"
response = http.request(request)
raise "HTTP error #{response.code}: #{response.message}" if response.code.to_i >= 400
JSON.parse(response.body)
end
def twitter_get(path)
uri = twitter_uri(path)
request = Net::HTTP::Get.new(uri.request_uri)
twitter_request(uri, request)
end
tweet_url = ARGV[0]
puts "fetching thread *ending* with #{tweet_url}"
match = tweet_url.match(/status\/(\d+)/)
tweet_id = match[1]
tweets = []
while tweet_id
puts "fetching tweet #{tweet_id}"
response = twitter_get("2/tweets/#{tweet_id}?tweet.fields=referenced_tweets")
data = response['data']
text = data['text'].sub(/\n+/, ' ')
tweets.unshift text
referenced_tweets = data['referenced_tweets']
replied_to = referenced_tweets && referenced_tweets.find {|t| t['type'] == 'replied_to'}
tweet_id = replied_to && replied_to['id']
end
puts
puts tweets.join("\n\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment