twitter_labs_api 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b280e642f8468d372684da3c0a04ce2effffd652b244e53a50e1925ade66d3fc
4
- data.tar.gz: e1f1513a92468bc7fdb3e538bbc70b44ab15be2251f203485258f701b8c6b629
3
+ metadata.gz: f948545c92cea7e99843267178e59de531a72c6ae552b83d3e75e9166c15ef1a
4
+ data.tar.gz: 11a1eff22ea020997cfaa2242e2d53c3734d49d5bcf52ae6a505db5ed16d106a
5
5
  SHA512:
6
- metadata.gz: 7166032d4689b43fd696fc5f627dfe00af89eec532b3f36a652d6b22d3c74732c75b60e36be3a18caa9683b68c3b4629abad0d9319985ad56ef01ee19264ad94
7
- data.tar.gz: 259cb764a4c6f15ed5efb335bc46da7117fa447da3c19fd7754e931e40616bd2464847b547a9a17a7d5094f43195f717f196da6733ec47bfbf7d9c8470aa3e19
6
+ metadata.gz: b1ef6ca4d36e6c1fc0bbbeaa88a0ab764b66997b2ac8c1da2c546a8208f8368f9da6376341cdcc69a4d840a411ace4e5c38a30d71f6fa1463d1c24385a0164b2
7
+ data.tar.gz: 971f0fb5b2fe9d242ea98e1d7a51ee227f586580a04f14bf3c5af4e56541167c2e2f2d3e78977f7c3b78712a08ebf7af97e722ac7363da82cfe8e77e0ae8d387
@@ -0,0 +1 @@
1
+ pkg/
@@ -1,3 +1,9 @@
1
+ # 0.2.0 - 5 March 2020
2
+
3
+ - Fix: Handle 'successful' API errors (i.e., HTTP 200 response, but API error such as User Not Found)
4
+ - Documented expansion fields
5
+ - Documented methods
6
+
1
7
  # 0.1.0 - 5 March 2020
2
8
 
3
9
  Initial gem commit
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- twitter_labs_api (0.1.0)
4
+ twitter_labs_api (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -21,7 +21,7 @@ GEM
21
21
  minitest (5.14.0)
22
22
  rack (2.2.2)
23
23
  rainbow (3.0.0)
24
- rake (10.5.0)
24
+ rake (13.0.1)
25
25
  thread_safe (0.3.6)
26
26
  tzinfo (1.2.6)
27
27
  thread_safe (~> 0.1)
@@ -34,7 +34,7 @@ DEPENDENCIES
34
34
  activesupport
35
35
  bundler (~> 2.0)
36
36
  httplog
37
- rake (~> 10.0)
37
+ rake (~> 13.0)
38
38
  twitter_labs_api!
39
39
 
40
40
  BUNDLED WITH
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # twitter-labs-api
2
2
 
3
- A basic implementation of a Twitter Labs API client in Ruby. This project uses the v2 endpoints announced [here](https://twittercommunity.com/t/releasing-a-new-version-of-labs-endpoints/134219/3).
3
+ A basic implementation of a Twitter Labs API client as a handy Ruby [gem](https://rubygems.org/gems/twitter_labs_api). This project uses the v2 endpoints announced [here](https://twittercommunity.com/t/releasing-a-new-version-of-labs-endpoints/134219/3).
4
4
 
5
5
  ## Usage
6
6
 
@@ -9,10 +9,17 @@ All one needs is a Twitter [bearer token](https://developer.twitter.com/en/docs/
9
9
 
10
10
  One easy way to get a bearer token is to use [this method](https://www.rubydoc.info/gems/twitter/Twitter/REST/Client#bearer_token%3F-instance_method) from https://github.com/sferik/twitter.
11
11
 
12
+ ### Setup
13
+
14
+ ```shell
15
+ gem install twitter_labs_api
16
+ ```
17
+
12
18
  ### Example
13
19
 
20
+ #### Getting a Tweet by ID
14
21
  ```ruby
15
- requre `labs_api`
22
+ requre `twitter_labs_api`
16
23
 
17
24
  api = TwitterLabsAPI.new(bearer_token: 'YOUR-BEARER-TOKEN')
18
25
 
@@ -21,6 +28,18 @@ api.get_tweet(id: '1234671272602193920')
21
28
  >> {"data"=>{"author_id"=>"44196397", "created_at"=>"2020-03-03T02:45:45.000Z", "id"=>"1234671272602193920", "lang"=>"und", "public_metrics"=>{"retweet_count"=>4534, "reply_count"=>1036, "like_count"=>43489, "quote_count"=>224}, "text"=>"✌️ bro https://t.co/nJ7CUyhr2j"}}
22
29
  ```
23
30
 
31
+ #### Specifying which fields to include in the response
32
+
33
+ By default, the gem requests the 'default' fields for each entity. See the [API Reference](https://developer.twitter.com/en/docs/labs/tweets-and-users/api-reference) for available fields. One can customize the response payload like so:
34
+
35
+ ```ruby
36
+ my_fields = %w[id author_id created_at text]
37
+
38
+ api.get_tweet(id: '1235508591232090112', tweet_fields: my_fields)
39
+
40
+ >> {"author_id"=>"229708614", "created_at"=>"2020-03-05T10:12:57.000Z", "id"=>"1235508591232090112", "text"=>"Hot take: coronavirus will not boost remote work in the long run because spur-of-the-moment work-from-home for in-person companies is likely to be a shitshow."}
41
+ ```
42
+
24
43
  ### Status
25
44
  Currently, the following endpoints are implemented:
26
45
 
@@ -3,13 +3,14 @@ require 'net/http'
3
3
  require 'uri'
4
4
  require 'active_support/core_ext/hash/indifferent_access'
5
5
 
6
- DEFAULT_TWEET_FIELDS = %w[id author_id created_at lang public_metrics].join(',').freeze
7
- DEFAULT_USER_FIELDS = %w[name username].join(',').freeze
6
+ DEFAULT_TWEET_FIELDS = %w[id author_id created_at lang public_metrics].freeze
7
+ DEFAULT_USER_FIELDS = %w[name username].freeze
8
8
 
9
9
  class TwitterLabsAPIError < StandardError; end
10
10
 
11
+ # A basic implementation of a Twitter Labs API client.
11
12
  class TwitterLabsAPI
12
- attr_accessor :bearer_token, :debug
13
+ attr_accessor :bearer_token, :debug, :api_response, :parsed_response
13
14
 
14
15
  def initialize(bearer_token:, debug: false)
15
16
  @bearer_token = bearer_token
@@ -17,39 +18,47 @@ class TwitterLabsAPI
17
18
  require 'httplog' if debug
18
19
  end
19
20
 
21
+ # @param [String] :id the ID of the requested Tweet
22
+ # @param [Array<String>] :tweet_fields (["id", "author_id", "created_at", "lang", "public_metrics"]) the list of fields to retrieve for the given tweet
20
23
  def get_tweet(id:, tweet_fields: DEFAULT_TWEET_FIELDS)
21
24
  url = "https://api.twitter.com/labs/2/tweets/#{id}"
22
25
  params = {
23
- 'tweet.fields' => tweet_fields
26
+ 'tweet.fields' => tweet_fields.join(',')
24
27
  }.compact
25
28
 
26
29
  make_request(url: url, params: params)
27
30
  end
28
31
 
32
+ # @param [Array<String>] :ids the collection of requested Tweet IDs
33
+ # @param [Array<String>] :tweet_fields (["id", "author_id", "created_at", "lang", "public_metrics"]) the list of fields to retrieve for the given tweet
29
34
  def get_tweets(ids:, tweet_fields: DEFAULT_TWEET_FIELDS)
30
35
  url = 'https://api.twitter.com/labs/2/tweets'
31
36
  params = {
32
37
  'ids' => ids.join(','),
33
- 'tweet.fields' => tweet_fields
38
+ 'tweet.fields' => tweet_fields.join(',')
34
39
  }.compact
35
40
 
36
41
  make_request(url: url, params: params, is_collection: true)
37
42
  end
38
43
 
44
+ # @param [String] :id the ID of the requested User
45
+ # @param [Array<String>] :user_fields (["name", "username"]) the list of fields to retrieve for the given User
39
46
  def get_user(id:, user_fields: DEFAULT_USER_FIELDS)
40
47
  url = "https://api.twitter.com/labs/2/users/#{id}"
41
48
  params = {
42
- 'user.fields' => user_fields
49
+ 'user.fields' => user_fields.join(',')
43
50
  }.compact
44
51
 
45
52
  make_request(url: url, params: params)
46
53
  end
47
54
 
55
+ # @param [Array<String>] :ids the collection of requested User IDs
56
+ # @param [Array<String>] :user_fields (["name", "username"]) the list of fields to retrieve for the given User
48
57
  def get_users(ids:, user_fields: DEFAULT_USER_FIELDS)
49
58
  url = 'https://api.twitter.com/labs/2/users'
50
59
  params = {
51
60
  'ids' => ids.join(','),
52
- 'user.fields' => user_fields
61
+ 'user.fields' => user_fields.join(',')
53
62
  }.compact
54
63
 
55
64
  make_request(url: url, params: params, is_collection: true)
@@ -64,28 +73,33 @@ class TwitterLabsAPI
64
73
  request['Authorization'] = "Bearer #{bearer_token}"
65
74
  req_options = { use_ssl: uri.scheme == 'https' }
66
75
 
67
- response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
76
+ self.api_response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
68
77
  http.request(request)
69
78
  end
70
79
 
71
- is_collection ? handle_collection(response) : handle_single(response)
72
- end
80
+ raise TwitterLabsAPIError("#{api_response.code} #{api_response.msg}") unless api_response.is_a?(Net::HTTPSuccess)
81
+
82
+ self.parsed_response = JSON.parse(api_response.body)
73
83
 
74
- # TODO: handle non-api errs (e.g., timeouts)
75
- def handle_single(response)
76
- return JSON.parse(response.body)['data'].with_indifferent_access if response.is_a?(Net::HTTPSuccess)
84
+ handle_api_error if error_response?
77
85
 
78
- handle_api_error(response)
86
+ is_collection ? handle_collection : handle_single
79
87
  end
80
88
 
81
- def handle_collection(response)
82
- return JSON.parse(response.body)['data'].map(&:with_indifferent_access) if response.is_a?(Net::HTTPSuccess)
89
+ def error_response?
90
+ parsed_response.key?('errors')
91
+ end
92
+
93
+ def handle_single
94
+ parsed_response['data'].with_indifferent_access
95
+ end
83
96
 
84
- handle_api_error(response)
97
+ def handle_collection
98
+ parsed_response['data'].map(&:with_indifferent_access)
85
99
  end
86
100
 
87
- def handle_api_error(response)
88
- error = JSON.parse(response.body)
101
+ def handle_api_error
102
+ error = parsed_response['errors'].first
89
103
 
90
104
  raise TwitterLabsAPIError, "#{error['title']}: #{error['detail']} #{error['type']}"
91
105
  end
@@ -1,3 +1,3 @@
1
1
  class TwitterLabsAPI
2
- VERSION = '0.1.0'.freeze
2
+ VERSION = '0.2.0'.freeze
3
3
  end
@@ -26,5 +26,5 @@ Gem::Specification.new do |spec|
26
26
  spec.require_paths = ['lib']
27
27
 
28
28
  spec.add_development_dependency 'bundler', '~> 2.0'
29
- spec.add_development_dependency 'rake', '~> 10.0'
29
+ spec.add_development_dependency 'rake', '~> 13.0'
30
30
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twitter_labs_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - tomholford
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '13.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '13.0'
41
41
  description:
42
42
  email:
43
43
  - tomholford@users.noreply.github.com
@@ -45,6 +45,7 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
+ - ".gitignore"
48
49
  - CHANGELOG.md
49
50
  - Gemfile
50
51
  - Gemfile.lock