instagram_basic_display 0.2.0 → 0.2.2
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/.ruby-version +1 -1
- data/Gemfile +5 -5
- data/Gemfile.lock +61 -47
- data/README.md +201 -10
- data/instagram_basic_display.gemspec +14 -14
- data/lib/instagram_basic_display/auth.rb +39 -1
- data/lib/instagram_basic_display/client.rb +22 -2
- data/lib/instagram_basic_display/configuration.rb +25 -5
- data/lib/instagram_basic_display/profile.rb +55 -2
- data/lib/instagram_basic_display/response.rb +18 -0
- data/lib/instagram_basic_display/version.rb +1 -2
- metadata +15 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 917e8dc235fd078d724ccbd775d6306e5b61411443f3fe64a083e2dc988f89db
|
|
4
|
+
data.tar.gz: 9d842051035ee2852e273d195109570dd953e053116caa99a242d337705fcbf8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 83c536d281626fe977a917869f805aee783f982b9c458c752da2b23f6b80d6af32d4e6c4add9d5ebc592e18f74861616fcb403a7a0ca990ba6c6b477ea636fc9
|
|
7
|
+
data.tar.gz: 9099d5adad7117b3368fa7724f7dba4ec8379fb214b6de4585a4a72ec49e1975fae71c2ac5cebdb47635047da08da8cbb7a868c203cd37a340f492ff12f46ebd
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.
|
|
1
|
+
3.2.2
|
data/Gemfile
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
source
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
2
|
|
|
3
3
|
gemspec
|
|
4
4
|
|
|
5
5
|
group :development, :test do
|
|
6
|
-
gem 'rubocop', '~> 0.74.0'
|
|
7
|
-
gem 'pry'
|
|
8
6
|
gem 'dotenv'
|
|
7
|
+
gem 'pry'
|
|
8
|
+
gem 'rubocop', '~> 1.68'
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
group :test do
|
|
12
|
-
gem 'rspec', '~> 3.
|
|
13
|
-
gem 'webmock'
|
|
12
|
+
gem 'rspec', '~> 3.13.0'
|
|
14
13
|
gem 'vcr'
|
|
14
|
+
gem 'webmock'
|
|
15
15
|
end
|
data/Gemfile.lock
CHANGED
|
@@ -1,73 +1,87 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
instagram_basic_display (0.2.
|
|
4
|
+
instagram_basic_display (0.2.2)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: https://rubygems.org/
|
|
8
8
|
specs:
|
|
9
|
-
addressable (2.7
|
|
10
|
-
public_suffix (>= 2.0.2, <
|
|
11
|
-
ast (2.4.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
9
|
+
addressable (2.8.7)
|
|
10
|
+
public_suffix (>= 2.0.2, < 7.0)
|
|
11
|
+
ast (2.4.2)
|
|
12
|
+
base64 (0.2.0)
|
|
13
|
+
bigdecimal (3.1.8)
|
|
14
|
+
coderay (1.1.3)
|
|
15
|
+
crack (1.0.0)
|
|
16
|
+
bigdecimal
|
|
17
|
+
rexml
|
|
18
|
+
diff-lcs (1.5.1)
|
|
19
|
+
dotenv (3.1.4)
|
|
20
|
+
hashdiff (1.1.1)
|
|
21
|
+
json (2.8.1)
|
|
22
|
+
language_server-protocol (3.17.0.3)
|
|
23
|
+
method_source (1.1.0)
|
|
24
|
+
parallel (1.26.3)
|
|
25
|
+
parser (3.3.6.0)
|
|
26
|
+
ast (~> 2.4.1)
|
|
27
|
+
racc
|
|
28
|
+
pry (0.14.2)
|
|
29
|
+
coderay (~> 1.1)
|
|
30
|
+
method_source (~> 1.0)
|
|
31
|
+
public_suffix (6.0.1)
|
|
32
|
+
racc (1.8.1)
|
|
33
|
+
rainbow (3.1.1)
|
|
34
|
+
rake (13.2.1)
|
|
35
|
+
regexp_parser (2.9.2)
|
|
36
|
+
rexml (3.3.9)
|
|
37
|
+
rspec (3.13.0)
|
|
38
|
+
rspec-core (~> 3.13.0)
|
|
39
|
+
rspec-expectations (~> 3.13.0)
|
|
40
|
+
rspec-mocks (~> 3.13.0)
|
|
41
|
+
rspec-core (3.13.2)
|
|
42
|
+
rspec-support (~> 3.13.0)
|
|
43
|
+
rspec-expectations (3.13.3)
|
|
36
44
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
37
|
-
rspec-support (~> 3.
|
|
38
|
-
rspec-mocks (3.
|
|
45
|
+
rspec-support (~> 3.13.0)
|
|
46
|
+
rspec-mocks (3.13.2)
|
|
39
47
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
40
|
-
rspec-support (~> 3.
|
|
41
|
-
rspec-support (3.
|
|
42
|
-
rubocop (
|
|
43
|
-
|
|
48
|
+
rspec-support (~> 3.13.0)
|
|
49
|
+
rspec-support (3.13.1)
|
|
50
|
+
rubocop (1.68.0)
|
|
51
|
+
json (~> 2.3)
|
|
52
|
+
language_server-protocol (>= 3.17.0)
|
|
44
53
|
parallel (~> 1.10)
|
|
45
|
-
parser (>= 2
|
|
54
|
+
parser (>= 3.3.0.2)
|
|
46
55
|
rainbow (>= 2.2.2, < 4.0)
|
|
56
|
+
regexp_parser (>= 2.4, < 3.0)
|
|
57
|
+
rubocop-ast (>= 1.32.2, < 2.0)
|
|
47
58
|
ruby-progressbar (~> 1.7)
|
|
48
|
-
unicode-display_width (>=
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
59
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
|
60
|
+
rubocop-ast (1.34.0)
|
|
61
|
+
parser (>= 3.3.1.0)
|
|
62
|
+
ruby-progressbar (1.13.0)
|
|
63
|
+
unicode-display_width (2.6.0)
|
|
64
|
+
vcr (6.3.1)
|
|
65
|
+
base64
|
|
66
|
+
webmock (3.24.0)
|
|
67
|
+
addressable (>= 2.8.0)
|
|
55
68
|
crack (>= 0.3.2)
|
|
56
69
|
hashdiff (>= 0.4.0, < 2.0.0)
|
|
57
70
|
|
|
58
71
|
PLATFORMS
|
|
72
|
+
arm64-darwin-22
|
|
59
73
|
ruby
|
|
60
74
|
|
|
61
75
|
DEPENDENCIES
|
|
62
|
-
bundler (~>
|
|
76
|
+
bundler (~> 2.5.23)
|
|
63
77
|
dotenv
|
|
64
78
|
instagram_basic_display!
|
|
65
79
|
pry
|
|
66
|
-
rake (~>
|
|
67
|
-
rspec (~> 3.
|
|
68
|
-
rubocop (~>
|
|
80
|
+
rake (~> 13.2)
|
|
81
|
+
rspec (~> 3.13.0)
|
|
82
|
+
rubocop (~> 1.68)
|
|
69
83
|
vcr
|
|
70
84
|
webmock
|
|
71
85
|
|
|
72
86
|
BUNDLED WITH
|
|
73
|
-
|
|
87
|
+
2.5.23
|
data/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Instagram Basic Display
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This is a client gem for Instagram’s [Basic Display API](https://developers.facebook.com/docs/instagram-basic-display-api/). It’s a small wrapper around the API that provides access to users’ media and profile information. Not every endpoint has been implemented, so pull requests are welcome to round things out!
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Updates to the documentation are also very welcome!
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -20,9 +20,204 @@ Or install it yourself as:
|
|
|
20
20
|
|
|
21
21
|
$ gem install instagram_basic_display
|
|
22
22
|
|
|
23
|
-
## Usage
|
|
23
|
+
## Usage and examples
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
### Configuration
|
|
26
|
+
|
|
27
|
+
Set three environment variables to configure the client:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
INSTAGRAM_CLIENT_ID=your_client_id
|
|
31
|
+
INSTAGRAM_CLIENT_SECRET=your_client_secret
|
|
32
|
+
INSTAGRAM_REDIRECT_URI=your_redirect_url
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
These variables can be obtained from the Facebook developer console.
|
|
36
|
+
|
|
37
|
+
### Using the client
|
|
38
|
+
|
|
39
|
+
When initializing the client, you can optionally pass in an auth token from Instagram, which will be used to make further requests. If you do not already have a token, you can use one of the methods provided to retrieve one.
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
client = InstagramBasicDisplay::Client.new
|
|
43
|
+
|
|
44
|
+
# OR
|
|
45
|
+
|
|
46
|
+
client = InstagramBasicDisplay::Client.new(auth_token: token)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Getting auth tokens
|
|
50
|
+
|
|
51
|
+
Authenticating with Instagram starts with an access code. This access code is retrieved by implementing Instagram's [authortization window](https://developers.facebook.com/docs/instagram-basic-display-api/overview#authorization-window), and is not covered by this gem.
|
|
52
|
+
|
|
53
|
+
Once you have an access code, you can exchange it for a short-lived authentication token.
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
user = User.first
|
|
57
|
+
client = InstagramBasicDisplay::Client.new
|
|
58
|
+
|
|
59
|
+
short_token_request = client.short_lived_token(access_code: code)
|
|
60
|
+
|
|
61
|
+
if short_token_request.success?
|
|
62
|
+
auth_token = token_request.payload.access_token
|
|
63
|
+
expires_in = token_request.payload.expires_in
|
|
64
|
+
user.update_instagram_token(token: token, expires_in: expires_in)
|
|
65
|
+
else
|
|
66
|
+
render json: short_token_request.error, status: 400
|
|
67
|
+
end
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
You can exchange your short-lived token for a long-lived token.
|
|
71
|
+
|
|
72
|
+
```ruby
|
|
73
|
+
client = InstagramBasicDisplay::Client.new
|
|
74
|
+
user = User.first
|
|
75
|
+
|
|
76
|
+
long_token_request = client.long_lived_token(short_lived_token: user.instagram_token)
|
|
77
|
+
|
|
78
|
+
if long_token_request.success?
|
|
79
|
+
auth_token = token_request.payload.access_token
|
|
80
|
+
expires_in = token_request.payload.expires_in
|
|
81
|
+
user.update_instagram_token(token: token, expires_in: expires_in)
|
|
82
|
+
else
|
|
83
|
+
render json: long_token_request.error, status: 400
|
|
84
|
+
end
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
You can also pass an access code to `#long_lived_token`. It will be exchanged for a short-lived token, and then that will immediately be exchanged for a long-lived token.
|
|
88
|
+
|
|
89
|
+
```ruby
|
|
90
|
+
access_code = params[:access_code]
|
|
91
|
+
client = InstagramBasicDisplay::Client.new
|
|
92
|
+
user = User.first
|
|
93
|
+
|
|
94
|
+
long_token_request = client.long_lived_token(access_code: access_code)
|
|
95
|
+
|
|
96
|
+
if long_token_request.success?
|
|
97
|
+
auth_token = token_request.payload.access_token
|
|
98
|
+
expires_in = token_request.payload.expires_in
|
|
99
|
+
user.update_instagram_token(token: token, expires_in: expires_in)
|
|
100
|
+
else
|
|
101
|
+
render json: long_token_request.error, status: 400
|
|
102
|
+
end
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
You can refresh a long-lived token so that it remains valid for another period (at this stage, Instagram have set the validity period to 60 days).
|
|
106
|
+
|
|
107
|
+
```ruby
|
|
108
|
+
user = User.first
|
|
109
|
+
client = InstagramBasicDisplay::Client.new
|
|
110
|
+
|
|
111
|
+
refresh_request = client.refresh_long_lived_token(token: user.instagram_token)
|
|
112
|
+
|
|
113
|
+
if refresh_request.success?
|
|
114
|
+
client.update_instagram_token(token: token_request.payload.access_token)
|
|
115
|
+
else
|
|
116
|
+
render json: refresh_request.error, status: 400
|
|
117
|
+
end
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
To use an auth token when making requests, you can either pass it in when initializing the client,
|
|
121
|
+
or on-the-fly.
|
|
122
|
+
|
|
123
|
+
```ruby
|
|
124
|
+
auth_token = User.first.instagram_token
|
|
125
|
+
|
|
126
|
+
client = InstagramBasicDisplay::Client.new(auth_token: auth_token)
|
|
127
|
+
|
|
128
|
+
# OR
|
|
129
|
+
|
|
130
|
+
client = InstagramBasicDisplay::Client.new
|
|
131
|
+
client.configuration.auth_token = auth_token
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Getting profile information
|
|
135
|
+
|
|
136
|
+
You can retrieve a user's profile information (e.g. their username and Instagram id).
|
|
137
|
+
|
|
138
|
+
If no `user_id` is provided, the request will be made against the user associated with the client's auth token. For example:
|
|
139
|
+
|
|
140
|
+
```ruby
|
|
141
|
+
auth_token = User.first.instagram_token
|
|
142
|
+
|
|
143
|
+
client = InstagramBasicDisplay::Client.new(auth_token: auth_token)
|
|
144
|
+
response = client.profile
|
|
145
|
+
|
|
146
|
+
instagram_id = response.payload.id
|
|
147
|
+
instagram_username = response.payload.username
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
But you can also pass in a `user_id`, and request specific profile fields. Check the Instagram documentation to find out [which fields are supported](https://developers.facebook.com/docs/instagram-basic-display-api/reference/user#fields).
|
|
151
|
+
|
|
152
|
+
```ruby
|
|
153
|
+
user = User.first
|
|
154
|
+
|
|
155
|
+
client = InstagramBasicDisplay::Client.new(auth_token: user.instagram_token)
|
|
156
|
+
response = client.profile(user_id: user.instagram_id, fields: %i[username])
|
|
157
|
+
|
|
158
|
+
instagram_username = response.payload.username
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Getting media
|
|
162
|
+
|
|
163
|
+
You can query a user's media feed like this:
|
|
164
|
+
|
|
165
|
+
```ruby
|
|
166
|
+
user = User.first
|
|
167
|
+
|
|
168
|
+
client = InstagramBasicDisplay::Client.new(auth_token: user.instagram_token)
|
|
169
|
+
response = client.media_feed
|
|
170
|
+
|
|
171
|
+
media = response.payload.data
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
You can query for specific fields on the media, but by default you'll receive the `id` and `media_url` of each item. Refer to the Instagram documentation to [find out about other fields](https://developers.facebook.com/docs/instagram-basic-display-api/reference/media/).
|
|
175
|
+
|
|
176
|
+
```ruby
|
|
177
|
+
user = User.first
|
|
178
|
+
|
|
179
|
+
client = InstagramBasicDisplay::Client.new(auth_token: user.instagram_token)
|
|
180
|
+
response = client.media_feed(fields: %i[caption media_url])
|
|
181
|
+
|
|
182
|
+
media = response.payload.data
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
For pagination, the Instagram API provides previous/next links. Use those to retrieve the next page of results.
|
|
186
|
+
|
|
187
|
+
```ruby
|
|
188
|
+
|
|
189
|
+
user = User.first
|
|
190
|
+
|
|
191
|
+
client = InstagramBasicDisplay::Client.new(auth_token: user.instagram_token)
|
|
192
|
+
|
|
193
|
+
first_page = client.media_feed(fields: %i[caption media_url])
|
|
194
|
+
|
|
195
|
+
# you can ask the response whether there is a next/previous page
|
|
196
|
+
has_next_page_link = first_page.next_page?
|
|
197
|
+
|
|
198
|
+
# or ask for the url
|
|
199
|
+
next_page_link = first_page.next_page_link
|
|
200
|
+
|
|
201
|
+
second_page = client.media_feed(fields: %i[caption media_url], paginated_url: next_page_link)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
You can pass some additional parameters to the media feed. They aren't yet well-documented by Instagram, but you can make some reasonable guesses at what will be accepted, based on the Facebook API. For example, to limit the number of results retrieved:
|
|
205
|
+
|
|
206
|
+
```ruby
|
|
207
|
+
user = User.first
|
|
208
|
+
|
|
209
|
+
client = InstagramBasicDisplay::Client.new(auth_token: user.instagram_token)
|
|
210
|
+
client.media_feed(limit: 10)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
To retrieve a single piece of media, you'll need to know its id. As with the other requests, you can request whichever fields are supported by Instagram.
|
|
214
|
+
|
|
215
|
+
```ruby
|
|
216
|
+
user = User.first
|
|
217
|
+
client = InstagramBasicDisplay::Client.new(auth_token: user.instagram_token)
|
|
218
|
+
|
|
219
|
+
client.media_node(media_id: id, fields: %i[caption media_url id])
|
|
220
|
+
```
|
|
26
221
|
|
|
27
222
|
## Development
|
|
28
223
|
|
|
@@ -32,8 +227,4 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
|
32
227
|
|
|
33
228
|
## Contributing
|
|
34
229
|
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
|
36
|
-
|
|
37
|
-
## Code of Conduct
|
|
38
|
-
|
|
39
|
-
Everyone interacting in the InstagramBasicDisplay project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/instagram_basic_display/blob/master/CODE_OF_CONDUCT.md).
|
|
230
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/convertkit/instagram_basic_display. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
lib = File.expand_path(
|
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
|
-
require
|
|
3
|
+
require 'instagram_basic_display/version'
|
|
4
4
|
|
|
5
5
|
Gem::Specification.new do |spec|
|
|
6
|
-
spec.name =
|
|
6
|
+
spec.name = 'instagram_basic_display'
|
|
7
7
|
spec.version = InstagramBasicDisplay::VERSION
|
|
8
|
-
spec.authors = [
|
|
9
|
-
spec.email = [
|
|
8
|
+
spec.authors = ['Kit, LLC']
|
|
9
|
+
spec.email = ['engineering@kit.com']
|
|
10
10
|
|
|
11
|
-
spec.summary =
|
|
12
|
-
spec.description =
|
|
13
|
-
spec.homepage =
|
|
11
|
+
spec.summary = 'A ruby wrapper for the Instagram Basic Display API'
|
|
12
|
+
spec.description = 'A ruby wrapper for the Instagram Basic Display API'
|
|
13
|
+
spec.homepage = 'https://github.com/Kit/instagram_basic_display'
|
|
14
14
|
|
|
15
15
|
# Specify which files should be added to the gem when it is released.
|
|
16
16
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
17
|
-
spec.files = Dir.chdir(File.expand_path(
|
|
17
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
18
18
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
19
19
|
end
|
|
20
|
-
spec.bindir =
|
|
20
|
+
spec.bindir = 'exe'
|
|
21
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
22
|
-
spec.require_paths = [
|
|
22
|
+
spec.require_paths = ['lib']
|
|
23
23
|
|
|
24
|
-
spec.add_development_dependency
|
|
25
|
-
spec.add_development_dependency
|
|
26
|
-
spec.add_development_dependency
|
|
24
|
+
spec.add_development_dependency 'bundler', '~> 2.5.23'
|
|
25
|
+
spec.add_development_dependency 'rake', '~> 13.2'
|
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.13.0'
|
|
27
27
|
end
|
|
@@ -19,14 +19,34 @@ require 'instagram_basic_display/configuration'
|
|
|
19
19
|
require 'instagram_basic_display/response'
|
|
20
20
|
|
|
21
21
|
module InstagramBasicDisplay
|
|
22
|
+
# A module to handle authentication requests to the Instagram API. Allows you to retrieve
|
|
23
|
+
# short- and long-lived tokens, and refresh long-lived tokens.
|
|
24
|
+
#
|
|
25
|
+
# Does not handle retrieving access codes. These must be retrieved by implementing Instagram's
|
|
26
|
+
# authentication window.
|
|
27
|
+
# https://developers.facebook.com/docs/instagram-basic-display-api/overview#authentication-window
|
|
22
28
|
class Auth
|
|
29
|
+
# Constructor
|
|
30
|
+
#
|
|
31
|
+
# @param configuration [InstagramBasicDisplay::Configuration] configuration information
|
|
32
|
+
# that should be used to make requests against the Instagram API.
|
|
33
|
+
#
|
|
34
|
+
# @return void
|
|
23
35
|
def initialize(configuration)
|
|
24
36
|
@configuration = configuration
|
|
25
37
|
end
|
|
26
38
|
|
|
39
|
+
# Exchanges an access code for a _short-lived_ access token. A short-lived token is valid
|
|
40
|
+
# for one hour, but can be exchanged for a long-lived token. Refer to Instagram's documentation.
|
|
41
|
+
# https://developers.facebook.com/docs/instagram-basic-display-api/overview#short-lived-access-tokens
|
|
42
|
+
#
|
|
43
|
+
# @param access_code [String] A code retrieved by implementing Instagram's authentication window
|
|
44
|
+
# flow: https://developers.facebook.com/docs/instagram-basic-display-api/overview#authentication-window
|
|
45
|
+
#
|
|
46
|
+
# @return [InstagramBasicDisplay::Response] a response object containing either the token or an error
|
|
27
47
|
def short_lived_token(access_code:)
|
|
28
48
|
response = Net::HTTP.post_form(
|
|
29
|
-
URI(
|
|
49
|
+
URI(auth_url),
|
|
30
50
|
client_id: configuration.client_id,
|
|
31
51
|
client_secret: configuration.client_secret,
|
|
32
52
|
grant_type: 'authorization_code',
|
|
@@ -37,6 +57,13 @@ module InstagramBasicDisplay
|
|
|
37
57
|
InstagramBasicDisplay::Response.new(response)
|
|
38
58
|
end
|
|
39
59
|
|
|
60
|
+
# Exchanges _either_ an access code OR a short-lived token for a long-lived token.
|
|
61
|
+
# If an access code is passed, it will first be exchanged for a short-lived token.
|
|
62
|
+
# Once that is achieved, the short-lived token will be exchanged for a long-lived token.
|
|
63
|
+
# Refer to Instagram's documentation for more information on tokens:
|
|
64
|
+
# https://developers.facebook.com/docs/instagram-basic-display-api/overview
|
|
65
|
+
#
|
|
66
|
+
# @return [InstagramBasicDisplay::Response] a response object containing either the token or an error
|
|
40
67
|
def long_lived_token(short_lived_token: nil, access_code: nil)
|
|
41
68
|
short_lived_token ||= short_lived_token(access_code: access_code).payload.access_token
|
|
42
69
|
|
|
@@ -52,6 +79,9 @@ module InstagramBasicDisplay
|
|
|
52
79
|
InstagramBasicDisplay::Response.new(response)
|
|
53
80
|
end
|
|
54
81
|
|
|
82
|
+
# Refreshes a long-lived token for a new period of validity.
|
|
83
|
+
#
|
|
84
|
+
# @return [InstagramBasicDisplay::Response] a response object containing either the token or an error
|
|
55
85
|
def refresh_long_lived_token(token:)
|
|
56
86
|
uri = URI('https://graph.instagram.com/refresh_access_token')
|
|
57
87
|
params = {
|
|
@@ -67,5 +97,13 @@ module InstagramBasicDisplay
|
|
|
67
97
|
private
|
|
68
98
|
|
|
69
99
|
attr_reader :configuration
|
|
100
|
+
|
|
101
|
+
def auth_url
|
|
102
|
+
if configuration.version == 1
|
|
103
|
+
'https://api.instagram.com/oauth/access_token'
|
|
104
|
+
else
|
|
105
|
+
'https://graph.instagram.com/oauth/access_token'
|
|
106
|
+
end
|
|
107
|
+
end
|
|
70
108
|
end
|
|
71
109
|
end
|
|
@@ -19,23 +19,43 @@ require 'instagram_basic_display/auth'
|
|
|
19
19
|
require 'instagram_basic_display/profile'
|
|
20
20
|
|
|
21
21
|
module InstagramBasicDisplay
|
|
22
|
+
# Exposes all the functionality of the gem, so that you can interact with the Instagram API.
|
|
23
|
+
# Methods are defined in separate modules, but delegated here for simplicity when interacting
|
|
24
|
+
# with the gem.
|
|
22
25
|
class Client
|
|
23
26
|
extend Forwardable
|
|
24
27
|
|
|
25
28
|
def_delegators :@auth, :short_lived_token, :long_lived_token, :refresh_long_lived_token
|
|
26
29
|
def_delegators :@profile, :profile, :media_feed, :media_node, :media_feed_from_link
|
|
27
30
|
|
|
28
|
-
|
|
31
|
+
# Constructor method
|
|
32
|
+
#
|
|
33
|
+
# @param auth_token [String] optionally pass an auth token that will be used to
|
|
34
|
+
# make requests. If you do not have a token, you can retrieve one by using the
|
|
35
|
+
# authentication utilities provided.
|
|
36
|
+
#
|
|
37
|
+
# @return void
|
|
38
|
+
def initialize(auth_token: nil, version: 1)
|
|
29
39
|
@auth_token = auth_token
|
|
40
|
+
@version = version
|
|
30
41
|
|
|
31
42
|
@auth = Auth.new(configuration)
|
|
32
43
|
@profile = Profile.new(configuration)
|
|
33
44
|
end
|
|
34
45
|
|
|
46
|
+
# Configuration that will be used to make requests against the Instagram API:
|
|
47
|
+
# redirect_uri, client secret, and client ID. These are automatically picked up from
|
|
48
|
+
# environment variables. Optionally, you can pass an auth token which will be used
|
|
49
|
+
# to make requests.
|
|
50
|
+
#
|
|
51
|
+
# @return [InstagramBasicDisplay::Configuration]
|
|
35
52
|
def configuration
|
|
36
|
-
@configuration ||= InstagramBasicDisplay::Configuration.new(auth_token: @auth_token)
|
|
53
|
+
@configuration ||= InstagramBasicDisplay::Configuration.new(auth_token: @auth_token, version: @version)
|
|
37
54
|
end
|
|
38
55
|
|
|
56
|
+
# Sets the gem's configuration
|
|
57
|
+
#
|
|
58
|
+
# @return void
|
|
39
59
|
def configure
|
|
40
60
|
yield(configuration) if block_given?
|
|
41
61
|
nil
|
|
@@ -15,10 +15,18 @@
|
|
|
15
15
|
# limitations under the License.
|
|
16
16
|
|
|
17
17
|
module InstagramBasicDisplay
|
|
18
|
+
# Holds configuration values that are used to make requests against the
|
|
19
|
+
# Instagram API
|
|
18
20
|
class Configuration
|
|
19
|
-
attr_accessor :client_id, :client_secret, :redirect_uri, :auth_token
|
|
21
|
+
attr_accessor :client_id, :client_secret, :redirect_uri, :auth_token, :version
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
# Constructor method
|
|
24
|
+
#
|
|
25
|
+
# @param auth_token [String] token that will be used to make requests
|
|
26
|
+
#
|
|
27
|
+
# @return void
|
|
28
|
+
def initialize(auth_token: nil, version: 1)
|
|
29
|
+
@version = version
|
|
22
30
|
@client_id = set_client_id
|
|
23
31
|
@client_secret = set_client_secret
|
|
24
32
|
@redirect_uri = set_redirect_uri
|
|
@@ -26,15 +34,27 @@ module InstagramBasicDisplay
|
|
|
26
34
|
end
|
|
27
35
|
|
|
28
36
|
def set_client_id
|
|
29
|
-
|
|
37
|
+
if version == 1
|
|
38
|
+
ENV.fetch('INSTAGRAM_CLIENT_ID')
|
|
39
|
+
else
|
|
40
|
+
ENV.fetch('INSTAGRAM_CLIENT_ID_V2')
|
|
41
|
+
end
|
|
30
42
|
end
|
|
31
43
|
|
|
32
44
|
def set_client_secret
|
|
33
|
-
|
|
45
|
+
if version == 1
|
|
46
|
+
ENV.fetch('INSTAGRAM_CLIENT_SECRET')
|
|
47
|
+
else
|
|
48
|
+
ENV.fetch('INSTAGRAM_CLIENT_SECRET_V2')
|
|
49
|
+
end
|
|
34
50
|
end
|
|
35
51
|
|
|
36
52
|
def set_redirect_uri
|
|
37
|
-
|
|
53
|
+
if version == 1
|
|
54
|
+
ENV.fetch('INSTAGRAM_REDIRECT_URI')
|
|
55
|
+
else
|
|
56
|
+
ENV.fetch('INSTAGRAM_REDIRECT_URI_V2')
|
|
57
|
+
end
|
|
38
58
|
end
|
|
39
59
|
end
|
|
40
60
|
end
|
|
@@ -20,11 +20,37 @@ require 'instagram_basic_display/response'
|
|
|
20
20
|
require 'instagram_basic_display/errors'
|
|
21
21
|
|
|
22
22
|
module InstagramBasicDisplay
|
|
23
|
+
# Module for interacting with an Instagram user's profile. You can retrieve profile information
|
|
24
|
+
# and media.
|
|
23
25
|
class Profile
|
|
26
|
+
# Constructor
|
|
27
|
+
#
|
|
28
|
+
# @param configuration [InstagramBasicDisplay::Configuration] the configuration
|
|
29
|
+
# information to use when making requests to Instagram.
|
|
30
|
+
#
|
|
31
|
+
# @return void
|
|
24
32
|
def initialize(configuration)
|
|
25
33
|
@configuration = configuration
|
|
26
34
|
end
|
|
27
35
|
|
|
36
|
+
# Method for interacting with an Instagram user's profile. Can be used to retrieve
|
|
37
|
+
# information such as their id and username.
|
|
38
|
+
#
|
|
39
|
+
# @param user_id [String] the id of the user whose information you are retrieving.
|
|
40
|
+
# If no user_id is passed, the query will be made agains the user associated with the
|
|
41
|
+
# current auth token.
|
|
42
|
+
#
|
|
43
|
+
# @param fields [Array<Symbol>] array of fields to retrieve. Defaults to id and username.
|
|
44
|
+
# The full list of fields can be found in the Instagram documentation:
|
|
45
|
+
# https://developers.facebook.com/docs/instagram-basic-display-api/reference/user#fields
|
|
46
|
+
#
|
|
47
|
+
# @param params [Hash] any additional request parameters that should be passed to the API.
|
|
48
|
+
#
|
|
49
|
+
# @return [InstagramBasicDisplay::Response] a response object containing the response from
|
|
50
|
+
# the Instagram API.
|
|
51
|
+
#
|
|
52
|
+
# @raise [InstagramBasicDisplay::NoAuthToken] raises when no auth token is provided in the
|
|
53
|
+
# client configuration
|
|
28
54
|
def profile(user_id: nil, fields: %i[id username], **params)
|
|
29
55
|
check_for_auth_token!(params)
|
|
30
56
|
|
|
@@ -38,7 +64,23 @@ module InstagramBasicDisplay
|
|
|
38
64
|
make_request(uri, params)
|
|
39
65
|
end
|
|
40
66
|
|
|
41
|
-
#
|
|
67
|
+
# Method for retrieving a user's media feed.
|
|
68
|
+
#
|
|
69
|
+
# @param user_id [String] the id of the user whose information you are retrieving.
|
|
70
|
+
# If no user_id is passed, the query will be made agains the user associated with the
|
|
71
|
+
# current auth token.
|
|
72
|
+
#
|
|
73
|
+
# @param fields [Array<Symbol>] array of fields to retrieve. Defaults to id and media_url.
|
|
74
|
+
# The full list of fields can be found in the Instagram documentation:
|
|
75
|
+
# https://developers.facebook.com/docs/instagram-basic-display-api/reference/media/
|
|
76
|
+
#
|
|
77
|
+
# @param paginated_url [String] a url to retrieve the next or previous set of results
|
|
78
|
+
# from the API. This url is provided by the response from Instagram.
|
|
79
|
+
#
|
|
80
|
+
# @param params [Hash] any additional request parameters that should be passed to the API
|
|
81
|
+
#
|
|
82
|
+
# @raise [InstagramBasicDisplay::NoAuthToken] raises when no auth token is provided in the
|
|
83
|
+
# client configuration
|
|
42
84
|
def media_feed(user_id: nil, fields: %i[id media_url], paginated_url: nil, **params)
|
|
43
85
|
check_for_auth_token!(params)
|
|
44
86
|
|
|
@@ -57,7 +99,18 @@ module InstagramBasicDisplay
|
|
|
57
99
|
make_request(uri, params)
|
|
58
100
|
end
|
|
59
101
|
|
|
60
|
-
|
|
102
|
+
# Method for retrieving information for a particular media node (i.e. one image or video).
|
|
103
|
+
#
|
|
104
|
+
# @param media_id [String] the id of the media you are querying for.
|
|
105
|
+
#
|
|
106
|
+
# @param fields [Array<Symbol>] array of fields to retrieve. Defaults to id and media_url.
|
|
107
|
+
# The full list of fields can be found in the Instagram documentation:
|
|
108
|
+
# https://developers.facebook.com/docs/instagram-basic-display-api/reference/media/
|
|
109
|
+
#
|
|
110
|
+
# @param params [Hash] any additional request parameters that should be passed to the API
|
|
111
|
+
#
|
|
112
|
+
# @raise [InstagramBasicDisplay::NoAuthToken] raises when no auth token is provided in the
|
|
113
|
+
# client configuration
|
|
61
114
|
def media_node(media_id:, fields: %i[id media_url], **params)
|
|
62
115
|
check_for_auth_token!(params)
|
|
63
116
|
|
|
@@ -18,6 +18,10 @@ module InstagramBasicDisplay
|
|
|
18
18
|
class Response
|
|
19
19
|
attr_reader :status, :body, :response, :paging
|
|
20
20
|
|
|
21
|
+
# Constructor
|
|
22
|
+
# @param response [String] raw JSON repsonse from the Instagram API
|
|
23
|
+
#
|
|
24
|
+
# @return void
|
|
21
25
|
def initialize(response)
|
|
22
26
|
@response = response
|
|
23
27
|
@body = JSON.parse(response.body)
|
|
@@ -25,30 +29,44 @@ module InstagramBasicDisplay
|
|
|
25
29
|
@paging = body['paging']
|
|
26
30
|
end
|
|
27
31
|
|
|
32
|
+
# Returns whether or not a next page of results from the Instagram API is available
|
|
33
|
+
# @return [Boolean]
|
|
28
34
|
def next_page?
|
|
29
35
|
!next_page_link.nil?
|
|
30
36
|
end
|
|
31
37
|
|
|
38
|
+
# Returns whether or not a previous page of results from the Instagram API is available
|
|
39
|
+
# @return [Boolean]
|
|
32
40
|
def previous_page?
|
|
33
41
|
!previous_page_link.nil?
|
|
34
42
|
end
|
|
35
43
|
|
|
44
|
+
# Returns a link to the next page of results from the Instagram API
|
|
45
|
+
# @return [String]
|
|
36
46
|
def next_page_link
|
|
37
47
|
paging['next'] if paging
|
|
38
48
|
end
|
|
39
49
|
|
|
50
|
+
# Returns a link to the previous page of results from the Instagram API
|
|
51
|
+
# @return [String]
|
|
40
52
|
def previous_page_link
|
|
41
53
|
paging['previous'] if paging
|
|
42
54
|
end
|
|
43
55
|
|
|
56
|
+
# Returns whether the request to the Instagram API was a success
|
|
57
|
+
# @return [Boolean]
|
|
44
58
|
def success?
|
|
45
59
|
response.message == 'OK'
|
|
46
60
|
end
|
|
47
61
|
|
|
62
|
+
# Returns the raw payload from Instagram's API deserialized into a Struct
|
|
63
|
+
# @return [Struct]
|
|
48
64
|
def payload
|
|
49
65
|
deserialize_json(body)
|
|
50
66
|
end
|
|
51
67
|
|
|
68
|
+
# If an error is returned from the Instagram API, returns it as a Struct
|
|
69
|
+
# @return [Nil, Struct]
|
|
52
70
|
def error
|
|
53
71
|
return unless body['error'] || body['error_message']
|
|
54
72
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: instagram_basic_display
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
8
|
-
autorequire:
|
|
7
|
+
- Kit, LLC
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2024-11-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -16,45 +16,45 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
19
|
+
version: 2.5.23
|
|
20
20
|
type: :development
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
26
|
+
version: 2.5.23
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: rake
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
33
|
+
version: '13.2'
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
40
|
+
version: '13.2'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: rspec
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
45
|
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version:
|
|
47
|
+
version: 3.13.0
|
|
48
48
|
type: :development
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version:
|
|
54
|
+
version: 3.13.0
|
|
55
55
|
description: A ruby wrapper for the Instagram Basic Display API
|
|
56
56
|
email:
|
|
57
|
-
- engineering@
|
|
57
|
+
- engineering@kit.com
|
|
58
58
|
executables: []
|
|
59
59
|
extensions: []
|
|
60
60
|
extra_rdoc_files: []
|
|
@@ -80,10 +80,10 @@ files:
|
|
|
80
80
|
- lib/instagram_basic_display/profile.rb
|
|
81
81
|
- lib/instagram_basic_display/response.rb
|
|
82
82
|
- lib/instagram_basic_display/version.rb
|
|
83
|
-
homepage: https://github.com/
|
|
83
|
+
homepage: https://github.com/Kit/instagram_basic_display
|
|
84
84
|
licenses: []
|
|
85
85
|
metadata: {}
|
|
86
|
-
post_install_message:
|
|
86
|
+
post_install_message:
|
|
87
87
|
rdoc_options: []
|
|
88
88
|
require_paths:
|
|
89
89
|
- lib
|
|
@@ -98,9 +98,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
98
98
|
- !ruby/object:Gem::Version
|
|
99
99
|
version: '0'
|
|
100
100
|
requirements: []
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
signing_key:
|
|
101
|
+
rubygems_version: 3.4.10
|
|
102
|
+
signing_key:
|
|
104
103
|
specification_version: 4
|
|
105
104
|
summary: A ruby wrapper for the Instagram Basic Display API
|
|
106
105
|
test_files: []
|