simple_twitter 1.0.0 → 2.1.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: 2736729c95b2f5def88674bda64a6fecd397a5f422c829ab8b301ac4a36f216c
4
- data.tar.gz: 530c600f14041e91c7476b1179bf2069f8d35076175d10089b07db642b13c3fe
3
+ metadata.gz: 9efa656f4b989f1702d73b9fc4dcd1526edeb944fd9de450993cea3a359ac980
4
+ data.tar.gz: eb2027e3aaf434de6014f8ad60775af313c6a3bc88dfca3ac350dd5ad4798c91
5
5
  SHA512:
6
- metadata.gz: e216e514b9bcdfd91e600e07137c409b1bd3d84c4eb045a7988b30a29c4b4dea4bb05f39dddf309295c104a640420bd43a7cf5f7f2702b86ea05f13b2df0acda
7
- data.tar.gz: '036388ae7887f3af5b3b625f15dd6ab7e5241502e1af4257ae1b59ed92b3082e406f9246f623d711a9791af9de851d3f0b5870badde6a4e41e4673df75308a06'
6
+ metadata.gz: d7f681333e86714dbf3aba86319761118c002b914f0d45579b9c35bcb0d0937a4a276ee04137c7cc76cdf66ddd25ab057e431420bd3b95b0fa91e411a96925d0
7
+ data.tar.gz: 7c0159dbc2da88fed921c25887488b5c81406ebcb4793ff10bf76de8d447cb5d8d61f7954c0c44a0b766e3ee1828d68f6ef9c9fa2812eaf709ab5f705d678579
data/.env.example ADDED
@@ -0,0 +1,5 @@
1
+ # TWITTER_OAUTH2_BEARER_TOKEN=
2
+ # TWITTER_OAUTH1_API_KEY=
3
+ # TWITTER_OAUTH1_API_SECRET_KEY=
4
+ # TWITTER_OAUTH1_ACCESS_TOKEN=
5
+ # TWITTER_OAUTH1_ACCESS_TOKEN_SECRET=
@@ -0,0 +1,8 @@
1
+ # c.f. https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
2
+ version: 2
3
+
4
+ updates:
5
+ - package-ecosystem: github-actions
6
+ directory: /
7
+ schedule:
8
+ interval: weekly
@@ -0,0 +1,51 @@
1
+ # Simple workflow for deploying static content to GitHub Pages
2
+ name: Deploy static content to Pages
3
+
4
+ on:
5
+ # Runs on pushes targeting the default branch
6
+ push:
7
+ branches:
8
+ - main
9
+
10
+ # Allows you to run this workflow manually from the Actions tab
11
+ workflow_dispatch:
12
+
13
+ # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
14
+ permissions:
15
+ contents: read
16
+ pages: write
17
+ id-token: write
18
+
19
+ # Allow one concurrent deployment
20
+ concurrency:
21
+ group: "pages"
22
+ cancel-in-progress: true
23
+
24
+ jobs:
25
+ # Single deploy job since we're just deploying
26
+ deploy:
27
+ environment:
28
+ name: github-pages
29
+ url: ${{ steps.deployment.outputs.page_url }}
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - name: Checkout
33
+ uses: actions/checkout@v3
34
+
35
+ - uses: ruby/setup-ruby@v1
36
+ with:
37
+ ruby-version: ruby
38
+ bundler-cache: true
39
+
40
+ - run: bundle exec yard
41
+
42
+ - name: Setup Pages
43
+ uses: actions/configure-pages@v3
44
+ - name: Upload artifact
45
+ uses: actions/upload-pages-artifact@v2
46
+ with:
47
+ # Upload entire repository
48
+ path: './doc'
49
+ - name: Deploy to GitHub Pages
50
+ id: deployment
51
+ uses: actions/deploy-pages@main
@@ -0,0 +1,48 @@
1
+ name: test
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+ types:
9
+ - opened
10
+ - synchronize
11
+ - reopened
12
+ schedule:
13
+ - cron: "0 10 * * 5" # JST 19:00 (Fri)
14
+
15
+ jobs:
16
+ test:
17
+ runs-on: ubuntu-latest
18
+
19
+ strategy:
20
+ fail-fast: false
21
+
22
+ matrix:
23
+ ruby:
24
+ - "2.3"
25
+ - "2.4"
26
+ - "2.5"
27
+ - "2.6"
28
+ - "2.7"
29
+ - "3.0"
30
+ - "3.1"
31
+ - "3.2"
32
+
33
+ steps:
34
+ - uses: actions/checkout@v3
35
+
36
+ - uses: ruby/setup-ruby@v1
37
+ with:
38
+ ruby-version: ${{ matrix.ruby }}
39
+ bundler-cache: true
40
+
41
+ - name: bundle update
42
+ run: |
43
+ set -xe
44
+ bundle config path vendor/bundle
45
+ bundle update --jobs $(nproc) --retry 3
46
+
47
+ - run: bundle exec rspec
48
+ - run: bundle exec yard --fail-on-warning
data/.gitignore CHANGED
@@ -6,3 +6,5 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ Gemfile.lock
10
+ .env
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.yardopts ADDED
@@ -0,0 +1,5 @@
1
+ --markup markdown
2
+ --hide-void-return
3
+ -
4
+ CHANGELOG.md
5
+ LICENSE.txt
data/CHANGELOG.md CHANGED
@@ -1,3 +1,125 @@
1
+ ## Unreleased
2
+ https://github.com/yhara/simple_twitter/compare/v2.1.0...main
3
+
4
+ ## v2.1.0 (2023-07-22)
5
+ https://github.com/yhara/simple_twitter/compare/v2.0.0...v2.1.0
6
+
7
+ * Support media uploading
8
+ * https://github.com/yhara/simple_twitter/pull/26
9
+ * Add User-Agent
10
+ * https://github.com/yhara/simple_twitter/pull/27
11
+
12
+ ## v2.0.0 (2023-07-17)
13
+ https://github.com/yhara/simple_twitter/compare/v1.0.0...v2.0.0
14
+
15
+ ### :bomb: [BREAKING CHANGE] positional args to keywords args
16
+ Since v2.0, the positional arguments of the following methods are now keyword arguments.
17
+
18
+ | v1.0 | v2.0+ |
19
+ | ---------------------------------------------------- | ------------------------------------------------------------- |
20
+ | `SimpleTwitter::Client#get(url, params = {})` | `SimpleTwitter::Client#get(url, params: {}, json: {})` |
21
+ | `SimpleTwitter::Client#get_raw(url, params = {})` | `SimpleTwitter::Client#get_raw(url, params: {}, json: {})` |
22
+ | `SimpleTwitter::Client#post(url, params = {})` | `SimpleTwitter::Client#post(url, params: {}, json: {})` |
23
+ | `SimpleTwitter::Client#post_raw(url, params = {})` | `SimpleTwitter::Client#post_raw(url, params: {}, json: {})` |
24
+ | `SimpleTwitter::Client#put(url, params = {})` | `SimpleTwitter::Client#put(url, params: {}, json: {})` |
25
+ | `SimpleTwitter::Client#put_raw(url, params = {})` | `SimpleTwitter::Client#put_raw(url, params: {}, json: {})` |
26
+ | `SimpleTwitter::Client#delete(url, params = {})` | `SimpleTwitter::Client#delete(url, params: {}, json: {})` |
27
+ | `SimpleTwitter::Client#delete_raw(url, params = {})` | `SimpleTwitter::Client#delete_raw(url, params: {}, json: {})` |
28
+
29
+ Please modify as follows when you upgrade from v1.0 :pray:
30
+
31
+ Before (v1.0)
32
+
33
+ ```ruby
34
+ client.get("https://api.twitter.com/2/tweets", ids: "1302127884039909376,1369885448319889409")
35
+ ```
36
+
37
+ After (v2.0+)
38
+
39
+ ```ruby
40
+ client.get("https://api.twitter.com/2/tweets", params: { ids: "1302127884039909376,1369885448319889409" })
41
+ ```
42
+
43
+ If only 1 argument was used (e.g. `client.get("https://api.twitter.com/2/users/me")`), no modification is required.
44
+
45
+ See more.
46
+
47
+ * https://github.com/yhara/simple_twitter/pull/3
48
+ * https://github.com/yhara/simple_twitter/pull/19
49
+
50
+ ### :bomb: [BREAKING CHANGE] raise Error when Twitter API returned error
51
+ Until v1.0, even if the Twitter API returns an error, Ruby does not throw an error, so it is considered a normal exit.
52
+
53
+ This is confusing, so when the API returns an error, Ruby also raises an error.
54
+
55
+ Before (v1.0)
56
+
57
+ ```ruby
58
+ client = SimpleTwitter::Client.new(bearer_token: "dummy")
59
+ client.get("https://api.twitter.com/2/users/me")
60
+ #=>
61
+ {:title=>"Unsupported Authentication",
62
+ :detail=>
63
+ "Authenticating with OAuth 2.0 Application-Only is forbidden for this endpoint. Supported authentication types are [OAuth 1.0a User Context, OAuth 2.0 User Context].",
64
+ :type=>"https://api.twitter.com/2/problems/unsupported-authentication",
65
+ :status=>403}
66
+ ```
67
+
68
+ After (v2.0+)
69
+
70
+ ```ruby
71
+ client = SimpleTwitter::Client.new(bearer_token: "dummy")
72
+ client.get("https://api.twitter.com/2/users/me")
73
+ /path/to/simple_twitter/lib/simple_twitter.rb:96:in `parse_response': Unsupported Authentication (status 403) (SimpleTwitter::ClientError)
74
+ from (eval):6:in `get'
75
+ from (irb):2:in `<main>'
76
+ from ./bin/console:15:in `<main>'
77
+ ```
78
+
79
+ Detailed error details can be obtained as follows
80
+
81
+ ```ruby
82
+ begin
83
+ client = SimpleTwitter::Client.new(bearer_token: "invalid_bearer_token")
84
+ client.get("https://api.twitter.com/2/users/me")
85
+ rescue SimpleTwitter::Error => error
86
+ error.raw_response.class
87
+ #=> HTTP::Response
88
+
89
+ error.raw_response.code
90
+ #=> 403
91
+
92
+ error.body[:title]
93
+ # => "Unsupported Authentication"
94
+ end
95
+ ```
96
+
97
+ See more.
98
+
99
+ * https://github.com/yhara/simple_twitter/pull/2
100
+ * https://github.com/yhara/simple_twitter/pull/15
101
+
102
+ ### Features
103
+ - Enabled rubygems_mfa_required
104
+ - https://github.com/yhara/simple_twitter/pull/9
105
+ - Add changelog_uri to gemspec
106
+ - https://github.com/yhara/simple_twitter/pull/10
107
+ - Write YARD comment and publish to Pages
108
+ - https://github.com/yhara/simple_twitter/pull/13
109
+ - Add documentation_uri to gemspec metadata
110
+ - https://github.com/yhara/simple_twitter/pull/16
111
+
112
+ ### Others
113
+ - Add @sue445 as an author
114
+ - https://github.com/yhara/simple_twitter/pull/6
115
+ - Add tests and CI
116
+ - https://github.com/yhara/simple_twitter/pull/7
117
+ - https://github.com/yhara/simple_twitter/pull/12
118
+ - Tweak doc
119
+ - https://github.com/yhara/simple_twitter/pull/17
120
+ - https://github.com/yhara/simple_twitter/pull/18
121
+ - https://github.com/yhara/simple_twitter/pull/20
122
+
1
123
  ## v1.0.0 (2021-03-28)
2
124
 
3
125
  - initial release
data/README.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  Dead simple Twitter API client. Supports both v1 and v2
4
4
 
5
+ [![Gem Version](https://badge.fury.io/rb/simple_twitter.svg)](https://badge.fury.io/rb/simple_twitter)
6
+ [![test](https://github.com/yhara/simple_twitter/actions/workflows/test.yml/badge.svg)](https://github.com/yhara/simple_twitter/actions/workflows/test.yml)
7
+
5
8
  ## Installation
6
9
 
7
10
  Add this line to your application's Gemfile:
@@ -25,7 +28,7 @@ require 'simple_twitter'
25
28
 
26
29
  client = SimpleTwitter::Client.new(bearer_token: "...")
27
30
  pp client.get("https://api.twitter.com/2/tweets",
28
- ids: "1302127884039909376,1369885448319889409")
31
+ params: { ids: "1302127884039909376,1369885448319889409" })
29
32
  ```
30
33
 
31
34
  Result:
@@ -55,11 +58,67 @@ client = SimpleTwitter::Client.new(
55
58
  access_token_secret: config[:access_token_secret],
56
59
  )
57
60
  pp client.post("https://api.twitter.com/1.1/statuses/update.json",
58
- status: "Test.")
61
+ params: { status: "Test." })
59
62
  ```
60
63
 
61
64
  You can get the access_token and access_token_secret for your own at the Twitter Developer Portal. For other users, you need to get them via OAuth (out of scope of this gem.)
62
65
 
66
+ ### Post with JSON body
67
+ Since Twitter API v2, POST must be sent as JSON body
68
+
69
+ e.g.https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets
70
+
71
+ Send using the `json` argument.
72
+
73
+ e.g.
74
+
75
+ ```ruby
76
+ client = SimpleTwitter::Client.new(bearer_token: ENV["ACCESS_TOKEN"])
77
+ client.post("https://api.twitter.com/2/tweets", json: { text: "Hello twitter!" })
78
+ ```
79
+
80
+ ### Upload media
81
+ If you want to tweet with an image, you need to do the following steps
82
+
83
+ 1. Upload image as media
84
+ * c.f. https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-upload
85
+ 2. Tweet with media
86
+ * c.f. https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets
87
+
88
+ e.g.
89
+
90
+ ```ruby
91
+ config = (load from yaml or something)
92
+ client = SimpleTwitter::Client.new(
93
+ api_key: config[:api_key],
94
+ api_secret_key: config[:api_secret_key],
95
+ access_token: config[:access_token],
96
+ access_token_secret: config[:access_token_secret],
97
+ )
98
+
99
+ # Upload image as media
100
+ media = client.post(
101
+ "https://upload.twitter.com/1.1/media/upload.json",
102
+ form: {
103
+ media: HTTP::FormData::File.new("/path/to/image.png")
104
+ }
105
+ )
106
+ # =>
107
+ # {:media_id=>12345678901234567890,
108
+ # :media_id_string=>"12345678901234567890",
109
+ # :size=>60628,
110
+ # :expires_after_secs=>86400,
111
+ # :image=>{:image_type=>"image/png", :w=>400, :h=>400}}
112
+
113
+ # Tweet with media
114
+ client.post("https://api.twitter.com/2/tweets",
115
+ json: {
116
+ text: "Test tweet with image",
117
+ media: { media_ids: [media[:media_id_string]] },
118
+ }
119
+ )
120
+ ```
121
+
63
122
  ### Advanced
64
123
 
65
124
  If you want the raw json string or use streaming API, use `get_raw`, `post_raw`, etc. which returns `HTTP::Response` of the [http gem](https://github.com/httprb/http).
@@ -77,16 +136,42 @@ end
77
136
  Some API parameters has `.` in its name (eg. `tweet.fields`.) Did you know that in Ruby you can include `.` in a hash key if quoted? :-)
78
137
 
79
138
  ```rb
80
- tweets = @client.get("https://api.twitter.com/2/users/#{id}/tweets", {
139
+ tweets = @client.get("https://api.twitter.com/2/users/#{id}/tweets", params: {
81
140
  expansions: "author_id",
82
141
  max_results: 100,
83
142
  "tweet.fields": "author_id,created_at,referenced_tweets,text",
84
143
  })
85
144
  ```
86
145
 
146
+ ### Detailed error details
147
+ If an error is returned from the API, you may need more information.
148
+
149
+ In such cases, you can retrieve it as follows.
150
+
151
+ ```ruby
152
+ begin
153
+ client = SimpleTwitter::Client.new(bearer_token: "invalid_bearer_token")
154
+ client.get("https://api.twitter.com/2/users/me")
155
+ rescue SimpleTwitter::Error => error
156
+ error.raw_response.class
157
+ #=> HTTP::Response
158
+
159
+ error.raw_response.code
160
+ #=> 403
161
+
162
+ error.body[:title]
163
+ # => "Unsupported Authentication"
164
+ end
165
+ ```
166
+
167
+ See more. [SimpleTwitter::Error](https://yhara.github.io/simple_twitter/SimpleTwitter/Error.html)
168
+
169
+ ## API Reference
170
+ See https://yhara.github.io/simple_twitter/
171
+
87
172
  ## Contributing
88
173
 
89
- Bug reports and pull requests are welcome on GitHub at https://github.com/naclyhara/simple_twitter.
174
+ Bug reports and pull requests are welcome on GitHub at https://github.com/yhara/simple_twitter.
90
175
 
91
176
  ## License
92
177
 
data/bin/console CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  require "bundler/setup"
5
5
  require "simple_twitter"
6
+ require "dotenv/load"
6
7
 
7
8
  # You can add fixtures and/or initialization code here to make experimenting
8
9
  # with your gem easier. You can also use a different console, if you like.
@@ -11,5 +12,13 @@ require "simple_twitter"
11
12
  # require "pry"
12
13
  # Pry.start
13
14
 
15
+ @client = SimpleTwitter::Client.new(
16
+ bearer_token: ENV["TWITTER_OAUTH2_BEARER_TOKEN"],
17
+ api_key: ENV["TWITTER_OAUTH1_API_KEY"],
18
+ api_secret_key: ENV["TWITTER_OAUTH1_API_SECRET_KEY"],
19
+ access_token: ENV["TWITTER_OAUTH1_ACCESS_TOKEN"],
20
+ access_token_secret: ENV["TWITTER_OAUTH1_ACCESS_TOKEN_SECRET"],
21
+ )
22
+
14
23
  require "irb"
15
24
  IRB.start(__FILE__)
@@ -0,0 +1,165 @@
1
+ module SimpleTwitter
2
+ # Twitter API Client
3
+ class Client
4
+ # @param bearer_token [String] This requires for OAuth 2
5
+ # @param api_key [String] This requires for OAuth 1.0a
6
+ # @param api_secret_key [String] This requires for OAuth 1.0a
7
+ # @param access_token [String] This requires for OAuth 1.0a
8
+ # @param access_token_secret [String] This requires for OAuth 1.0a
9
+ def initialize(bearer_token: nil,
10
+ api_key: nil,
11
+ api_secret_key: nil,
12
+ access_token: nil,
13
+ access_token_secret: nil)
14
+ if bearer_token
15
+ @bearer_token = bearer_token
16
+ else
17
+ @oauth_params = {
18
+ consumer_key: api_key,
19
+ consumer_secret: api_secret_key,
20
+ token: access_token,
21
+ token_secret: access_token_secret,
22
+ }
23
+ end
24
+ end
25
+
26
+ # @!method get(url, params: {}, json: {}, form: {})
27
+ # Call Twitter API with GET method
28
+ # @param url [String]
29
+ # @param params [Hash] Send this arg as a query string. (e.g. `?name1=value1&name2=value2`)
30
+ # @param json [Hash] Send this arg as JSON request body with `Content-Type: application/json` header
31
+ # @param form [Hash] Send this arg as form-data request body with `Content-Type: multipart/form-data` header
32
+ # @return [Hash] parsed json data
33
+ # @raise [SimpleTwitter::ClientError] Twitter API returned 4xx error
34
+ # @raise [SimpleTwitter::ServerError] Twitter API returned 5xx error
35
+
36
+ # @!method get_raw(url, params: {}, json: {}, form: {})
37
+ # Call Twitter API with GET method
38
+ # @param url [String]
39
+ # @param params [Hash] Send this arg as a query string. (e.g. `?name1=value1&name2=value2`)
40
+ # @param json [Hash] Send this arg as JSON request body with `Content-Type: application/json` header
41
+ # @param form [Hash] Send this arg as form-data request body with `Content-Type: multipart/form-data` header
42
+ # @return [HTTP::Response]
43
+
44
+ # @!method post(url, params: {}, json: {}, form: {})
45
+ # Call Twitter API with POST method
46
+ # @param url [String]
47
+ # @param params [Hash] Send this arg as a query string. (e.g. `?name1=value1&name2=value2`)
48
+ # @param json [Hash] Send this arg as JSON request body with `Content-Type: application/json` header
49
+ # @param form [Hash] Send this arg as form-data request body with `Content-Type: multipart/form-data` header
50
+ # @return [Hash] parsed json data
51
+ # @raise [SimpleTwitter::ClientError] Twitter API returned 4xx error
52
+ # @raise [SimpleTwitter::ServerError] Twitter API returned 5xx error
53
+
54
+ # @!method post_raw(url, params: {}, json: {}, form: {})
55
+ # Call Twitter API with POST method
56
+ # @param url [String]
57
+ # @param params [Hash] Send this arg as a query string. (e.g. `?name1=value1&name2=value2`)
58
+ # @param json [Hash] Send this arg as JSON request body with `Content-Type: application/json` header
59
+ # @param form [Hash] Send this arg as form-data request body with `Content-Type: multipart/form-data` header
60
+ # @return [HTTP::Response]
61
+
62
+ # @!method put(url, params: {}, json: {}, form: {})
63
+ # Call Twitter API with PUT method
64
+ # @param url [String]
65
+ # @param params [Hash] Send this arg as a query string. (e.g. `?name1=value1&name2=value2`)
66
+ # @param json [Hash] Send this arg as JSON request body with `Content-Type: application/json` header
67
+ # @param form [Hash] Send this arg as form-data request body with `Content-Type: multipart/form-data` header
68
+ # @return [Hash] parsed json data
69
+ # @raise [SimpleTwitter::ClientError] Twitter API returned 4xx error
70
+ # @raise [SimpleTwitter::ServerError] Twitter API returned 5xx error
71
+
72
+ # @!method put_raw(url, params: {}, json: {}, form: {})
73
+ # Call Twitter API with PUT method
74
+ # @param url [String]
75
+ # @param params [Hash] Send this arg as a query string. (e.g. `?name1=value1&name2=value2`)
76
+ # @param json [Hash] Send this arg as JSON request body with `Content-Type: application/json` header
77
+ # @param form [Hash] Send this arg as form-data request body with `Content-Type: multipart/form-data` header
78
+ # @return [HTTP::Response]
79
+
80
+ # @!method delete(url, params: {}, json: {}, form: {})
81
+ # Call Twitter API with DELETE method
82
+ # @param url [String]
83
+ # @param params [Hash] Send this arg as a query string. (e.g. `?name1=value1&name2=value2`)
84
+ # @param json [Hash] Send this arg as JSON request body with `Content-Type: application/json` header
85
+ # @param form [Hash] Send this arg as form-data request body with `Content-Type: multipart/form-data` header
86
+ # @return [Hash] parsed json data
87
+ # @raise [SimpleTwitter::ClientError] Twitter API returned 4xx error
88
+ # @raise [SimpleTwitter::ServerError] Twitter API returned 5xx error
89
+
90
+ # @!method delete_raw(url, params: {}, json: {}, form: {})
91
+ # Call Twitter API with DELETE method
92
+ # @param url [String]
93
+ # @param params [Hash] Send this arg as a query string. (e.g. `?name1=value1&name2=value2`)
94
+ # @param json [Hash] Send this arg as JSON request body with `Content-Type: application/json` header
95
+ # @param form [Hash] Send this arg as form-data request body with `Content-Type: multipart/form-data` header
96
+ # @return [HTTP::Response]
97
+
98
+ %i[get post put delete].each do |m|
99
+ class_eval <<~EOD
100
+ def #{m}(url, params: {}, json: {}, form: {})
101
+ res = #{m}_raw(url, params: params, json: json, form: form)
102
+ parse_response(res)
103
+ end
104
+
105
+ def #{m}_raw(url, params: {}, json: {}, form: {})
106
+ args = create_http_args(params: params, json: json, form: form)
107
+ http(:#{m}, url, params).#{m}(url, args)
108
+ end
109
+ EOD
110
+ end
111
+
112
+ private
113
+
114
+ # @param params [Hash] Send this arg as a query string. (e.g. `?name1=value1&name2=value2`)
115
+ # @param json [Hash] Send this arg as JSON request body with `Content-Type: application/json` header
116
+ # @param form [Hash] Send this arg as form-data request body with `Content-Type: multipart/form-data` header
117
+ # @return [Hash<Symbol, Object>]
118
+ def create_http_args(params:, json:, form:)
119
+ args = {
120
+ params: params,
121
+ headers: {
122
+ "User-Agent" => "simple_twitter v#{SimpleTwitter::VERSION} (https://github.com/yhara/simple_twitter)",
123
+ },
124
+ }
125
+ args[:json] = json unless json.empty?
126
+ args[:form] = form unless form.empty?
127
+ args
128
+ end
129
+
130
+ # @param method [Symbol]
131
+ # @param url [String]
132
+ # @param params [Hash<Symbol, String>]
133
+ # @return [HTTP::Client]
134
+ def http(method, url, params)
135
+ HTTP.auth(auth_header(method, url, params))
136
+ end
137
+
138
+ # @param method [Symbol]
139
+ # @param url [String]
140
+ # @param params [Hash<Symbol, String>]
141
+ # @return [String]
142
+ def auth_header(method, url, params)
143
+ if @bearer_token
144
+ "Bearer #{@bearer_token}"
145
+ else
146
+ SimpleOAuth::Header.new(method, url, params, @oauth_params).to_s
147
+ end
148
+ end
149
+
150
+ # @param res [HTTP::Response]
151
+ # @return [Hash] parsed json data
152
+ # @raise [SimpleTwitter::ClientError] Twitter API returned 4xx error
153
+ # @raise [SimpleTwitter::ServerError] Twitter API returned 5xx error
154
+ def parse_response(res)
155
+ case res.code.to_i / 100
156
+ when 4
157
+ raise ClientError, res
158
+ when 5
159
+ raise ServerError, res
160
+ end
161
+
162
+ JSON.parse(res.to_s, symbolize_names: true)
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,5 @@
1
+ module SimpleTwitter
2
+ # Twitter API 4xx error
3
+ class ClientError < Error
4
+ end
5
+ end
@@ -0,0 +1,29 @@
1
+ module SimpleTwitter
2
+ # Error base class
3
+ class Error < StandardError
4
+ # @!attribute [r] raw_response
5
+ # @return [HTTP::Response] raw error response
6
+ attr_reader :raw_response
7
+
8
+ # @!attribute [r] body
9
+ # @return [Hash<Symbol, String>] error response body
10
+ attr_reader :body
11
+
12
+ # @param raw_response [HTTP::Response] raw error response from Twitter API
13
+ def initialize(raw_response)
14
+ @raw_response = raw_response
15
+
16
+ begin
17
+ @body = JSON.parse(raw_response.to_s, symbolize_names: true)
18
+
19
+ title = @body[:title] || "Unknown error"
20
+ title << " (status #{raw_response.code})"
21
+
22
+ super(title)
23
+ rescue JSON::ParserError => e
24
+ # Twitter doesn't returns json
25
+ super("Unknown error (status #{raw_response.code})")
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,5 @@
1
+ module SimpleTwitter
2
+ # Twitter API 5xx error
3
+ class ServerError < Error
4
+ end
5
+ end
@@ -1,3 +1,3 @@
1
1
  module SimpleTwitter
2
- VERSION = "1.0.0"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -1,59 +1,11 @@
1
1
  require 'http'
2
2
  require 'simple_oauth'
3
3
 
4
- module SimpleTwitter
5
- class Client
6
- def initialize(bearer_token: nil,
7
- api_key: nil,
8
- api_secret_key: nil,
9
- access_token: nil,
10
- access_token_secret: nil)
11
- if bearer_token
12
- @bearer_token = bearer_token
13
- else
14
- @oauth_params = {
15
- consumer_key: api_key,
16
- consumer_secret: api_secret_key,
17
- token: access_token,
18
- token_secret: access_token_secret,
19
- }
20
- end
21
- end
22
-
23
- %i[get post put delete].each do |m|
24
- class_eval <<~EOD
25
- # @return [Object] parsed json data
26
- def #{m}(url, params={})
27
- JSON.parse(#{m}_raw(url, params).to_s, symbolize_names: true)
28
- end
29
-
30
- # @return [HTTP::Response]
31
- def #{m}_raw(url, params={})
32
- http(:#{m}, url, params).#{m}(url, params: params)
33
- end
34
- EOD
35
- end
4
+ require_relative "simple_twitter/version"
36
5
 
37
- private
38
-
39
- # @param method [Symbol]
40
- # @param url [String]
41
- # @param params [Hash<Symbol, String>]
42
- # @return [HTTP::Request]
43
- def http(method, url, params)
44
- HTTP.auth(auth_header(method, url, params))
45
- end
46
-
47
- # @param method [Symbol]
48
- # @param url [String]
49
- # @param params [Hash<Symbol, String>]
50
- # @return [String]
51
- def auth_header(method, url, params)
52
- if @bearer_token
53
- "Bearer #{@bearer_token}"
54
- else
55
- SimpleOAuth::Header.new(method, url, params, @oauth_params).to_s
56
- end
57
- end
58
- end
6
+ module SimpleTwitter
7
+ autoload :Client, "simple_twitter/client"
8
+ autoload :ClientError, "simple_twitter/client_error"
9
+ autoload :Error, "simple_twitter/error"
10
+ autoload :ServerError, "simple_twitter/server_error"
59
11
  end
@@ -3,8 +3,8 @@ require_relative "lib/simple_twitter/version"
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "simple_twitter"
5
5
  spec.version = SimpleTwitter::VERSION
6
- spec.authors = ["Yutaka HARA"]
7
- spec.email = ["yutaka.hara+github@gmail.com"]
6
+ spec.authors = ["Yutaka HARA", "sue445"]
7
+ spec.email = ["yutaka.hara+github@gmail.com", "sue445fukuoka@gmail.com"]
8
8
 
9
9
  spec.summary = "Dead simple client for Twitter API v1/v2"
10
10
  spec.description = "Dead simple client for Twitter API (supports both v1 and v2)"
@@ -14,7 +14,9 @@ Gem::Specification.new do |spec|
14
14
 
15
15
  spec.metadata["homepage_uri"] = spec.homepage
16
16
  spec.metadata["source_code_uri"] = spec.homepage
17
- #spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
17
+ spec.metadata["changelog_uri"] = spec.homepage + "/blob/main/CHANGELOG.md"
18
+ spec.metadata["documentation_uri"] = "https://yhara.github.io/simple_twitter/"
19
+ spec.metadata["rubygems_mfa_required"] = "true"
18
20
 
19
21
  # Specify which files should be added to the gem when it is released.
20
22
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -25,6 +27,12 @@ Gem::Specification.new do |spec|
25
27
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
26
28
  spec.require_paths = ["lib"]
27
29
 
28
- spec.add_dependency "http", "~> 4"
29
- spec.add_dependency "simple_oauth", "~> 0.3.1"
30
+ spec.add_dependency "http", ">= 4"
31
+ spec.add_dependency "simple_oauth", ">= 0.3.1"
32
+
33
+ spec.add_development_dependency "dotenv"
34
+ spec.add_development_dependency "rspec"
35
+ spec.add_development_dependency "rspec-its"
36
+ spec.add_development_dependency "webmock"
37
+ spec.add_development_dependency "yard"
30
38
  end
metadata CHANGED
@@ -1,51 +1,129 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_twitter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yutaka HARA
8
+ - sue445
8
9
  autorequire:
9
10
  bindir: exe
10
11
  cert_chain: []
11
- date: 2021-03-28 00:00:00.000000000 Z
12
+ date: 2023-07-21 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: http
15
16
  requirement: !ruby/object:Gem::Requirement
16
17
  requirements:
17
- - - "~>"
18
+ - - ">="
18
19
  - !ruby/object:Gem::Version
19
20
  version: '4'
20
21
  type: :runtime
21
22
  prerelease: false
22
23
  version_requirements: !ruby/object:Gem::Requirement
23
24
  requirements:
24
- - - "~>"
25
+ - - ">="
25
26
  - !ruby/object:Gem::Version
26
27
  version: '4'
27
28
  - !ruby/object:Gem::Dependency
28
29
  name: simple_oauth
29
30
  requirement: !ruby/object:Gem::Requirement
30
31
  requirements:
31
- - - "~>"
32
+ - - ">="
32
33
  - !ruby/object:Gem::Version
33
34
  version: 0.3.1
34
35
  type: :runtime
35
36
  prerelease: false
36
37
  version_requirements: !ruby/object:Gem::Requirement
37
38
  requirements:
38
- - - "~>"
39
+ - - ">="
39
40
  - !ruby/object:Gem::Version
40
41
  version: 0.3.1
42
+ - !ruby/object:Gem::Dependency
43
+ name: dotenv
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rspec-its
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: webmock
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: yard
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
41
112
  description: Dead simple client for Twitter API (supports both v1 and v2)
42
113
  email:
43
114
  - yutaka.hara+github@gmail.com
115
+ - sue445fukuoka@gmail.com
44
116
  executables: []
45
117
  extensions: []
46
118
  extra_rdoc_files: []
47
119
  files:
120
+ - ".env.example"
121
+ - ".github/dependabot.yml"
122
+ - ".github/workflows/pages.yml"
123
+ - ".github/workflows/test.yml"
48
124
  - ".gitignore"
125
+ - ".rspec"
126
+ - ".yardopts"
49
127
  - CHANGELOG.md
50
128
  - Gemfile
51
129
  - LICENSE.txt
@@ -54,6 +132,10 @@ files:
54
132
  - bin/console
55
133
  - bin/setup
56
134
  - lib/simple_twitter.rb
135
+ - lib/simple_twitter/client.rb
136
+ - lib/simple_twitter/client_error.rb
137
+ - lib/simple_twitter/error.rb
138
+ - lib/simple_twitter/server_error.rb
57
139
  - lib/simple_twitter/version.rb
58
140
  - simple_twitter.gemspec
59
141
  homepage: https://github.com/yhara/simple_twitter
@@ -62,6 +144,9 @@ licenses:
62
144
  metadata:
63
145
  homepage_uri: https://github.com/yhara/simple_twitter
64
146
  source_code_uri: https://github.com/yhara/simple_twitter
147
+ changelog_uri: https://github.com/yhara/simple_twitter/blob/main/CHANGELOG.md
148
+ documentation_uri: https://yhara.github.io/simple_twitter/
149
+ rubygems_mfa_required: 'true'
65
150
  post_install_message:
66
151
  rdoc_options: []
67
152
  require_paths:
@@ -77,7 +162,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
77
162
  - !ruby/object:Gem::Version
78
163
  version: '0'
79
164
  requirements: []
80
- rubygems_version: 3.2.3
165
+ rubygems_version: 3.4.10
81
166
  signing_key:
82
167
  specification_version: 4
83
168
  summary: Dead simple client for Twitter API v1/v2