Class: Msgtrail::Twitter

Inherits:
Object
  • Object
show all
Defined in:
lib/msgtrail/twitter.rb

Constant Summary collapse

PRE_AUTHENTICATION =
"Basic %s".freeze
POST_AUTHENTICATION =
"Bearer %s".freeze
CONTENT_TYPE_HEADER =
{ 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' }.freeze
TWITTER_API_OAUTH_ENDPOINT =
'https://api.twitter.com/oauth2/token'.freeze
TWITTER_API_STATUS_ENDPOINT =
"https://api.twitter.com/1.1/statuses/show.json?id=%s&tweet_mode=extended".freeze
TWITTER_AUTH_BODY =
'grant_type=client_credentials'.freeze
EXPECTED_TOKEN_TYPE =
'bearer'.freeze
TWITTER_STATUS_ENDPOINT =
"https://twitter.com/i/web/status/%s".freeze

Class Method Summary collapse

Class Method Details

.authenticateObject



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/msgtrail/twitter.rb', line 25

def self.authenticate
  api_key = ENV['TWITTER_CONSUMER_API_KEY']
  secret = ENV['TWITTER_CONSUMER_SECRET_KEY']
  credentials = Base64.strict_encode64("#{api_key}:#{secret}")
  begin
    result = HTTP.auth(PRE_AUTHENTICATION % credentials)
                 .headers(CONTENT_TYPE_HEADER)
                 .post(TWITTER_API_OAUTH_ENDPOINT, body: TWITTER_AUTH_BODY)
  rescue
    puts("Failed to authenticate with Twitter API (#{$!})")
    exit(2)
  end
  begin
    json = MultiJson.load(result.to_s, symbolize_keys: true)
  rescue
    puts("Invalid JSON from '#{TWITTER_API_OAUTH_ENDPOINT}' (#{$!})")
    exit(2)
  end
  EXPECTED_TOKEN_TYPE == json[:token_type] ? json[:access_token] : nil
end

.fetch(tweet_id) ⇒ Object



17
18
19
20
21
22
23
# File 'lib/msgtrail/twitter.rb', line 17

def self.fetch(tweet_id)
  if access_token = authenticate
    full_tweet_text(access_token, tweet_id)
  else
    puts("Failed to authenticate with Twitter API")
  end
end

.full_tweet_text(access_token, tweet_id) ⇒ Object

There seem to be two ways to get to any tweet by its ID:

  1. twitter.com/i/web/status/id

  2. twitter.com/statuses/#id

Using former method which seems to work best on desktop and mobile.



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/msgtrail/twitter.rb', line 50

def self.full_tweet_text(access_token, tweet_id)
  url = TWITTER_API_STATUS_ENDPOINT % tweet_id
  begin
    result = HTTP.auth(POST_AUTHENTICATION % access_token)
                 .get(url)
  rescue
    puts("Failed to get tweet from '#{url}' (#{$!})")
    exit(2)
  end
  begin
    json = MultiJson.load(result.to_s, symbolize_keys: true)
  rescue
    puts("Invalid JSON from '#{url}' (#{$!})")
    exit(2)
  end
  {
    body: json[:full_text],
    source: TWITTER_STATUS_ENDPOINT % tweet_id,
    type: Article::TYPE_TWEET
  }
end

.tweet_bodies(tweet_ids) ⇒ Object



13
14
15
# File 'lib/msgtrail/twitter.rb', line 13

def self.tweet_bodies(tweet_ids)
  tweet_ids.map { |tweet_id| fetch(tweet_id) }
end