twitter_labs_api 0.3.0 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +32 -0
- data/.rspec +1 -0
- data/CHANGELOG.md +22 -0
- data/Gemfile +10 -3
- data/Gemfile.lock +105 -12
- data/README.md +33 -8
- data/bin/specs +1 -0
- data/lib/twitter_labs_api.rb +5 -97
- data/lib/twitter_labs_api/api_error.rb +13 -0
- data/lib/twitter_labs_api/client.rb +72 -0
- data/lib/twitter_labs_api/resources/tweet.rb +57 -0
- data/lib/twitter_labs_api/resources/user.rb +48 -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: 697a03319c55056717774438db0f412e52df2337e52452bfecc0c9f5f00c99f2
|
4
|
+
data.tar.gz: d841c0f5c73763593663180cae40f1528b21037708fbc9b05f0c4fcc89d83720
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4f956e69a646de92cd9c79139bae452091603630da9e6596e004d0a6f084c8be362bb083a01aa2ccb66cb4385dcfdc099d35dd8f2b91c291f9a19b93395f774
|
7
|
+
data.tar.gz: 88bb52e555879a7c003f4006f3d4f10c34bd509dfd083ac06856006a3e2a9d2f3b57dcd1a0e5d5e93df3c15a92bd8b723c0b362a40b0a287c639cfe234b68aa1
|
@@ -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,25 @@
|
|
1
|
+
# 0.5.2 - 28 July 2020
|
2
|
+
|
3
|
+
- Add `search`
|
4
|
+
- Finish `rdoc` coverage
|
5
|
+
|
6
|
+
# 0.5.1 - 28 July 2020
|
7
|
+
|
8
|
+
- Add `User-Agent` request header
|
9
|
+
- Add `hide_reply`
|
10
|
+
|
11
|
+
# 0.5.0 - 27 July 2020
|
12
|
+
|
13
|
+
- Refactor structure to prepare for adding additional API endpoints
|
14
|
+
- Add `get_users_by_username`
|
15
|
+
- Add some test coverage
|
16
|
+
|
17
|
+
|
18
|
+
# 0.4.0 - 24 July 2020
|
19
|
+
|
20
|
+
- 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.
|
21
|
+
|
22
|
+
|
1
23
|
# 0.3.0 - 28 April 2020
|
2
24
|
|
3
25
|
- Fix: namespace of error class
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,41 +1,134 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
twitter_labs_api (0.
|
4
|
+
twitter_labs_api (0.5.2)
|
5
|
+
activesupport (~> 6.0)
|
6
|
+
httplog (~> 1.4)
|
5
7
|
|
6
8
|
GEM
|
7
9
|
remote: https://rubygems.org/
|
8
10
|
specs:
|
9
|
-
activesupport (6.0.
|
11
|
+
activesupport (6.0.3.2)
|
10
12
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
11
13
|
i18n (>= 0.7, < 2)
|
12
14
|
minitest (~> 5.1)
|
13
15
|
tzinfo (~> 1.1)
|
14
|
-
zeitwerk (~> 2.
|
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)
|
27
|
+
coderay (1.1.3)
|
15
28
|
concurrent-ruby (1.1.6)
|
16
|
-
|
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)
|
17
45
|
rack (>= 1.0)
|
18
46
|
rainbow (>= 2.0.0)
|
19
|
-
i18n (1.
|
47
|
+
i18n (1.8.5)
|
20
48
|
concurrent-ruby (~> 1.0)
|
21
|
-
|
22
|
-
|
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)
|
75
|
+
method_source (1.0.0)
|
76
|
+
methodfinder (2.2.1)
|
77
|
+
minitest (5.14.1)
|
78
|
+
ori (0.1.0)
|
79
|
+
os (0.9.6)
|
80
|
+
paint (2.2.0)
|
81
|
+
pry (0.13.1)
|
82
|
+
coderay (~> 1.1)
|
83
|
+
method_source (~> 1.0)
|
84
|
+
public_suffix (4.0.5)
|
85
|
+
rack (2.2.3)
|
23
86
|
rainbow (3.0.0)
|
24
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
|
25
107
|
thread_safe (0.3.6)
|
26
|
-
tzinfo (1.2.
|
108
|
+
tzinfo (1.2.7)
|
27
109
|
thread_safe (~> 0.1)
|
28
|
-
|
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)
|
117
|
+
zeitwerk (2.4.0)
|
29
118
|
|
30
119
|
PLATFORMS
|
31
120
|
ruby
|
32
121
|
|
33
122
|
DEPENDENCIES
|
34
|
-
|
123
|
+
amazing_print
|
35
124
|
bundler (~> 2.0)
|
36
125
|
httplog
|
37
|
-
|
126
|
+
irbtools
|
127
|
+
pry
|
128
|
+
rake
|
129
|
+
rspec
|
38
130
|
twitter_labs_api!
|
131
|
+
webmock
|
39
132
|
|
40
133
|
BUNDLED WITH
|
41
|
-
2.
|
134
|
+
2.1.4
|
data/README.md
CHANGED
@@ -5,9 +5,9 @@ A basic implementation of a Twitter Labs API client as a handy Ruby [gem](https:
|
|
5
5
|
## Usage
|
6
6
|
|
7
7
|
### 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.
|
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. 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
9
|
|
10
|
-
|
10
|
+
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
11
|
|
12
12
|
### Setup
|
13
13
|
|
@@ -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
|
|
@@ -40,17 +40,42 @@ api.get_tweet(id: '1235508591232090112', tweet_fields: my_fields)
|
|
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
41
|
```
|
42
42
|
|
43
|
+
#### API Errors
|
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:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
def my_twitter_request
|
49
|
+
api.get_tweet(id: '1235508591232090112', tweet_fields: my_fields)
|
50
|
+
|
51
|
+
rescue TwitterLabsAPI::APIError => e
|
52
|
+
puts e.msg # 429 Too Many Requests
|
53
|
+
puts e.response # <Net::HTTPTooManyRequests 429 Too Many Requests readbody=true>
|
54
|
+
# do something with the Net::HTTP response...
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
43
58
|
### Status
|
44
59
|
Currently, the following endpoints are implemented:
|
45
60
|
|
46
|
-
|
47
|
-
|
48
|
-
- `TwitterLabsAPI#
|
49
|
-
- `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
|
+
- `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
|
66
|
+
- `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.
|
67
|
+
|
68
|
+
#### Users
|
69
|
+
|
70
|
+
- `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`
|
71
|
+
- `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`
|
72
|
+
- `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`
|
50
73
|
|
51
74
|
## Roadmap
|
52
75
|
|
53
|
-
|
76
|
+
Currently focused on implementing support for all v2 endpoints; if there is enough interest, I will add v1 endpoint support as well.
|
77
|
+
|
78
|
+
And of course, contributions are welcome :)
|
54
79
|
|
55
80
|
## Dependencies
|
56
81
|
|
data/bin/specs
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
bundle exec rspec
|
data/lib/twitter_labs_api.rb
CHANGED
@@ -2,105 +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
|
-
|
15
|
-
def initialize(bearer_token:, debug: false)
|
16
|
-
@bearer_token = bearer_token
|
17
|
-
@debug = debug
|
18
|
-
require 'httplog' if debug
|
19
|
-
end
|
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
|
23
|
-
def get_tweet(id:, tweet_fields: DEFAULT_TWEET_FIELDS)
|
24
|
-
url = "https://api.twitter.com/labs/2/tweets/#{id}"
|
25
|
-
params = {
|
26
|
-
'tweet.fields' => tweet_fields.join(',')
|
27
|
-
}.compact
|
28
|
-
|
29
|
-
make_request(url: url, params: params)
|
30
|
-
end
|
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
|
34
|
-
def get_tweets(ids:, tweet_fields: DEFAULT_TWEET_FIELDS)
|
35
|
-
url = 'https://api.twitter.com/labs/2/tweets'
|
36
|
-
params = {
|
37
|
-
'ids' => ids.join(','),
|
38
|
-
'tweet.fields' => tweet_fields.join(',')
|
39
|
-
}.compact
|
40
|
-
|
41
|
-
make_request(url: url, params: params, is_collection: true)
|
42
|
-
end
|
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
|
46
|
-
def get_user(id:, user_fields: DEFAULT_USER_FIELDS)
|
47
|
-
url = "https://api.twitter.com/labs/2/users/#{id}"
|
48
|
-
params = {
|
49
|
-
'user.fields' => user_fields.join(',')
|
50
|
-
}.compact
|
51
|
-
|
52
|
-
make_request(url: url, params: params)
|
53
|
-
end
|
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
|
57
|
-
def get_users(ids:, user_fields: DEFAULT_USER_FIELDS)
|
58
|
-
url = 'https://api.twitter.com/labs/2/users'
|
59
|
-
params = {
|
60
|
-
'ids' => ids.join(','),
|
61
|
-
'user.fields' => user_fields.join(',')
|
62
|
-
}.compact
|
63
|
-
|
64
|
-
make_request(url: url, params: params, is_collection: true)
|
65
|
-
end
|
66
|
-
|
67
|
-
private
|
68
|
-
|
69
|
-
def make_request(url:, params: {}, is_collection: false)
|
70
|
-
uri = URI.parse(url)
|
71
|
-
uri.query = URI.encode_www_form(params)
|
72
|
-
request = Net::HTTP::Get.new(uri)
|
73
|
-
request['Authorization'] = "Bearer #{bearer_token}"
|
74
|
-
req_options = { use_ssl: uri.scheme == 'https' }
|
75
|
-
|
76
|
-
self.api_response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
|
77
|
-
http.request(request)
|
8
|
+
module TwitterLabsAPI
|
9
|
+
class << self
|
10
|
+
def new(bearer_token:, debug: false)
|
11
|
+
Client.new(bearer_token: bearer_token, debug: debug)
|
78
12
|
end
|
79
|
-
|
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)
|
83
|
-
|
84
|
-
handle_api_error if error_response?
|
85
|
-
|
86
|
-
is_collection ? handle_collection : handle_single
|
87
|
-
end
|
88
|
-
|
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
|
96
|
-
|
97
|
-
def handle_collection
|
98
|
-
parsed_response['data'].map(&:with_indifferent_access)
|
99
|
-
end
|
100
|
-
|
101
|
-
def handle_api_error
|
102
|
-
error = parsed_response['errors'].first
|
103
|
-
|
104
|
-
raise TwitterLabsAPIError, "#{error['title']}: #{error['detail']} #{error['type']}"
|
105
13
|
end
|
106
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,72 @@
|
|
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, method: :get)
|
21
|
+
uri = URI.parse(url)
|
22
|
+
uri.query = URI.encode_www_form(params)
|
23
|
+
request = http_adapter(method).new(uri)
|
24
|
+
request['Authorization'] = "Bearer #{bearer_token}"
|
25
|
+
request['User-Agent'] = "twitter_labs_api gem #{TwitterLabsAPI::VERSION}"
|
26
|
+
req_options = { use_ssl: uri.scheme == 'https' }
|
27
|
+
|
28
|
+
self.api_response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
|
29
|
+
http.request(request)
|
30
|
+
end
|
31
|
+
|
32
|
+
raise_http_error unless api_response.is_a?(Net::HTTPSuccess)
|
33
|
+
|
34
|
+
self.parsed_response = JSON.parse(api_response.body)
|
35
|
+
|
36
|
+
handle_api_error if error_response?
|
37
|
+
|
38
|
+
is_collection ? handle_collection : handle_single
|
39
|
+
end
|
40
|
+
|
41
|
+
def http_adapter(method)
|
42
|
+
case method
|
43
|
+
when :put
|
44
|
+
Net::HTTP::Put
|
45
|
+
else
|
46
|
+
Net::HTTP::Get
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def error_response?
|
51
|
+
parsed_response.key?('errors')
|
52
|
+
end
|
53
|
+
|
54
|
+
def handle_single
|
55
|
+
parsed_response['data'].with_indifferent_access
|
56
|
+
end
|
57
|
+
|
58
|
+
def handle_collection
|
59
|
+
parsed_response['data'].map(&:with_indifferent_access)
|
60
|
+
end
|
61
|
+
|
62
|
+
def raise_http_error
|
63
|
+
raise(APIError.new("#{api_response.code} #{api_response.msg}", api_response))
|
64
|
+
end
|
65
|
+
|
66
|
+
def handle_api_error
|
67
|
+
error = parsed_response['errors'].first
|
68
|
+
|
69
|
+
raise APIError.new("#{error['title']}: #{error['detail']} #{error['type']}", api_response)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,57 @@
|
|
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
|
+
# Returns a variety of information about a single Tweet specified by the requested ID.
|
7
|
+
# @param [String] :id the ID of the requested Tweet
|
8
|
+
# @param [Array<String>] :tweet_fields (["id", "author_id", "created_at", "lang", "public_metrics"]) the list of fields to retrieve for the given tweet
|
9
|
+
# @return Hash an object with requested tweet fields
|
10
|
+
def get_tweet(id:, tweet_fields: DEFAULT_TWEET_FIELDS)
|
11
|
+
url = "https://api.twitter.com/labs/2/tweets/#{id}"
|
12
|
+
params = {
|
13
|
+
'tweet.fields' => tweet_fields.join(',')
|
14
|
+
}.compact
|
15
|
+
|
16
|
+
make_request(url: url, params: params)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns a variety of information about the Tweet specified by the requested ID or list of IDs.
|
20
|
+
# @param [Array<String>] :ids the collection of requested Tweet IDs
|
21
|
+
# @param [Array<String>] :tweet_fields (["id", "author_id", "created_at", "lang", "public_metrics"]) the list of fields to retrieve for the given tweet
|
22
|
+
# @return [Array<Hash>] of tweet objects with the requested tweet fields
|
23
|
+
def get_tweets(ids:, tweet_fields: DEFAULT_TWEET_FIELDS)
|
24
|
+
url = 'https://api.twitter.com/labs/2/tweets'
|
25
|
+
params = {
|
26
|
+
'ids' => ids.join(','),
|
27
|
+
'tweet.fields' => tweet_fields.join(',')
|
28
|
+
}.compact
|
29
|
+
|
30
|
+
make_request(url: url, params: params, is_collection: true)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Hides or unhides a reply to a Tweet.
|
34
|
+
# @param [String] :id the ID of the requested Tweet; must belong to a conversation by the authenticated user
|
35
|
+
# @return boolean indicating the hidden status of the requested tweet
|
36
|
+
def hide_reply(id:)
|
37
|
+
url = "https://api.twitter.com/labs/2/tweets/#{id}/hidden"
|
38
|
+
|
39
|
+
make_request(url: url, method: :put)[:hidden]
|
40
|
+
end
|
41
|
+
|
42
|
+
# The Labs recent search endpoint returns Tweets from the last 7 days that match a search query.
|
43
|
+
# @param [String] :query the search query
|
44
|
+
# @param [Array<String>] :tweet_fields (["id", "author_id", "created_at", "lang", "public_metrics"]) the list of fields to retrieve for the given tweet
|
45
|
+
# @param [Array<String>] :tweet_fields (["id", "author_id", "created_at", "lang", "public_metrics"]) the list of fields to retrieve for the given tweet
|
46
|
+
def search(query:, tweet_fields: DEFAULT_TWEET_FIELDS)
|
47
|
+
url = "https://api.twitter.com/labs/2/tweets/search"
|
48
|
+
params = {
|
49
|
+
'query' => query,
|
50
|
+
'tweet.fields' => tweet_fields.join(',')
|
51
|
+
}.compact
|
52
|
+
|
53
|
+
make_request(url: url, params: params, is_collection: true)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module TwitterLabsAPI
|
2
|
+
module Resources
|
3
|
+
module User
|
4
|
+
DEFAULT_USER_FIELDS = %w[id name username].freeze
|
5
|
+
|
6
|
+
# Returns a variety of information about a single more user specified by the requested ID.
|
7
|
+
# @param [String] :id the ID of the requested User
|
8
|
+
# @param [Array<String>] :user_fields (["name", "username"]) the list of fields to retrieve for the given User
|
9
|
+
# @return Hash an object with requested user fields
|
10
|
+
def get_user(id:, user_fields: DEFAULT_USER_FIELDS)
|
11
|
+
url = "https://api.twitter.com/labs/2/users/#{id}"
|
12
|
+
params = {
|
13
|
+
'user.fields' => user_fields.join(',')
|
14
|
+
}.compact
|
15
|
+
|
16
|
+
make_request(url: url, params: params)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns a variety of information about one or more Users specified by the requested IDs.
|
20
|
+
# @param [Array<String>] :ids the collection of requested User IDs
|
21
|
+
# @param [Array<String>] :user_fields (["name", "username"]) the list of fields to retrieve for the given User
|
22
|
+
# @return [Array<Hash>] of user objects with the requested user fields
|
23
|
+
def get_users(ids:, user_fields: DEFAULT_USER_FIELDS)
|
24
|
+
url = 'https://api.twitter.com/labs/2/users'
|
25
|
+
params = {
|
26
|
+
'ids' => ids.join(','),
|
27
|
+
'user.fields' => user_fields.join(',')
|
28
|
+
}.compact
|
29
|
+
|
30
|
+
make_request(url: url, params: params, is_collection: true)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns a variety of information about one or more Users specified by the requested usernames.
|
34
|
+
# @param [Array<String>] :usernames the collection of requested Usernames
|
35
|
+
# @param [Array<String>] :user_fields (["name", "username"]) the list of fields to retrieve for the given User
|
36
|
+
# @return [Array<Hash>] of user objects with the requested user fields
|
37
|
+
def get_users_by_usernames(usernames:, user_fields: DEFAULT_USER_FIELDS)
|
38
|
+
url = 'https://api.twitter.com/labs/2/users/by'
|
39
|
+
params = {
|
40
|
+
'usernames' => usernames.join(','),
|
41
|
+
'user.fields' => user_fields.join(',')
|
42
|
+
}.compact
|
43
|
+
|
44
|
+
make_request(url: url, params: params, is_collection: true)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = '0.
|
1
|
+
module TwitterLabsAPI
|
2
|
+
VERSION = '0.5.2'.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.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- tomholford
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-28 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
|