twitter_labs_api 0.4.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 471a4a8a8b2f248f11d0337240451d5b5bc2fdff5601370335f0ab080038cb0a
4
- data.tar.gz: 25f2097f036e2ba1b9431f5e4a01db6a062ea7507f05b648c85b9d3514c5d083
3
+ metadata.gz: 308afe5c20914abca1ed575f09b1e5924206034eae405886944d495fb6e4d3da
4
+ data.tar.gz: 5b931944828a477b39d0360d492c2fb6215b13ec12f8b953ac01533bcf822b44
5
5
  SHA512:
6
- metadata.gz: df432778d2baef5046f1c0d36ddd1b96f17e58414063ce3e76f15fdb9d7f78abc82327c598bc2a0e67fc3e205a430c5e5f851e1afb16691176a5722e506fe226
7
- data.tar.gz: bcad0b98629f789f004974fdc505929b7a7f42af362490a8d9bd5e3ade4389ae770e25cf1550cd46af308f3336b2c4f3018a71580e41e9f92e48d42d1aea5fca
6
+ metadata.gz: 12be24ffd5dfbc7b81b5bba6665cd264c39a8d9cbe828977b569285093b37e00036950db0a1b94c50fb287847897a6d8ba356bcb8b950c33197c4bda888a2a5a
7
+ data.tar.gz: b44d15ee5acc7a147ea3c2208c242cd45b6d5966cfbac0a2c2946b85594f73263853c4b0b45d9125567d20ffb295e33c45ae6491a2d4a0a31535a94a00b77ef7
@@ -0,0 +1,32 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Ruby
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ jobs:
17
+ test:
18
+
19
+ runs-on: ubuntu-latest
20
+
21
+ steps:
22
+ - uses: actions/checkout@v2
23
+ - name: Set up Ruby
24
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
25
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
26
+ uses: ruby/setup-ruby@v1
27
+ with:
28
+ ruby-version: 2.7
29
+ - name: Install dependencies
30
+ run: bundle install
31
+ - name: Run tests
32
+ run: bundle exec rspec
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
@@ -1,3 +1,49 @@
1
+ # 0.7.0 - 28 August 2020
2
+
3
+ - Refactor interface for requesting custom response fields
4
+
5
+ ## Breaking Change
6
+
7
+ Heads up, the argument to request fields was previously called `tweet_fields`; it is now called `fields`.
8
+
9
+ ```ruby
10
+ api.get_tweet(id: '123455683780', fields: requested_fields)
11
+ ```
12
+
13
+ The `fields` parameter now supports multiple different data types (instead of just Tweet attributes). So for example, to request the URL of an embedded media item:
14
+
15
+ ```ruby
16
+ requested_fields = { tweet: %w[id username], media: %w[url] }
17
+
18
+ api.get_tweet(id: my_id, fields: requested_fields)
19
+ ```
20
+
21
+ # 0.6.0 - 28 July 2020
22
+
23
+ - Fix: broken dependency
24
+
25
+ # 0.5.2 - 28 July 2020
26
+
27
+ - Add `search`
28
+ - Finish `rdoc` coverage
29
+
30
+ # 0.5.1 - 28 July 2020
31
+
32
+ - Add `User-Agent` request header
33
+ - Add `hide_reply`
34
+
35
+ # 0.5.0 - 27 July 2020
36
+
37
+ - Refactor structure to prepare for adding additional API endpoints
38
+ - Add `get_users_by_username`
39
+ - Add some test coverage
40
+
41
+
42
+ # 0.4.0 - 24 July 2020
43
+
44
+ - Better exception-handling: when API returns an error, a `TwitterLabsAPI::APIError` is thrown. It has the `Net::HTTP` response as an attribute so that the error can be handled properly. See the README for an example.
45
+
46
+
1
47
  # 0.3.0 - 28 April 2020
2
48
 
3
49
  - Fix: namespace of error class
data/Gemfile CHANGED
@@ -1,7 +1,13 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gemspec
3
+ group :development, :test do
4
+ gem 'amazing_print'
5
+ gem 'httplog'
6
+ gem 'irbtools'
7
+ gem 'pry'
8
+ gem 'rake'
9
+ gem 'rspec'
10
+ gem 'webmock'
11
+ end
4
12
 
5
- gem 'activesupport'
6
- gem 'httplog'
7
- gem 'pry'
13
+ gemspec
@@ -1,7 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- twitter_labs_api (0.4.0)
4
+ twitter_labs_api (0.7.0)
5
+ activesupport (~> 6.0)
6
+ httplog (~> 1.4)
5
7
 
6
8
  GEM
7
9
  remote: https://rubygems.org/
@@ -12,36 +14,121 @@ GEM
12
14
  minitest (~> 5.1)
13
15
  tzinfo (~> 1.1)
14
16
  zeitwerk (~> 2.2, >= 2.2.2)
17
+ addressable (2.7.0)
18
+ public_suffix (>= 2.0.2, < 5.0)
19
+ alias (0.2.3)
20
+ amazing_print (1.2.1)
21
+ binding.repl (3.0.0)
22
+ boson (1.3.0)
23
+ boson-more (0.3.1)
24
+ boson (>= 1.3.0)
25
+ cd (1.0.1)
26
+ clipboard (1.0.6)
15
27
  coderay (1.1.3)
16
- concurrent-ruby (1.1.6)
17
- httplog (1.3.2)
28
+ concurrent-ruby (1.1.7)
29
+ crack (0.4.3)
30
+ safe_yaml (~> 1.0.0)
31
+ debugging (1.1.1)
32
+ binding.repl (~> 3.0)
33
+ paint (>= 0.9, < 3.0)
34
+ diff-lcs (1.4.4)
35
+ every_day_irb (2.1.0)
36
+ cd (~> 1.0)
37
+ fancy_irb (1.2.1)
38
+ paint (>= 0.9, < 3.0)
39
+ unicode-display_width (~> 1.1)
40
+ ffi (1.13.1)
41
+ g (1.7.2)
42
+ hashdiff (1.0.1)
43
+ hirb (0.7.3)
44
+ httplog (1.4.3)
18
45
  rack (>= 1.0)
19
46
  rainbow (>= 2.0.0)
20
47
  i18n (1.8.5)
21
48
  concurrent-ruby (~> 1.0)
49
+ interactive_editor (0.0.11)
50
+ spoon (>= 0.0.1)
51
+ irbtools (1.7.1)
52
+ alias (~> 0.2.3)
53
+ binding.repl (~> 3.0)
54
+ boson (~> 1.3.0)
55
+ boson-more (~> 0.3.0)
56
+ clipboard (~> 1.0.5)
57
+ coderay (~> 1.1.0)
58
+ debugging (~> 1.0)
59
+ every_day_irb (>= 1.7.1)
60
+ fancy_irb (>= 0.7.3)
61
+ g (>= 1.7.2)
62
+ hirb (~> 0.7, >= 0.7.3)
63
+ interactive_editor (>= 0.0.10)
64
+ method_locator (>= 0.0.4)
65
+ method_source (>= 0.8.2)
66
+ methodfinder (~> 2.0)
67
+ ori (~> 0.1.0)
68
+ os (~> 0.9)
69
+ paint (>= 0.8.7)
70
+ ruby_engine (~> 1.0)
71
+ ruby_info (~> 1.0)
72
+ ruby_version (~> 1.0)
73
+ wirb (>= 1.0.3)
74
+ method_locator (0.0.4)
22
75
  method_source (1.0.0)
76
+ methodfinder (2.2.1)
23
77
  minitest (5.14.1)
78
+ ori (0.1.0)
79
+ os (0.9.6)
80
+ paint (2.2.0)
24
81
  pry (0.13.1)
25
82
  coderay (~> 1.1)
26
83
  method_source (~> 1.0)
84
+ public_suffix (4.0.5)
27
85
  rack (2.2.3)
28
86
  rainbow (3.0.0)
29
87
  rake (13.0.1)
88
+ rspec (3.9.0)
89
+ rspec-core (~> 3.9.0)
90
+ rspec-expectations (~> 3.9.0)
91
+ rspec-mocks (~> 3.9.0)
92
+ rspec-core (3.9.2)
93
+ rspec-support (~> 3.9.3)
94
+ rspec-expectations (3.9.2)
95
+ diff-lcs (>= 1.2.0, < 2.0)
96
+ rspec-support (~> 3.9.0)
97
+ rspec-mocks (3.9.1)
98
+ diff-lcs (>= 1.2.0, < 2.0)
99
+ rspec-support (~> 3.9.0)
100
+ rspec-support (3.9.3)
101
+ ruby_engine (1.0.1)
102
+ ruby_info (1.0.1)
103
+ ruby_version (1.0.2)
104
+ safe_yaml (1.0.5)
105
+ spoon (0.0.6)
106
+ ffi
30
107
  thread_safe (0.3.6)
31
108
  tzinfo (1.2.7)
32
109
  thread_safe (~> 0.1)
110
+ unicode-display_width (1.7.0)
111
+ webmock (3.8.3)
112
+ addressable (>= 2.3.6)
113
+ crack (>= 0.3.2)
114
+ hashdiff (>= 0.4.0, < 2.0.0)
115
+ wirb (2.2.1)
116
+ paint (>= 0.9, < 3.0)
33
117
  zeitwerk (2.4.0)
34
118
 
35
119
  PLATFORMS
36
120
  ruby
37
121
 
38
122
  DEPENDENCIES
39
- activesupport
123
+ amazing_print
40
124
  bundler (~> 2.0)
41
125
  httplog
126
+ irbtools
42
127
  pry
43
- rake (~> 13.0)
128
+ rake
129
+ rspec
44
130
  twitter_labs_api!
131
+ webmock
45
132
 
46
133
  BUNDLED WITH
47
134
  2.1.4
data/README.md CHANGED
@@ -1,13 +1,15 @@
1
1
  # twitter-labs-api
2
2
 
3
+ [![Labs v2](https://img.shields.io/static/v1?label=Twitter%20API&message=Developer%20Labs%20v2&color=192430&style=flat&logo=Twitter)](https://developer.twitter.com/en/docs/labs/overview/versioning)
4
+
3
5
  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
6
 
5
7
  ## Usage
6
8
 
7
9
  ### Prerequisite
8
- All one needs is a Twitter [bearer token](https://developer.twitter.com/en/docs/basics/authentication/oauth-2-0/bearer-tokens) to get started.
10
+ All one needs is a Twitter [bearer token](https://developer.twitter.com/en/docs/basics/authentication/oauth-2-0/bearer-tokens) to get started. The bearer token is available on the 'Tokens and Keys' page within your app's dashboard on the [Twitter for Developers](https://developer.twitter.com/) site.
9
11
 
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.
12
+ Alternatively, one can get a bearer token using [this method](https://www.rubydoc.info/gems/twitter/Twitter/REST/Client#bearer_token%3F-instance_method) from https://github.com/sferik/twitter.
11
13
 
12
14
  ### Setup
13
15
 
@@ -19,7 +21,7 @@ gem install twitter_labs_api
19
21
 
20
22
  #### Getting a Tweet by ID
21
23
  ```ruby
22
- requre `twitter_labs_api`
24
+ require `twitter_labs_api`
23
25
 
24
26
  api = TwitterLabsAPI.new(bearer_token: 'YOUR-BEARER-TOKEN')
25
27
 
@@ -30,19 +32,18 @@ api.get_tweet(id: '1234671272602193920')
30
32
 
31
33
  #### Specifying which fields to include in the response
32
34
 
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:
35
+ 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, depending on the requested resource.
34
36
 
37
+ For example, to request the URL of a Tweet's embedded media item:
35
38
  ```ruby
36
- my_fields = %w[id author_id created_at text]
37
-
38
- api.get_tweet(id: '1235508591232090112', tweet_fields: my_fields)
39
+ requested_fields = { tweet: %w[id username], media: %w[url] }
39
40
 
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
+ api.get_tweet(id: my_id, fields: requested_fields)
41
42
  ```
42
43
 
43
44
  #### API Errors
44
45
 
45
- Sometimes the API will respond with an error, for example `429 Too Many Requests`. The gem will throw an error with the `Net::HTTP` response as an attribute for proper exception-handling by the consuming app:
46
+ Sometimes the API will respond with an error, for example, `429 Too Many Requests`. The gem will throw an error with the `Net::HTTP` response as an attribute for proper exception-handling by the consuming app:
46
47
 
47
48
  ```ruby
48
49
  def my_twitter_request
@@ -58,14 +59,24 @@ end
58
59
  ### Status
59
60
  Currently, the following endpoints are implemented:
60
61
 
61
- - `TwitterLabsAPI#get_tweet` - Retrieve a single Tweet object with an `id`
62
- - `TwitterLabsAPI#get_tweets` - Retrieve multiple Tweets with a collection of `ids`
63
- - `TwitterLabsAPI#get_user` - Retrieve a single user object with an `id`
64
- - `TwitterLabsAPI#get_users` - Retrieve multiple user objects with a collection of `ids`
62
+ #### Tweets
63
+
64
+ - `TwitterLabsAPI#get_tweet` ([docs](https://developer.twitter.com/en/docs/labs/tweets-and-users/api-reference/get-tweets-id)) - Retrieve a single Tweet object with an `id`
65
+ - `TwitterLabsAPI#get_tweets` ([docs](https://developer.twitter.com/en/docs/labs/tweets-and-users/api-reference/get-tweets)) - Retrieve multiple Tweets with a collection of `ids`
66
+ - `TwitterLabsAPI#hide_reply` ([docs](https://developer.twitter.com/en/docs/labs/hide-replies/api-reference/put-hidden)) - Hide a reply by referencing it's `id`; must be in a conversation belonging to the authenticating user
67
+ - `TwitterLabsAPI#search` ([docs](https://developer.twitter.com/en/docs/labs/recent-search/api-reference/get-recent-search)) - Returns Tweets from the last 7 days that match a search query.
68
+
69
+ #### Users
70
+
71
+ - `TwitterLabsAPI#get_user` ([docs](https://developer.twitter.com/en/docs/labs/tweets-and-users/api-reference/get-users-id)) - Retrieve a single user object with an `id`
72
+ - `TwitterLabsAPI#get_users` ([docs](https://developer.twitter.com/en/docs/labs/tweets-and-users/api-reference/get-users)) - Retrieve multiple user objects with a collection of `ids`
73
+ - `TwitterLabsAPI#get_users_by_username` ([docs](https://developer.twitter.com/en/docs/labs/tweets-and-users/api-reference/get-users)) - Retrieve multiple user objects with a collection of `usernames`
65
74
 
66
75
  ## Roadmap
67
76
 
68
- Since this project is initially driven by my own usage of the API, I will focus on implementing and refinining the Tweets, Users, and Metrics endpoints. If this repo gets enough interest, I might implement the other endpoints and create a proper `.gemspec`. And of course, contributions are welcome :)
77
+ Currently focused on implementing support for all v2 endpoints; if there is enough interest, I will add v1 endpoint support as well.
78
+
79
+ And of course, contributions are welcome :)
69
80
 
70
81
  ## Dependencies
71
82
 
@@ -0,0 +1 @@
1
+ bundle exec rspec
@@ -2,119 +2,13 @@ require 'json'
2
2
  require 'net/http'
3
3
  require 'uri'
4
4
  require 'active_support/core_ext/hash/indifferent_access'
5
-
6
- DEFAULT_TWEET_FIELDS = %w[id author_id created_at lang public_metrics].freeze
7
- DEFAULT_USER_FIELDS = %w[name username].freeze
5
+ require_relative 'twitter_labs_api/client'
8
6
 
9
7
  # A basic implementation of a Twitter Labs API client.
10
- class TwitterLabsAPI
11
- attr_accessor :bearer_token, :debug, :api_response, :parsed_response
12
-
13
- class APIError < StandardError
14
- DEFAULT_MESSAGE = 'Twitter Labs API error, check the response attribute'.freeze
15
-
16
- attr_reader :response
17
-
18
- def initialize(msg = DEFAULT_MESSAGE, response = nil)
19
- @response = response
20
-
21
- super(msg)
8
+ module TwitterLabsAPI
9
+ class << self
10
+ def new(bearer_token:, debug: false)
11
+ Client.new(bearer_token: bearer_token, debug: debug)
22
12
  end
23
13
  end
24
-
25
- def initialize(bearer_token:, debug: false)
26
- @bearer_token = bearer_token
27
- @debug = debug
28
- require 'httplog' if debug
29
- end
30
-
31
- # @param [String] :id the ID of the requested Tweet
32
- # @param [Array<String>] :tweet_fields (["id", "author_id", "created_at", "lang", "public_metrics"]) the list of fields to retrieve for the given tweet
33
- def get_tweet(id:, tweet_fields: DEFAULT_TWEET_FIELDS)
34
- url = "https://api.twitter.com/labs/2/tweets/#{id}"
35
- params = {
36
- 'tweet.fields' => tweet_fields.join(',')
37
- }.compact
38
-
39
- make_request(url: url, params: params)
40
- end
41
-
42
- # @param [Array<String>] :ids the collection of requested Tweet IDs
43
- # @param [Array<String>] :tweet_fields (["id", "author_id", "created_at", "lang", "public_metrics"]) the list of fields to retrieve for the given tweet
44
- def get_tweets(ids:, tweet_fields: DEFAULT_TWEET_FIELDS)
45
- url = 'https://api.twitter.com/labs/2/tweets'
46
- params = {
47
- 'ids' => ids.join(','),
48
- 'tweet.fields' => tweet_fields.join(',')
49
- }.compact
50
-
51
- make_request(url: url, params: params, is_collection: true)
52
- end
53
-
54
- # @param [String] :id the ID of the requested User
55
- # @param [Array<String>] :user_fields (["name", "username"]) the list of fields to retrieve for the given User
56
- def get_user(id:, user_fields: DEFAULT_USER_FIELDS)
57
- url = "https://api.twitter.com/labs/2/users/#{id}"
58
- params = {
59
- 'user.fields' => user_fields.join(',')
60
- }.compact
61
-
62
- make_request(url: url, params: params)
63
- end
64
-
65
- # @param [Array<String>] :ids the collection of requested User IDs
66
- # @param [Array<String>] :user_fields (["name", "username"]) the list of fields to retrieve for the given User
67
- def get_users(ids:, user_fields: DEFAULT_USER_FIELDS)
68
- url = 'https://api.twitter.com/labs/2/users'
69
- params = {
70
- 'ids' => ids.join(','),
71
- 'user.fields' => user_fields.join(',')
72
- }.compact
73
-
74
- make_request(url: url, params: params, is_collection: true)
75
- end
76
-
77
- private
78
-
79
- def make_request(url:, params: {}, is_collection: false)
80
- uri = URI.parse(url)
81
- uri.query = URI.encode_www_form(params)
82
- request = Net::HTTP::Get.new(uri)
83
- request['Authorization'] = "Bearer #{bearer_token}"
84
- req_options = { use_ssl: uri.scheme == 'https' }
85
-
86
- self.api_response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
87
- http.request(request)
88
- end
89
-
90
- raise_http_error unless api_response.is_a?(Net::HTTPSuccess)
91
-
92
- self.parsed_response = JSON.parse(api_response.body)
93
-
94
- handle_api_error if error_response?
95
-
96
- is_collection ? handle_collection : handle_single
97
- end
98
-
99
- def error_response?
100
- parsed_response.key?('errors')
101
- end
102
-
103
- def handle_single
104
- parsed_response['data'].with_indifferent_access
105
- end
106
-
107
- def handle_collection
108
- parsed_response['data'].map(&:with_indifferent_access)
109
- end
110
-
111
- def raise_http_error
112
- raise(APIError.new("#{api_response.code} #{api_response.msg}", api_response))
113
- end
114
-
115
- def handle_api_error
116
- error = parsed_response['errors'].first
117
-
118
- raise APIError.new("#{error['title']}: #{error['detail']} #{error['type']}", api_response)
119
- end
120
14
  end
@@ -0,0 +1,13 @@
1
+ module TwitterLabsAPI
2
+ class APIError < StandardError
3
+ DEFAULT_MESSAGE = 'Twitter Labs API error, check the response attribute'.freeze
4
+
5
+ attr_reader :response
6
+
7
+ def initialize(msg = DEFAULT_MESSAGE, response = nil)
8
+ @response = response
9
+
10
+ super(msg)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,73 @@
1
+ require_relative 'version'
2
+ require_relative 'api_error'
3
+ require_relative 'resources/tweet'
4
+ require_relative 'resources/user'
5
+
6
+ module TwitterLabsAPI
7
+ class Client
8
+ include Resources::Tweet
9
+ include Resources::User
10
+
11
+ attr_accessor :bearer_token, :debug, :api_response, :parsed_response
12
+
13
+ def initialize(bearer_token:, debug: false)
14
+ @bearer_token = bearer_token
15
+ @debug = debug
16
+ require 'httplog' if debug
17
+ end
18
+
19
+ private
20
+
21
+ def make_request(url:, params: {}, is_collection: false, method: :get)
22
+ uri = URI.parse(url)
23
+ uri.query = URI.encode_www_form(params)
24
+ request = http_adapter(method).new(uri)
25
+ request['Authorization'] = "Bearer #{bearer_token}"
26
+ request['User-Agent'] = "twitter_labs_api gem #{TwitterLabsAPI::VERSION}"
27
+ req_options = { use_ssl: uri.scheme == 'https' }
28
+
29
+ self.api_response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
30
+ http.request(request)
31
+ end
32
+
33
+ raise_http_error unless api_response.is_a?(Net::HTTPSuccess)
34
+
35
+ self.parsed_response = JSON.parse(api_response.body)
36
+
37
+ handle_api_error if error_response?
38
+
39
+ is_collection ? handle_collection : handle_single
40
+ end
41
+
42
+ def http_adapter(method)
43
+ case method
44
+ when :put
45
+ Net::HTTP::Put
46
+ else
47
+ Net::HTTP::Get
48
+ end
49
+ end
50
+
51
+ def error_response?
52
+ parsed_response.key?('errors')
53
+ end
54
+
55
+ def handle_single
56
+ parsed_response['data'].with_indifferent_access
57
+ end
58
+
59
+ def handle_collection
60
+ parsed_response['data'].map(&:with_indifferent_access)
61
+ end
62
+
63
+ def raise_http_error
64
+ raise(APIError.new("#{api_response.code} #{api_response.msg}", api_response))
65
+ end
66
+
67
+ def handle_api_error
68
+ error = parsed_response['errors'].first
69
+
70
+ raise APIError.new("#{error['title']}: #{error['detail']} #{error['type']}", api_response)
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,58 @@
1
+ module TwitterLabsAPI
2
+ module Resources
3
+ module Tweet
4
+ DEFAULT_TWEET_FIELDS = %w[id author_id created_at lang public_metrics].freeze
5
+ DEFAULT_FIELDS = { tweet: DEFAULT_TWEET_FIELDS }.freeze
6
+
7
+ # Returns a variety of information about a single Tweet specified by the requested ID.
8
+ # @param [String] :id the ID of the requested Tweet
9
+ # @param [Hash] :fields a hash for fields to include in the response payload;
10
+ #
11
+ # e.g.: { tweet: %w[id username], media: %w[url] }
12
+ # @return Hash an object with requested tweet fields
13
+ def get_tweet(id:, fields: DEFAULT_FIELDS)
14
+ url = "https://api.twitter.com/labs/2/tweets/#{id}"
15
+ params = ParamsService.from_fields(fields)
16
+
17
+ make_request(url: url, params: params)
18
+ end
19
+
20
+ # Returns a variety of information about the Tweet specified by the requested ID or list of IDs.
21
+ # @param [Array<String>] :ids the collection of requested Tweet IDs
22
+ # @param [Hash] :fields a hash for fields to include in the response payload;
23
+ #
24
+ # e.g.: { tweet: %w[id username], media: %w[url] }
25
+ # @return [Array<Hash>] of tweet objects with the requested tweet fields
26
+ def get_tweets(ids:, fields: DEFAULT_FIELDS)
27
+ url = 'https://api.twitter.com/labs/2/tweets'
28
+ params = ParamsService.from_fields(fields)
29
+ params.merge!({ ids: ids.join(',') })
30
+
31
+ make_request(url: url, params: params, is_collection: true)
32
+ end
33
+
34
+ # Hides or unhides a reply to a Tweet.
35
+ # @param [String] :id the ID of the requested Tweet; must belong to a conversation by the authenticated user
36
+ # @return boolean indicating the hidden status of the requested tweet
37
+ def hide_reply(id:)
38
+ url = "https://api.twitter.com/labs/2/tweets/#{id}/hidden"
39
+
40
+ make_request(url: url, method: :put)[:hidden]
41
+ end
42
+
43
+ # The Labs recent search endpoint returns Tweets from the last 7 days that match a search query.
44
+ # @param [String] :query the search query
45
+ # @param [Hash] :fields a hash for fields to include in the response payload;
46
+ #
47
+ # e.g.: { tweet: %w[id username], media: %w[url] }
48
+ # @return [Array<Hash>] of tweet objects with the requested tweet fields
49
+ def search(query:, fields: DEFAULT_FIELDS)
50
+ url = 'https://api.twitter.com/labs/2/tweets/search'
51
+ params = ParamsService.from_fields(fields)
52
+ params.merge!({ query: query })
53
+
54
+ make_request(url: url, params: params, is_collection: true)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,49 @@
1
+ module TwitterLabsAPI
2
+ module Resources
3
+ module User
4
+ DEFAULT_USER_FIELDS = %w[id name username].freeze
5
+ DEFAULT_FIELDS = { user: DEFAULT_USER_FIELDS }.freeze
6
+
7
+ # Returns a variety of information about a single more user specified by the requested ID.
8
+ # @param [String] :id the ID of the requested User
9
+ # @param [Hash] :fields a hash for fields to include in the response payload;
10
+ #
11
+ # e.g.: { user: %w[id name username] }
12
+ # @return Hash an object with requested user fields
13
+ def get_user(id:, fields: DEFAULT_FIELDS)
14
+ url = "https://api.twitter.com/labs/2/users/#{id}"
15
+ params = ParamsService.from_fields(fields)
16
+
17
+ make_request(url: url, params: params)
18
+ end
19
+
20
+ # Returns a variety of information about one or more Users specified by the requested IDs.
21
+ # @param [Array<String>] :ids the collection of requested User IDs
22
+ # @param [Hash] :fields a hash for fields to include in the response payload;
23
+ #
24
+ # e.g.: { user: %w[id name username] }
25
+ # @return [Array<Hash>] of user objects with the requested user fields
26
+ def get_users(ids:, fields: DEFAULT_FIELDS)
27
+ url = 'https://api.twitter.com/labs/2/users'
28
+ params = ParamsService.from_fields(fields)
29
+ params.merge!({ ids: ids.join(',') })
30
+
31
+ make_request(url: url, params: params, is_collection: true)
32
+ end
33
+
34
+ # Returns a variety of information about one or more Users specified by the requested usernames.
35
+ # @param [Array<String>] :usernames the collection of requested Usernames
36
+ # @param [Hash] :fields a hash for fields to include in the response payload;
37
+ #
38
+ # e.g.: { user: %w[id name username] }
39
+ # @return [Array<Hash>] of user objects with the requested user fields
40
+ def get_users_by_usernames(usernames:, fields: DEFAULT_FIELDS)
41
+ url = 'https://api.twitter.com/labs/2/users/by'
42
+ params = ParamsService.from_fields(fields)
43
+ params.merge!({ usernames: usernames.join(',') })
44
+
45
+ make_request(url: url, params: params, is_collection: true)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,15 @@
1
+ class ParamsService
2
+ # Convert user-passed fields hash to query params
3
+ # @param [Hash] :fields A hash of requested fields; see API Reference for details
4
+ # @return [Hash] A hash of query params for consumption by API client
5
+ # @example
6
+ # input: { tweet: %w[id username], media: ['url'] }
7
+ # output: { 'tweet.fields' => 'id,username', 'media.fields' => 'url }
8
+ def self.from_fields(fields)
9
+ fields.keys.inject({}) do |memo, key|
10
+ memo["#{key}.fields"] = fields[key].join(',')
11
+
12
+ memo
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,3 @@
1
- class TwitterLabsAPI
2
- VERSION = '0.4.0'.freeze
1
+ module TwitterLabsAPI
2
+ VERSION = '0.7.0'.freeze
3
3
  end
@@ -25,6 +25,9 @@ Gem::Specification.new do |spec|
25
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
26
  spec.require_paths = ['lib']
27
27
 
28
+ spec.add_dependency 'activesupport', '~> 6.0'
29
+ spec.add_dependency 'httplog', '~> 1.4'
30
+
28
31
  spec.add_development_dependency 'bundler', '~> 2.0'
29
32
  spec.add_development_dependency 'rake', '~> 13.0'
30
33
  end
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twitter_labs_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - tomholford
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-24 00:00:00.000000000 Z
11
+ date: 2020-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '6.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '6.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: httplog
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.4'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: bundler
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -45,7 +73,9 @@ executables: []
45
73
  extensions: []
46
74
  extra_rdoc_files: []
47
75
  files:
76
+ - ".github/workflows/ruby.yml"
48
77
  - ".gitignore"
78
+ - ".rspec"
49
79
  - CHANGELOG.md
50
80
  - Gemfile
51
81
  - Gemfile.lock
@@ -54,7 +84,13 @@ files:
54
84
  - Rakefile
55
85
  - bin/console
56
86
  - bin/setup
87
+ - bin/specs
57
88
  - lib/twitter_labs_api.rb
89
+ - lib/twitter_labs_api/api_error.rb
90
+ - lib/twitter_labs_api/client.rb
91
+ - lib/twitter_labs_api/resources/tweet.rb
92
+ - lib/twitter_labs_api/resources/user.rb
93
+ - lib/twitter_labs_api/services/params_service.rb
58
94
  - lib/twitter_labs_api/version.rb
59
95
  - twitter-labs-api.gemspec
60
96
  homepage: https://github.com/tomholford/twitter-labs-api