twitter_labs_api 0.4.0 → 0.5.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 +4 -4
- data/.github/workflows/ruby.yml +32 -0
- data/.rspec +1 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +10 -4
- data/Gemfile.lock +91 -4
- data/README.md +13 -7
- data/bin/specs +1 -0
- data/lib/twitter_labs_api.rb +5 -111
- data/lib/twitter_labs_api/api_error.rb +13 -0
- data/lib/twitter_labs_api/client.rb +62 -0
- data/lib/twitter_labs_api/resources/tweet.rb +30 -0
- data/lib/twitter_labs_api/resources/user.rb +42 -0
- data/lib/twitter_labs_api/version.rb +2 -2
- data/twitter-labs-api.gemspec +3 -0
- metadata +37 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f31f636cbf46ed53a3d35e61c3376b9f47184220db4b23277f4f7c504f4be251
|
|
4
|
+
data.tar.gz: be3ae4940e263fe6bf33661686072c62c807236f9c2814488661efc8da8799a8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6062719f695c9979a327d94396795df7365559e92598fe08e727d2e87dc2e4a987a4f6bf689954cd2efc2b6c20f0ad5ae3003f651e0e45fc0caea12f46a57688
|
|
7
|
+
data.tar.gz: 7c1616a9f97582a2dda4061f2a0c540b7967d4d525c0bd344141643723450d91a4208357d919b8acf4d0d89a17d2046e0f6fba75a5c3eb6e9a10d9f6caa4df31
|
|
@@ -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
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
# 0.5.0 - 27 July 2020
|
|
2
|
+
|
|
3
|
+
- Refactor structure to prepare for adding additional API endpoints
|
|
4
|
+
- Add `get_users_by_username`
|
|
5
|
+
- Add some test coverage
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# 0.4.0 - 24 July 2020
|
|
9
|
+
|
|
10
|
+
- 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.
|
|
11
|
+
|
|
12
|
+
|
|
1
13
|
# 0.3.0 - 28 April 2020
|
|
2
14
|
|
|
3
15
|
- Fix: namespace of error class
|
data/Gemfile
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
source 'https://rubygems.org'
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
6
|
-
gem 'httplog'
|
|
7
|
-
gem 'pry'
|
|
13
|
+
gemspec
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
twitter_labs_api (0.
|
|
4
|
+
twitter_labs_api (0.5.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
28
|
concurrent-ruby (1.1.6)
|
|
17
|
-
|
|
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
|
-
|
|
123
|
+
amazing_print
|
|
40
124
|
bundler (~> 2.0)
|
|
41
125
|
httplog
|
|
126
|
+
irbtools
|
|
42
127
|
pry
|
|
43
|
-
rake
|
|
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
|
@@ -19,7 +19,7 @@ gem install twitter_labs_api
|
|
|
19
19
|
|
|
20
20
|
#### Getting a Tweet by ID
|
|
21
21
|
```ruby
|
|
22
|
-
|
|
22
|
+
require `twitter_labs_api`
|
|
23
23
|
|
|
24
24
|
api = TwitterLabsAPI.new(bearer_token: 'YOUR-BEARER-TOKEN')
|
|
25
25
|
|
|
@@ -42,7 +42,7 @@ api.get_tweet(id: '1235508591232090112', tweet_fields: my_fields)
|
|
|
42
42
|
|
|
43
43
|
#### API Errors
|
|
44
44
|
|
|
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:
|
|
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
46
|
|
|
47
47
|
```ruby
|
|
48
48
|
def my_twitter_request
|
|
@@ -58,14 +58,20 @@ end
|
|
|
58
58
|
### Status
|
|
59
59
|
Currently, the following endpoints are implemented:
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
- `TwitterLabsAPI#
|
|
64
|
-
- `TwitterLabsAPI#
|
|
61
|
+
#### Tweets
|
|
62
|
+
|
|
63
|
+
- `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`
|
|
64
|
+
- `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`
|
|
65
|
+
|
|
66
|
+
#### Users
|
|
67
|
+
|
|
68
|
+
- `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`
|
|
69
|
+
- `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`
|
|
70
|
+
- `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
71
|
|
|
66
72
|
## Roadmap
|
|
67
73
|
|
|
68
|
-
Since this project is initially driven by my own usage of the API, I will focus on implementing and
|
|
74
|
+
Since this project is initially driven by my own usage of the API, I will focus on implementing and refining 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 :)
|
|
69
75
|
|
|
70
76
|
## Dependencies
|
|
71
77
|
|
data/bin/specs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
bundle exec rspec
|
data/lib/twitter_labs_api.rb
CHANGED
|
@@ -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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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,62 @@
|
|
|
1
|
+
require_relative 'api_error'
|
|
2
|
+
require_relative 'resources/tweet'
|
|
3
|
+
require_relative 'resources/user'
|
|
4
|
+
|
|
5
|
+
module TwitterLabsAPI
|
|
6
|
+
class Client
|
|
7
|
+
include Resources::Tweet
|
|
8
|
+
include Resources::User
|
|
9
|
+
|
|
10
|
+
attr_accessor :bearer_token, :debug, :api_response, :parsed_response
|
|
11
|
+
|
|
12
|
+
def initialize(bearer_token:, debug: false)
|
|
13
|
+
@bearer_token = bearer_token
|
|
14
|
+
@debug = debug
|
|
15
|
+
require 'httplog' if debug
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def make_request(url:, params: {}, is_collection: false)
|
|
21
|
+
uri = URI.parse(url)
|
|
22
|
+
uri.query = URI.encode_www_form(params)
|
|
23
|
+
request = Net::HTTP::Get.new(uri)
|
|
24
|
+
request['Authorization'] = "Bearer #{bearer_token}"
|
|
25
|
+
req_options = { use_ssl: uri.scheme == 'https' }
|
|
26
|
+
|
|
27
|
+
self.api_response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
|
|
28
|
+
http.request(request)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
raise_http_error unless api_response.is_a?(Net::HTTPSuccess)
|
|
32
|
+
|
|
33
|
+
self.parsed_response = JSON.parse(api_response.body)
|
|
34
|
+
|
|
35
|
+
handle_api_error if error_response?
|
|
36
|
+
|
|
37
|
+
is_collection ? handle_collection : handle_single
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def error_response?
|
|
41
|
+
parsed_response.key?('errors')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def handle_single
|
|
45
|
+
parsed_response['data'].with_indifferent_access
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def handle_collection
|
|
49
|
+
parsed_response['data'].map(&:with_indifferent_access)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def raise_http_error
|
|
53
|
+
raise(APIError.new("#{api_response.code} #{api_response.msg}", api_response))
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def handle_api_error
|
|
57
|
+
error = parsed_response['errors'].first
|
|
58
|
+
|
|
59
|
+
raise APIError.new("#{error['title']}: #{error['detail']} #{error['type']}", api_response)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module TwitterLabsAPI
|
|
2
|
+
module Resources
|
|
3
|
+
module Tweet
|
|
4
|
+
DEFAULT_TWEET_FIELDS = %w[id author_id created_at lang public_metrics].freeze
|
|
5
|
+
|
|
6
|
+
# @param [String] :id the ID of the requested Tweet
|
|
7
|
+
# @param [Array<String>] :tweet_fields (["id", "author_id", "created_at", "lang", "public_metrics"]) the list of fields to retrieve for the given tweet
|
|
8
|
+
def get_tweet(id:, tweet_fields: DEFAULT_TWEET_FIELDS)
|
|
9
|
+
url = "https://api.twitter.com/labs/2/tweets/#{id}"
|
|
10
|
+
params = {
|
|
11
|
+
'tweet.fields' => tweet_fields.join(',')
|
|
12
|
+
}.compact
|
|
13
|
+
|
|
14
|
+
make_request(url: url, params: params)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @param [Array<String>] :ids the collection of requested Tweet IDs
|
|
18
|
+
# @param [Array<String>] :tweet_fields (["id", "author_id", "created_at", "lang", "public_metrics"]) the list of fields to retrieve for the given tweet
|
|
19
|
+
def get_tweets(ids:, tweet_fields: DEFAULT_TWEET_FIELDS)
|
|
20
|
+
url = 'https://api.twitter.com/labs/2/tweets'
|
|
21
|
+
params = {
|
|
22
|
+
'ids' => ids.join(','),
|
|
23
|
+
'tweet.fields' => tweet_fields.join(',')
|
|
24
|
+
}.compact
|
|
25
|
+
|
|
26
|
+
make_request(url: url, params: params, is_collection: true)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module TwitterLabsAPI
|
|
2
|
+
module Resources
|
|
3
|
+
module User
|
|
4
|
+
DEFAULT_USER_FIELDS = %w[id name username].freeze
|
|
5
|
+
|
|
6
|
+
# @param [String] :id the ID of the requested User
|
|
7
|
+
# @param [Array<String>] :user_fields (["name", "username"]) the list of fields to retrieve for the given User
|
|
8
|
+
def get_user(id:, user_fields: DEFAULT_USER_FIELDS)
|
|
9
|
+
url = "https://api.twitter.com/labs/2/users/#{id}"
|
|
10
|
+
params = {
|
|
11
|
+
'user.fields' => user_fields.join(',')
|
|
12
|
+
}.compact
|
|
13
|
+
|
|
14
|
+
make_request(url: url, params: params)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @param [Array<String>] :ids the collection of requested User IDs
|
|
18
|
+
# @param [Array<String>] :user_fields (["name", "username"]) the list of fields to retrieve for the given User
|
|
19
|
+
def get_users(ids:, user_fields: DEFAULT_USER_FIELDS)
|
|
20
|
+
url = 'https://api.twitter.com/labs/2/users'
|
|
21
|
+
params = {
|
|
22
|
+
'ids' => ids.join(','),
|
|
23
|
+
'user.fields' => user_fields.join(',')
|
|
24
|
+
}.compact
|
|
25
|
+
|
|
26
|
+
make_request(url: url, params: params, is_collection: true)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @param [Array<String>] :usernames the collection of requested Usernames
|
|
30
|
+
# @param [Array<String>] :user_fields (["name", "username"]) the list of fields to retrieve for the given User
|
|
31
|
+
def get_users_by_usernames(usernames:, user_fields: DEFAULT_USER_FIELDS)
|
|
32
|
+
url = 'https://api.twitter.com/labs/2/users/by'
|
|
33
|
+
params = {
|
|
34
|
+
'usernames' => usernames.join(','),
|
|
35
|
+
'user.fields' => user_fields.join(',')
|
|
36
|
+
}.compact
|
|
37
|
+
|
|
38
|
+
make_request(url: url, params: params, is_collection: true)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
VERSION = '0.
|
|
1
|
+
module TwitterLabsAPI
|
|
2
|
+
VERSION = '0.5.0'.freeze
|
|
3
3
|
end
|
data/twitter-labs-api.gemspec
CHANGED
|
@@ -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
|
+
version: 0.5.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-
|
|
11
|
+
date: 2020-07-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,12 @@ 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
|
|
58
93
|
- lib/twitter_labs_api/version.rb
|
|
59
94
|
- twitter-labs-api.gemspec
|
|
60
95
|
homepage: https://github.com/tomholford/twitter-labs-api
|