snapcat 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +194 -0
- data/Rakefile +10 -0
- data/lib/snapcat.rb +19 -0
- data/lib/snapcat/client.rb +189 -0
- data/lib/snapcat/crypt.rb +35 -0
- data/lib/snapcat/friend.rb +57 -0
- data/lib/snapcat/media.rb +81 -0
- data/lib/snapcat/requestor.rb +106 -0
- data/lib/snapcat/response.rb +43 -0
- data/lib/snapcat/snap.rb +80 -0
- data/lib/snapcat/snapcat_error.rb +4 -0
- data/lib/snapcat/timestamp.rb +17 -0
- data/lib/snapcat/user.rb +46 -0
- data/snapcat.gemspec +28 -0
- data/spec/snapcat/client_spec.rb +217 -0
- data/spec/snapcat/crypt_spec.rb +27 -0
- data/spec/snapcat/friend_spec.rb +22 -0
- data/spec/snapcat/media_spec.rb +61 -0
- data/spec/snapcat/response_spec.rb +71 -0
- data/spec/snapcat/snap_spec.rb +72 -0
- data/spec/snapcat/timestamp_spec.rb +32 -0
- data/spec/snapcat/user_spec.rb +40 -0
- data/spec/snapcat_spec.rb +4 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/support/data_helper.rb +20 -0
- data/spec/support/fixture.rb +70 -0
- data/spec/support/minitest_spec_context.rb +7 -0
- data/spec/support/request_stub.rb +322 -0
- data/spec/support/response_helper.rb +15 -0
- data/spec/support/responses/block_success.json +5 -0
- data/spec/support/responses/delete_success.json +5 -0
- data/spec/support/responses/login_success.json +91 -0
- data/spec/support/responses/logout_success.json +1 -0
- data/spec/support/responses/register_failure.json +4 -0
- data/spec/support/responses/register_success.json +6 -0
- data/spec/support/responses/registeru_failure.json +4 -0
- data/spec/support/responses/registeru_success.json +58 -0
- data/spec/support/responses/send_snap_success.json +1 -0
- data/spec/support/responses/set_display_name_failure.json +4 -0
- data/spec/support/responses/set_display_name_success.json +9 -0
- data/spec/support/responses/unblock_success.json +10 -0
- data/spec/support/responses/update_email_success.json +5 -0
- data/spec/support/responses/update_privacy_success.json +5 -0
- data/spec/support/responses/updates_success.json +97 -0
- data/spec/support/responses/upload_success.json +1 -0
- data/spec/support/snaps/image_decrypted.jpg +0 -0
- data/spec/support/snaps/image_encrypted.jpg +0 -0
- data/spec/support/snaps/video_decrypted.mp4 +0 -0
- data/spec/support/snaps/video_encrypted.mp4 +0 -0
- data/spec/support/user_experience.rb +20 -0
- metadata +218 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1e888b4d7abb16b802f4805367bb673590c1220a
|
4
|
+
data.tar.gz: fbb23356c09c30d5544735805a18671afea27ef5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: aa65c119939ce0e0cc1c2fd4ad27f0a8a2d7f021bde43d38f319da5564cb7b37d330ba89309f314032cbf48f3bf364c1c000367d4d9d807536ae7bc5ac18dc2b
|
7
|
+
data.tar.gz: 16f5299266b6dc2087998db38f3a342f3c9b331ef3606579c31523c5360fd3c4147cbdfebf30b3c1315e2ceba7bdb7d6166992f7dadd6fa48bf92e2ba9ea1960
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Neal Kemp
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,194 @@
|
|
1
|
+
Snapcat
|
2
|
+
=======
|
3
|
+
[![Build Status](https://travis-ci.org/NealKemp/snapcat.png)](https://travis-ci.org/NealKemp/snapcat)
|
4
|
+
|
5
|
+
|
6
|
+
A cat-tastic Ruby wrapper for the [Snapchat](http://snapchat.com) private API.
|
7
|
+
Meow. This gem is designed to give you a friendly Ruby-like interface for
|
8
|
+
interacting with the Snapchat API.
|
9
|
+
|
10
|
+
|
11
|
+
Installation
|
12
|
+
------------
|
13
|
+
|
14
|
+
Add this line to your application's `Gemfile`:
|
15
|
+
|
16
|
+
gem 'snapcat', '0.0.1'
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
Alternatively, install it via command line:
|
23
|
+
|
24
|
+
$ gem install snapcat
|
25
|
+
|
26
|
+
|
27
|
+
Usage
|
28
|
+
-----
|
29
|
+
|
30
|
+
**User Auth**
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
# Initialize a client and login
|
34
|
+
snapcat = Snapcat::Client.new('your-username')
|
35
|
+
snapcat.login('topsecretpassword')
|
36
|
+
|
37
|
+
# Initialize a new client, register, and login
|
38
|
+
snapcat = Snapcat::Client.new('your-new-username')
|
39
|
+
snapcat.register('topsecretpassword', '1990-01-20', 'test@example.com')
|
40
|
+
|
41
|
+
# Logout
|
42
|
+
snapcat.logout
|
43
|
+
```
|
44
|
+
|
45
|
+
|
46
|
+
**User Actions**
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
# Block a user
|
50
|
+
snapcat.block('username-to-block')
|
51
|
+
|
52
|
+
# Clear feed
|
53
|
+
snapcat.clear_feed
|
54
|
+
|
55
|
+
# Fetch a user's updates
|
56
|
+
snapcat.fetch_updates
|
57
|
+
|
58
|
+
# Unblock a user
|
59
|
+
snapcat.unblock('username-to-unlock')
|
60
|
+
|
61
|
+
# Update user's email
|
62
|
+
snapcat.update_email('newemail@example.com')
|
63
|
+
|
64
|
+
# Update user's privacy setting
|
65
|
+
# Two choices:
|
66
|
+
# Snapcat::User::Privacy::EVERYONE
|
67
|
+
# Snapcat::User::Privacy::FRIENDS
|
68
|
+
snapcat.update_privacy(Snapcat::User::Privacy::EVERYONE)
|
69
|
+
|
70
|
+
# Pro tip:
|
71
|
+
# Every call to the API responds with Snapcat::Response object with which
|
72
|
+
# you can check a few important things
|
73
|
+
response = snapcat.block('username-to-block')
|
74
|
+
response.code # => 200
|
75
|
+
response.http_success # => true
|
76
|
+
response.data # => { logged: true, ... }
|
77
|
+
```
|
78
|
+
|
79
|
+
**User Data**
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
# Get the user
|
83
|
+
user = snapcat.user
|
84
|
+
|
85
|
+
# Examine all raw user data
|
86
|
+
user.data
|
87
|
+
|
88
|
+
# Examine snaps received
|
89
|
+
user.snaps_received
|
90
|
+
|
91
|
+
# Examine snaps sent
|
92
|
+
user.snaps_sent
|
93
|
+
|
94
|
+
# Examine friends
|
95
|
+
user.friends
|
96
|
+
```
|
97
|
+
|
98
|
+
**Friends**
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
# Grab a friend
|
102
|
+
friend = user.friends.first
|
103
|
+
|
104
|
+
# Set a friend's display name
|
105
|
+
snapcat.set_display_name(friend.username, 'Nik Ro')
|
106
|
+
|
107
|
+
# Delete a friend :(
|
108
|
+
snapcat.delete_friend(friend.username)
|
109
|
+
|
110
|
+
# Learn more about your friend
|
111
|
+
friend.can_see_custom_stories
|
112
|
+
friend.display_name
|
113
|
+
friend.username
|
114
|
+
|
115
|
+
# What kind of friend are they anyway??
|
116
|
+
friend.type
|
117
|
+
friend.type.confirmed?
|
118
|
+
friend.type.unconfirmed?
|
119
|
+
friend.type.blocked?
|
120
|
+
friend.type.deleted?
|
121
|
+
```
|
122
|
+
|
123
|
+
**Sending Snaps**
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
# Send it to catsaregreat with 3 seconds duration
|
127
|
+
# `data` is a string which can be read directly from an mp4 or jpg
|
128
|
+
snapcat.send_media(data, 'catsaregreat')
|
129
|
+
|
130
|
+
# Or send it to multiple recipients and override default view_duration
|
131
|
+
snapcat.send_media(data, %w(catsaregreat ronnie99), view_duration: 4)
|
132
|
+
```
|
133
|
+
|
134
|
+
**Received Snaps**
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
# Grab a snap
|
138
|
+
snap = user.snaps_received.first
|
139
|
+
|
140
|
+
# Get the snap image or video data
|
141
|
+
media_response = snapcat.media_for(snap.id)
|
142
|
+
media = media_response.data[:media]
|
143
|
+
|
144
|
+
# Learn more about the media
|
145
|
+
media.image?
|
146
|
+
media.video?
|
147
|
+
media.file_extension
|
148
|
+
media.type_code
|
149
|
+
|
150
|
+
# Get the data from the media object
|
151
|
+
media.to_s
|
152
|
+
```
|
153
|
+
|
154
|
+
**Snaps General**
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
# Learn more about the snap
|
158
|
+
snap.broadcast
|
159
|
+
snap.broadcast_action_text
|
160
|
+
snap.broadcast_hide_timer
|
161
|
+
snap.broadcast_url
|
162
|
+
snap.screenshot_count
|
163
|
+
snap.media_id
|
164
|
+
snap.id
|
165
|
+
snap.media_type
|
166
|
+
snap.recipient
|
167
|
+
snap.sender
|
168
|
+
snap.status
|
169
|
+
snap.sent
|
170
|
+
snap.opened
|
171
|
+
```
|
172
|
+
|
173
|
+
|
174
|
+
Contributing
|
175
|
+
------------
|
176
|
+
|
177
|
+
1. Fork it
|
178
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
179
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
180
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
181
|
+
5. Add tests and make sure they pass
|
182
|
+
6. Create new Pull Request
|
183
|
+
|
184
|
+
|
185
|
+
Credits
|
186
|
+
-------
|
187
|
+
|
188
|
+
* [Neal Kemp](http://nealke.mp)
|
189
|
+
* Based on work by martinp on [pysnap](https://github.com/martinp/pysnap) and by
|
190
|
+
djstelles on [php-snapchat](https://github.com/dstelljes/php-snapchat)
|
191
|
+
|
192
|
+
Copyright © 2013 Neal Kemp
|
193
|
+
|
194
|
+
Released under the MIT License, which can be found in the repository in `LICENSE.txt`.
|
data/Rakefile
ADDED
data/lib/snapcat.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'digest'
|
2
|
+
require 'httmultiparty'
|
3
|
+
require 'json'
|
4
|
+
require 'openssl'
|
5
|
+
require 'tempfile'
|
6
|
+
|
7
|
+
require 'snapcat/client'
|
8
|
+
require 'snapcat/crypt'
|
9
|
+
require 'snapcat/friend'
|
10
|
+
require 'snapcat/media'
|
11
|
+
require 'snapcat/requestor'
|
12
|
+
require 'snapcat/response'
|
13
|
+
require 'snapcat/snap'
|
14
|
+
require 'snapcat/snapcat_error'
|
15
|
+
require 'snapcat/timestamp'
|
16
|
+
require 'snapcat/user'
|
17
|
+
|
18
|
+
module Snapcat
|
19
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
module Snapcat
|
2
|
+
class Client
|
3
|
+
attr_reader :user
|
4
|
+
|
5
|
+
def initialize(username)
|
6
|
+
@user = User.new
|
7
|
+
@requestor = Requestor.new(username)
|
8
|
+
end
|
9
|
+
|
10
|
+
def block(username)
|
11
|
+
@requestor.request_with_username(
|
12
|
+
'friend',
|
13
|
+
action: 'block',
|
14
|
+
friend: username
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
def clear_feed
|
19
|
+
@requestor.request_with_username('clear')
|
20
|
+
end
|
21
|
+
|
22
|
+
def fetch_updates(update_timestamp = 0)
|
23
|
+
set_user_data_with(@requestor.request_with_username(
|
24
|
+
'updates',
|
25
|
+
update_timestamp: update_timestamp
|
26
|
+
))
|
27
|
+
end
|
28
|
+
|
29
|
+
def media_for(snap_id)
|
30
|
+
@requestor.request_media(snap_id)
|
31
|
+
end
|
32
|
+
|
33
|
+
def delete_friend(username)
|
34
|
+
@requestor.request_with_username(
|
35
|
+
'friend',
|
36
|
+
action: 'delete',
|
37
|
+
friend: username
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def set_display_name(username, display_name)
|
42
|
+
@requestor.request_with_username(
|
43
|
+
'friend',
|
44
|
+
action: 'display',
|
45
|
+
display: display_name,
|
46
|
+
friend: username
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
def login(password)
|
51
|
+
set_user_data_with(
|
52
|
+
@requestor.request_with_username('login', password: password)
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
def logout
|
57
|
+
@requestor.request_with_username('logout')
|
58
|
+
end
|
59
|
+
|
60
|
+
def register(password, birthday, email)
|
61
|
+
result = @requestor.request(
|
62
|
+
'register',
|
63
|
+
birthday: birthday,
|
64
|
+
email: email,
|
65
|
+
password: password
|
66
|
+
)
|
67
|
+
unless result.success?
|
68
|
+
return result
|
69
|
+
end
|
70
|
+
|
71
|
+
result_two = @requestor.request_with_username(
|
72
|
+
'registeru',
|
73
|
+
email: email
|
74
|
+
)
|
75
|
+
|
76
|
+
set_user_data_with(result_two)
|
77
|
+
end
|
78
|
+
|
79
|
+
def screenshot(snap_id, view_duration = 1)
|
80
|
+
raise NotImplementedError
|
81
|
+
|
82
|
+
snap_data = {
|
83
|
+
snap_id => {
|
84
|
+
c: Status::SCREENSHOT,
|
85
|
+
sv: view_duration,
|
86
|
+
t: Timestamp.float
|
87
|
+
}
|
88
|
+
}
|
89
|
+
events = [
|
90
|
+
{
|
91
|
+
eventName: 'SNAP_SCREENSHOT',
|
92
|
+
params: { id: snap_id },
|
93
|
+
ts: Timestamp.macro - view_duration
|
94
|
+
}
|
95
|
+
]
|
96
|
+
|
97
|
+
request_events(events, snap_data)
|
98
|
+
end
|
99
|
+
|
100
|
+
def send_media(data, recipients, options = {})
|
101
|
+
result = @requestor.request_upload(data, options[:type])
|
102
|
+
|
103
|
+
unless result.success?
|
104
|
+
return result
|
105
|
+
end
|
106
|
+
|
107
|
+
media_id = result.data[:media_id]
|
108
|
+
|
109
|
+
@requestor.request_with_username(
|
110
|
+
'send',
|
111
|
+
media_id: media_id,
|
112
|
+
recipient: prepare_recipients(recipients),
|
113
|
+
time: options[:view_duration] || 3
|
114
|
+
)
|
115
|
+
end
|
116
|
+
|
117
|
+
def unblock(username)
|
118
|
+
@requestor.request_with_username(
|
119
|
+
'friend',
|
120
|
+
action: 'unblock',
|
121
|
+
friend: username
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
def view(snap_id, view_duration = 1)
|
126
|
+
raise NotImplementedError
|
127
|
+
|
128
|
+
snap_data = {
|
129
|
+
snap_id => { t: Timestamp.float, sv: view_duration }
|
130
|
+
}
|
131
|
+
events = [
|
132
|
+
{
|
133
|
+
eventName: 'SNAP_VIEW',
|
134
|
+
params: { id: snap_id },
|
135
|
+
ts: Timestamp.macro - view_duration
|
136
|
+
},
|
137
|
+
{
|
138
|
+
eventName: 'SNAP_EXPIRED',
|
139
|
+
params: { id: snap_id },
|
140
|
+
ts: Timestamp.macro
|
141
|
+
}
|
142
|
+
]
|
143
|
+
|
144
|
+
request_events(events, snap_data)
|
145
|
+
end
|
146
|
+
|
147
|
+
def update_email(email)
|
148
|
+
@requestor.request_with_username(
|
149
|
+
'settings',
|
150
|
+
action: 'updateEmail',
|
151
|
+
email: email
|
152
|
+
)
|
153
|
+
end
|
154
|
+
|
155
|
+
def update_privacy(code)
|
156
|
+
@requestor.request_with_username(
|
157
|
+
'settings',
|
158
|
+
action: 'updatePrivacy',
|
159
|
+
privacySetting: code
|
160
|
+
)
|
161
|
+
end
|
162
|
+
|
163
|
+
private
|
164
|
+
|
165
|
+
def prepare_recipients(recipients)
|
166
|
+
if recipients.is_a? Array
|
167
|
+
recipients.join(',')
|
168
|
+
else
|
169
|
+
recipients
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def request_events(events, snap_data)
|
174
|
+
@requestor.request_with_username(
|
175
|
+
'update_snaps',
|
176
|
+
events: events,
|
177
|
+
json: snap_data
|
178
|
+
)
|
179
|
+
end
|
180
|
+
|
181
|
+
def set_user_data_with(result)
|
182
|
+
if result.success?
|
183
|
+
@user.data = result.data
|
184
|
+
end
|
185
|
+
|
186
|
+
result
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|