login_radius 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.DS_Store +0 -0
- data/.gitignore +18 -0
- data/Gemfile +25 -0
- data/LICENSE +22 -0
- data/LoginRadiusTestApp/.gitignore +15 -0
- data/LoginRadiusTestApp/Gemfile +42 -0
- data/LoginRadiusTestApp/Gemfile.lock +136 -0
- data/LoginRadiusTestApp/README.rdoc +261 -0
- data/LoginRadiusTestApp/Rakefile +7 -0
- data/LoginRadiusTestApp/app/assets/images/rails.png +0 -0
- data/LoginRadiusTestApp/app/assets/javascripts/application.js +15 -0
- data/LoginRadiusTestApp/app/assets/stylesheets/application.css +13 -0
- data/LoginRadiusTestApp/app/controllers/application_controller.rb +17 -0
- data/LoginRadiusTestApp/app/helpers/application_helper.rb +2 -0
- data/LoginRadiusTestApp/app/mailers/.gitkeep +0 -0
- data/LoginRadiusTestApp/app/models/.gitkeep +0 -0
- data/LoginRadiusTestApp/app/views/application/callback.html.erb +1 -0
- data/LoginRadiusTestApp/app/views/application/index.html.erb +7 -0
- data/LoginRadiusTestApp/app/views/layouts/application.html.erb +14 -0
- data/LoginRadiusTestApp/config/application.rb +62 -0
- data/LoginRadiusTestApp/config/boot.rb +6 -0
- data/LoginRadiusTestApp/config/database.yml +25 -0
- data/LoginRadiusTestApp/config/environment.rb +5 -0
- data/LoginRadiusTestApp/config/environments/development.rb +37 -0
- data/LoginRadiusTestApp/config/environments/production.rb +67 -0
- data/LoginRadiusTestApp/config/environments/test.rb +37 -0
- data/LoginRadiusTestApp/config/initializers/backtrace_silencers.rb +7 -0
- data/LoginRadiusTestApp/config/initializers/inflections.rb +15 -0
- data/LoginRadiusTestApp/config/initializers/mime_types.rb +5 -0
- data/LoginRadiusTestApp/config/initializers/secret_token.rb +7 -0
- data/LoginRadiusTestApp/config/initializers/session_store.rb +8 -0
- data/LoginRadiusTestApp/config/initializers/wrap_parameters.rb +14 -0
- data/LoginRadiusTestApp/config/locales/en.yml +5 -0
- data/LoginRadiusTestApp/config/routes.rb +61 -0
- data/LoginRadiusTestApp/config.ru +4 -0
- data/LoginRadiusTestApp/db/seeds.rb +7 -0
- data/LoginRadiusTestApp/lib/assets/.gitkeep +0 -0
- data/LoginRadiusTestApp/lib/tasks/.gitkeep +0 -0
- data/LoginRadiusTestApp/log/.gitkeep +0 -0
- data/LoginRadiusTestApp/public/404.html +26 -0
- data/LoginRadiusTestApp/public/422.html +26 -0
- data/LoginRadiusTestApp/public/500.html +25 -0
- data/LoginRadiusTestApp/public/favicon.ico +0 -0
- data/LoginRadiusTestApp/public/robots.txt +5 -0
- data/LoginRadiusTestApp/script/rails +6 -0
- data/LoginRadiusTestApp/test/fixtures/.gitkeep +0 -0
- data/LoginRadiusTestApp/test/functional/.gitkeep +0 -0
- data/LoginRadiusTestApp/test/integration/.gitkeep +0 -0
- data/LoginRadiusTestApp/test/performance/browsing_test.rb +12 -0
- data/LoginRadiusTestApp/test/test_helper.rb +13 -0
- data/LoginRadiusTestApp/test/unit/.gitkeep +0 -0
- data/LoginRadiusTestApp/vendor/assets/javascripts/.gitkeep +0 -0
- data/LoginRadiusTestApp/vendor/assets/stylesheets/.gitkeep +0 -0
- data/LoginRadiusTestApp/vendor/plugins/.gitkeep +0 -0
- data/README.md +417 -0
- data/Rakefile +2 -0
- data/lib/hash.rb +13 -0
- data/lib/login_radius/exception.rb +4 -0
- data/lib/login_radius/messages.rb +102 -0
- data/lib/login_radius/user_profile.rb +102 -0
- data/lib/login_radius/user_profile_getters.rb +106 -0
- data/lib/login_radius/version.rb +3 -0
- data/lib/login_radius.rb +11 -0
- data/lib/string.rb +9 -0
- data/login_radius.gemspec +20 -0
- data/test/.DS_Store +0 -0
- data/test/basic_async_test.rb +29 -0
- data/test/unit/.DS_Store +0 -0
- data/test/unit/base_test.rb +11 -0
- data/test/unit/user_profile_test.rb +68 -0
- metadata +152 -0
data/README.md
ADDED
@@ -0,0 +1,417 @@
|
|
1
|
+
# LoginRadius
|
2
|
+
|
3
|
+
Ruby wrapper for the LoginRadius API. Get social graph information and send messages using LoginRadius'
|
4
|
+
many social network clients!
|
5
|
+
|
6
|
+
Optional Asynchronous EventMachine friendly option!
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'login_radius'
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install login_radius
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
Take a peek:
|
25
|
+
|
26
|
+
@user_profile = LoginRadius::UserProfile.new({
|
27
|
+
:token => "TOKEN",
|
28
|
+
:secret => "SECRET",
|
29
|
+
:async => false #Set to true if using EventMachine driven frameworks(must use Em Synchrony)
|
30
|
+
})
|
31
|
+
@user_profile.login
|
32
|
+
my_contacts = @user_profile.contacts
|
33
|
+
|
34
|
+
That's right, folks. It's that simple. In order to get access to LoginRadius API, you only
|
35
|
+
need to create a UserProfile object with a user's login token and your apps secret, and login.
|
36
|
+
|
37
|
+
### How to get a token and actually make a client
|
38
|
+
|
39
|
+
On the LoginRadius website, you are able to enter your own callback URL for your app. You will need
|
40
|
+
to setup a route on whatever framework you use, maybe "/callback." Then, get the gem forward(www.forwardhq.com)
|
41
|
+
and use it to set up a public web address for your localhost server. Then, you can enter the callback on LoginRadius
|
42
|
+
as https://jordanmatthew.fwd.wf/callback, for instance.
|
43
|
+
|
44
|
+
Paste their example login stuff onto your index page, and then enter your FB/Twitter credentials on their site.
|
45
|
+
|
46
|
+
Now you're ready to go with testing!
|
47
|
+
|
48
|
+
When LoginRadius hits your callback after a user logs in, you'll see parameters like this:
|
49
|
+
|
50
|
+
Parameters: {"token"=>"yourtokenhere"}
|
51
|
+
|
52
|
+
This token is the token used in the above example. This is what you'll need to get your user's profile.
|
53
|
+
Just paste it into the code above, and you can immediately grab their user profile on the callback,
|
54
|
+
login, and grab their contacts.
|
55
|
+
|
56
|
+
### Some examples
|
57
|
+
|
58
|
+
Below is just code exemplifying some of the more interesting methods and what they return.
|
59
|
+
Note if you have a user authed via facebook, and not twitter, methods like
|
60
|
+
|
61
|
+
@user_profile.twitter_timeline
|
62
|
+
=> false
|
63
|
+
|
64
|
+
Will return false, indicating you don't have access to that stream.
|
65
|
+
|
66
|
+
#### Facebook Stuff
|
67
|
+
|
68
|
+
@user_profile.facebook_groups
|
69
|
+
=> [{:id=>"11111", :name=>"Name"},
|
70
|
+
{:id=>"11111", :name=>"Name"},
|
71
|
+
{:id=>"11111", :name=>"Name"},
|
72
|
+
{:id=>"11111", :name=>"Name"},
|
73
|
+
{:id=>"11111", :name=>"Name"},
|
74
|
+
{:id=>"11111", :name=>"Name"},
|
75
|
+
{:id=>"11111", :name=>"Name"},
|
76
|
+
{:id=>"11111", :name=>"Name"},
|
77
|
+
{:id=>"11111", :name=>"Name"}]
|
78
|
+
|
79
|
+
@user_profile.facebook_groups
|
80
|
+
=> [{:id=>"11111", :name=>"Name"},
|
81
|
+
{:id=>"11111", :name=>"Name"}]
|
82
|
+
|
83
|
+
|
84
|
+
@user_profile.facebook_events
|
85
|
+
=> [{:id=>"11111",
|
86
|
+
:name=>"Name",
|
87
|
+
:start_time=>"3/14/2015 9:00:00 AM",
|
88
|
+
:rsvp_status=>"attending",
|
89
|
+
:location=>"Across the world!"}]
|
90
|
+
|
91
|
+
And, finally, you can also make facebook posts:
|
92
|
+
|
93
|
+
params = {
|
94
|
+
:title => "Testing",
|
95
|
+
:url => "www.loginradius.com",
|
96
|
+
:status => "Wizzup",
|
97
|
+
:caption => "Testly",
|
98
|
+
:description => "Testing"
|
99
|
+
}
|
100
|
+
@user_profile.make_facebook_post(params)
|
101
|
+
=> true
|
102
|
+
|
103
|
+
Note that as of publishing, the :to option on facebook params does not work. You can't post to
|
104
|
+
other people's walls.
|
105
|
+
|
106
|
+
#### LinkedIn Stuff
|
107
|
+
|
108
|
+
To send messages over linked in:
|
109
|
+
|
110
|
+
@user_profile.send_linked_in_message(@user_profile.contacts.first[:id], "Testing", "This is a test.")
|
111
|
+
=> true
|
112
|
+
|
113
|
+
Notice how I grabbed my first contact and used his :id property.
|
114
|
+
|
115
|
+
Also, you can grab a user's linked in companies:
|
116
|
+
|
117
|
+
@user_profile.linked_in_companies
|
118
|
+
=> [{:id=>11111, :name=>"Name"}]
|
119
|
+
|
120
|
+
#### Twitter Stuff
|
121
|
+
|
122
|
+
To send messages over twitter:
|
123
|
+
|
124
|
+
@user_profile.send_linked_in_message(@user_profile.contacts.first[:id], "Testing", "This is a test.")
|
125
|
+
=> true
|
126
|
+
|
127
|
+
Notice how I grabbed my first contact and used his :id property.
|
128
|
+
|
129
|
+
Grab your timelines and mentions:
|
130
|
+
|
131
|
+
@user_profile.twitter_timeline
|
132
|
+
=> [{:id=>"11111",
|
133
|
+
:text=>"Stuff",
|
134
|
+
:date_time=>"5/20/2013 4:53:52 PM",
|
135
|
+
:likes=>0,
|
136
|
+
:place=>"",
|
137
|
+
:source=>
|
138
|
+
"<a href=\"http://twitterfeed.com\" rel=\"nofollow\">twitterfeed</a>",
|
139
|
+
:image_url=>nil,
|
140
|
+
:link_url=>nil,
|
141
|
+
:name=>"Name"}]
|
142
|
+
|
143
|
+
@user_profile.twitter_mentions
|
144
|
+
=> [{:id=>"11111",
|
145
|
+
:text=>"Stuff",
|
146
|
+
:date_time=>"3/31/2013 7:54:10 PM",
|
147
|
+
:likes=>0,
|
148
|
+
:place=>"",
|
149
|
+
:source=>"web",
|
150
|
+
:image_url=>nil,
|
151
|
+
:link_url=>nil,
|
152
|
+
:name=>"Name"}]
|
153
|
+
|
154
|
+
#### Social Network Contacts
|
155
|
+
|
156
|
+
Note this is all the contacts from every social network the user is connected to.
|
157
|
+
|
158
|
+
@user_profile.contacts
|
159
|
+
=> [{:name=>"Name",
|
160
|
+
:email_id=>"",
|
161
|
+
:phone_number=>"",
|
162
|
+
:id=>"11111",
|
163
|
+
:profile_url=>nil,
|
164
|
+
:image_url=>nil,
|
165
|
+
:status=>nil,
|
166
|
+
:industry=>nil,
|
167
|
+
:country=>nil,
|
168
|
+
:gender=>nil}]
|
169
|
+
|
170
|
+
#### User Profile Stuff
|
171
|
+
|
172
|
+
When you login, the API returns a hash of user profile information, which is then turned into methods
|
173
|
+
on the LoginRadius::UserProfile object for your accessing pleasure. A quick call to methods will show this.
|
174
|
+
|
175
|
+
@user_profile.methods
|
176
|
+
=>[:id,
|
177
|
+
:provider,
|
178
|
+
:prefix,
|
179
|
+
:first_name,
|
180
|
+
:middle_name,
|
181
|
+
:last_name,
|
182
|
+
:suffix,
|
183
|
+
:full_name,
|
184
|
+
:nick_name,
|
185
|
+
:profile_name,
|
186
|
+
:birth_date,
|
187
|
+
:gender,
|
188
|
+
:website,
|
189
|
+
:email,
|
190
|
+
:country,
|
191
|
+
...]
|
192
|
+
|
193
|
+
Calling .methods on a user profile right after a successful login call will reveal these.
|
194
|
+
For more information, please read the section in caveats on the matter, as it's a bit esoteric.
|
195
|
+
|
196
|
+
## Caveats
|
197
|
+
|
198
|
+
This section is for the nitpickers. It's got notes about the finer pickings of this API for those
|
199
|
+
who are wondering, but is not strictly necessary reading.
|
200
|
+
|
201
|
+
### The Bang Methods
|
202
|
+
|
203
|
+
When authenticated, a method like contacts will return
|
204
|
+
|
205
|
+
@user_profile.authenticated?
|
206
|
+
=> true
|
207
|
+
@user_profile.contacts
|
208
|
+
=> [{:name=>"Name",
|
209
|
+
:email_id=>"",
|
210
|
+
:phone_number=>"",
|
211
|
+
:id=>"11111",
|
212
|
+
:profile_url=>nil,
|
213
|
+
:image_url=>nil,
|
214
|
+
:status=>nil,
|
215
|
+
:industry=>nil,
|
216
|
+
:country=>nil,
|
217
|
+
:gender=>nil},
|
218
|
+
...
|
219
|
+
|
220
|
+
When unauthenticated, a method like contacts will return false.
|
221
|
+
|
222
|
+
@user_profile.authenticated?
|
223
|
+
=> false
|
224
|
+
@user_profile.contacts
|
225
|
+
=> false
|
226
|
+
|
227
|
+
However, if you want to be a bit more flammable, try using contacts!, the bang version. It still returns
|
228
|
+
the same results when authed, but when unauthed, will actually raise a LoginRadius::Exception.
|
229
|
+
|
230
|
+
### The LoginRadius::UserProfile object before and after login
|
231
|
+
|
232
|
+
Once you've got a valid user_profile, you have many methods available to you. Let's quickly take a look
|
233
|
+
at the methods in a LoginRadius::UserProfile object that hasn't yet been authenticated:
|
234
|
+
|
235
|
+
@user_profile.authenticated?
|
236
|
+
=> false
|
237
|
+
|
238
|
+
@user_profile.methods - Object.new.methods
|
239
|
+
=> [:secret,
|
240
|
+
:secret=,
|
241
|
+
:token,
|
242
|
+
:token=,
|
243
|
+
:async,
|
244
|
+
:async=,
|
245
|
+
:guid_valid?,
|
246
|
+
:authenticated?,
|
247
|
+
:call_api,
|
248
|
+
:send_twitter_message,
|
249
|
+
:send_linkedin_message,
|
250
|
+
:make_facebook_post,
|
251
|
+
:login!,
|
252
|
+
:login,
|
253
|
+
:twitter_mentions!,
|
254
|
+
:twitter_mentions,
|
255
|
+
:twitter_timeline!,
|
256
|
+
:twitter_timeline,
|
257
|
+
:linked_in_companies!,
|
258
|
+
:linked_in_companies,
|
259
|
+
:contacts!,
|
260
|
+
:contacts,
|
261
|
+
:facebook_groups!,
|
262
|
+
:facebook_groups,
|
263
|
+
:facebook_posts!,
|
264
|
+
:facebook_posts,
|
265
|
+
:facebook_events!,
|
266
|
+
:facebook_events]
|
267
|
+
|
268
|
+
Notice we've got a lot of stuff we can access. But we're not yet authenticated. Running login and then checking
|
269
|
+
the new methods created, we see we have much more than before!
|
270
|
+
|
271
|
+
@user_profile.login
|
272
|
+
=> true
|
273
|
+
@user_profile.authenticated?
|
274
|
+
=> true
|
275
|
+
@user_profile.methods - Object.new.methods
|
276
|
+
=> [:id,
|
277
|
+
:provider,
|
278
|
+
:prefix,
|
279
|
+
:first_name,
|
280
|
+
:middle_name,
|
281
|
+
:last_name,
|
282
|
+
:suffix,
|
283
|
+
:full_name,
|
284
|
+
:nick_name,
|
285
|
+
:profile_name,
|
286
|
+
:birth_date,
|
287
|
+
:gender,
|
288
|
+
:website,
|
289
|
+
:email,
|
290
|
+
:country,
|
291
|
+
:thumbnail_image_url,
|
292
|
+
:image_url,
|
293
|
+
:favicon,
|
294
|
+
:profile_url,
|
295
|
+
:home_town,
|
296
|
+
:state,
|
297
|
+
:city,
|
298
|
+
:industry,
|
299
|
+
:about,
|
300
|
+
:time_zone,
|
301
|
+
:local_language,
|
302
|
+
:language,
|
303
|
+
:verified,
|
304
|
+
:updated_time,
|
305
|
+
:positions,
|
306
|
+
:educations,
|
307
|
+
:phone_numbers,
|
308
|
+
:im_accounts,
|
309
|
+
:addresses,
|
310
|
+
:main_address,
|
311
|
+
:created,
|
312
|
+
:local_city,
|
313
|
+
:profile_city,
|
314
|
+
:local_country,
|
315
|
+
:profile_country,
|
316
|
+
:relationship_status,
|
317
|
+
:quota,
|
318
|
+
:interested_in,
|
319
|
+
:interests,
|
320
|
+
:religion,
|
321
|
+
:political,
|
322
|
+
:sports,
|
323
|
+
:inspirational_people,
|
324
|
+
:https_image_url,
|
325
|
+
:followers_count,
|
326
|
+
:friends_count,
|
327
|
+
:is_geo_enabled,
|
328
|
+
:total_statuses_count,
|
329
|
+
:associations,
|
330
|
+
:num_recommenders,
|
331
|
+
:honors,
|
332
|
+
:skills,
|
333
|
+
:current_status,
|
334
|
+
:certifications,
|
335
|
+
:courses,
|
336
|
+
:volunteer,
|
337
|
+
:recommendations_received,
|
338
|
+
:languages,
|
339
|
+
:public_repository,
|
340
|
+
:hireable,
|
341
|
+
:repository_url,
|
342
|
+
:age,
|
343
|
+
:patents,
|
344
|
+
:favorite_things,
|
345
|
+
:professional_headline,
|
346
|
+
:provider_access_credential,
|
347
|
+
:secret,
|
348
|
+
:secret=,
|
349
|
+
:token,
|
350
|
+
:token=,
|
351
|
+
:async,
|
352
|
+
:async=,
|
353
|
+
:guid_valid?,
|
354
|
+
:authenticated?,
|
355
|
+
:call_api,
|
356
|
+
:send_twitter_message,
|
357
|
+
:send_linkedin_message,
|
358
|
+
:make_facebook_post,
|
359
|
+
:login!,
|
360
|
+
:login,
|
361
|
+
:twitter_mentions!,
|
362
|
+
:twitter_mentions,
|
363
|
+
:twitter_timeline!,
|
364
|
+
:twitter_timeline,
|
365
|
+
:linked_in_companies!,
|
366
|
+
:linked_in_companies,
|
367
|
+
:contacts!,
|
368
|
+
:contacts,
|
369
|
+
:facebook_groups!,
|
370
|
+
:facebook_groups,
|
371
|
+
:facebook_posts!,
|
372
|
+
:facebook_posts,
|
373
|
+
:facebook_events!,
|
374
|
+
:facebook_events]
|
375
|
+
|
376
|
+
Holy moly we got a whole bunch of new methods! That's because on login, all the user profile information
|
377
|
+
returned by the API is turned into dynamically generated GETTERs on the object that you can then use later.
|
378
|
+
|
379
|
+
### Running the tests in test/unit
|
380
|
+
|
381
|
+
The base_test.rb file isn't meant to be run, it is inherited by user_profile_test.rb. In that file
|
382
|
+
you'll notice the lines at the top of the file:
|
383
|
+
|
384
|
+
TOKEN = "yourtokenhere"
|
385
|
+
SECRET = "yoursecrethere"
|
386
|
+
|
387
|
+
These are meant to be changed to your API secret and some user's token. What I do is I run a dummy
|
388
|
+
rails app locally and use the forward gem so that it can receive requests from the internet. Then I setup
|
389
|
+
a callback route and login page on the app and use it to have LoginRadius ping me with tokens that I can
|
390
|
+
paste into this test file.
|
391
|
+
|
392
|
+
*Beware, LoginRadius invalidates any token after 15 minutes, so during testing, you'll have to repeat the token
|
393
|
+
creation A LOT*
|
394
|
+
|
395
|
+
To run the tests, do:
|
396
|
+
|
397
|
+
bundle exec ruby -Itest test/unit/user_profile_test.rb
|
398
|
+
|
399
|
+
If you login with a facebook user, for instance, you'll notice all the twitter/linked in tests failing.
|
400
|
+
This is to be expected, you don't have access to those streams!
|
401
|
+
|
402
|
+
### Evented Frameworks
|
403
|
+
|
404
|
+
I've built this gem to work with frameworks like Cramp. I've done a little bit of testing by creating
|
405
|
+
a basic event loop script in basic_async_test.rb in the test folder, which you can run to see that
|
406
|
+
things work there.
|
407
|
+
|
408
|
+
I've also done some AB testing using a Cramp framework elsewhere, but you should take caution in using
|
409
|
+
this gem in evented frameworks and make sure to use apache bench to test it for nonblocking yourself.
|
410
|
+
|
411
|
+
## Contributing
|
412
|
+
|
413
|
+
1. Fork it
|
414
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
415
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
416
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
417
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/hash.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
class Hash
|
2
|
+
def self.lr_convert_hash_keys(value) #lr_ appended so no method naming conflicts with other gems
|
3
|
+
case value
|
4
|
+
when Array
|
5
|
+
value.map { |v| lr_convert_hash_keys(v) }
|
6
|
+
# or `value.map(&method(:convert_hash_keys))`
|
7
|
+
when Hash
|
8
|
+
Hash[value.map { |k, v| [k.to_s.lr_underscore, lr_convert_hash_keys(v)] }]
|
9
|
+
else
|
10
|
+
value
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module LoginRadius
|
2
|
+
module Messages
|
3
|
+
|
4
|
+
# Sends a message to a person using twitter
|
5
|
+
#
|
6
|
+
# @param sendto [String] Social ID of person you're contacting from contact list
|
7
|
+
# @param subject [String]
|
8
|
+
# @param message [String]
|
9
|
+
# @return [Boolean] Whether or not message succeeded
|
10
|
+
def send_twitter_message(sendto, subject, message)
|
11
|
+
send_message({:sendto => sendto, :subject => subject, :message => message})
|
12
|
+
end
|
13
|
+
|
14
|
+
# Sends a message to a person using twitter
|
15
|
+
#
|
16
|
+
# @param sendto [String] Social ID of person you're contacting from contact list
|
17
|
+
# @param subject [String]
|
18
|
+
# @param message [String]
|
19
|
+
# @return [Boolean] Whether or not message succeeded
|
20
|
+
def send_twitter_message!(sendto, subject, message)
|
21
|
+
send_message({:sendto => sendto, :subject => subject, :message => message})
|
22
|
+
end
|
23
|
+
|
24
|
+
# Sends a message to a person using linkedin
|
25
|
+
#
|
26
|
+
# @param sendto [String] Social ID of person you're contacting from contact list
|
27
|
+
# @param subject [String]
|
28
|
+
# @param message [String]
|
29
|
+
# @return [Boolean] Whether or not message succeeded
|
30
|
+
def send_linked_in_message(sendto, subject, message)
|
31
|
+
send_message({:sendto => sendto, :subject => subject, :message => message})
|
32
|
+
end
|
33
|
+
|
34
|
+
# Sends a message to a person using linkedin
|
35
|
+
#
|
36
|
+
# @param sendto [String] Social ID of person you're contacting from contact list
|
37
|
+
# @param subject [String]
|
38
|
+
# @param message [String]
|
39
|
+
# @return [Boolean] Whether or not message succeeded
|
40
|
+
def send_linked_in_message!(sendto, subject, message)
|
41
|
+
send_message!({:sendto => sendto, :subject => subject, :message => message})
|
42
|
+
end
|
43
|
+
|
44
|
+
# Sends a message to a person using facebook. Params hash takes following keys:
|
45
|
+
# to(optional) :- Person's wall it's going to, if blank, is your own
|
46
|
+
# title :- [optional parameter] status message title
|
47
|
+
# url:- [optional parameter] any url that you want post in status message
|
48
|
+
# imageurl :- [optional parameter] any image url that you want post in status message
|
49
|
+
# status :- your status message
|
50
|
+
# caption : [optional parameter] caption that you want post in status message
|
51
|
+
# description :- [optional parameter] description that you want post in status message
|
52
|
+
#
|
53
|
+
# @param params [Hash]
|
54
|
+
# @return [Boolean] Whether or not message succeeded
|
55
|
+
def make_facebook_post!(params = {})
|
56
|
+
call_api("status/update/#{secret}/#{token}", params)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Sends a message to a person using facebook. Params hash takes following keys:
|
60
|
+
# to(optional) :- Person's wall it's going to, if blank, is your own
|
61
|
+
# title :- [optional parameter] status message title
|
62
|
+
# url:- [optional parameter] any url that you want post in status message
|
63
|
+
# imageurl :- [optional parameter] any image url that you want post in status message
|
64
|
+
# status :- your status message
|
65
|
+
# caption : [optional parameter] caption that you want post in status message
|
66
|
+
# description :- [optional parameter] description that you want post in status message
|
67
|
+
#
|
68
|
+
# @param params [Hash]
|
69
|
+
# @return [Boolean] Whether or not message succeeded
|
70
|
+
def make_facebook_post(params = {})
|
71
|
+
make_facebook_post!(params)
|
72
|
+
rescue LoginRadius::Exception => e
|
73
|
+
false
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
# Sends a message to a person. Will use either twitter, facebook or linked in, depending
|
79
|
+
# on where the person you're sending it to came from, and the keys present in the hash.
|
80
|
+
# Other methods in this module describe the keys they use, they all call this method
|
81
|
+
# with the proper keys for their service type.
|
82
|
+
#
|
83
|
+
# @param params [Hash] Params hash describing what you'd like to send.
|
84
|
+
# @return [Boolean] Whether or not message succeeded
|
85
|
+
def send_message!(params = {})
|
86
|
+
call_api("directmessage/#{secret}/#{token}",params)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Sends a message to a person. Will use either twitter, facebook or linked in, depending
|
90
|
+
# on where the person you're sending it to came from, and the keys present in the hash.
|
91
|
+
# Other methods in this module describe the keys they use, they all call this method
|
92
|
+
# with the proper keys for their service type.
|
93
|
+
#
|
94
|
+
# @param params [Hash] Params hash describing what you'd like to send.
|
95
|
+
# @return [Boolean] Whether or not message succeeded
|
96
|
+
def send_message(params = {})
|
97
|
+
send_message!(params)
|
98
|
+
rescue LoginRadius::Exception => e
|
99
|
+
false
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
module LoginRadius
|
3
|
+
class UserProfile
|
4
|
+
include UserProfileGetters
|
5
|
+
include Messages
|
6
|
+
|
7
|
+
attr_accessor :secret, :token, :async
|
8
|
+
|
9
|
+
API_ROOT = "https://hub.loginradius.com/"
|
10
|
+
|
11
|
+
# Takes a hash of account secret, token, and connection type(net_http or em_http)
|
12
|
+
# and uses it to auth against the LoginRadius API. Then it returns the Account object. The
|
13
|
+
# async key is optional, if set to true, will use Em::HTTP instead of Net::HTTP.
|
14
|
+
#
|
15
|
+
# @param opts [Hash] Must have keys :token, :secret, and :async(optional)
|
16
|
+
# @return [LoginRadius::Account]
|
17
|
+
def initialize(opts = {})
|
18
|
+
self.token = opts[:token]
|
19
|
+
self.secret = opts[:secret]
|
20
|
+
self.async = opts[:async]
|
21
|
+
raise LoginRadius::Exception.new("Invalid Request") unless token
|
22
|
+
raise LoginRadius::Exception.new("Invalid Token") unless guid_valid?(token)
|
23
|
+
raise LoginRadius::Exception.new("Invalid Secret") unless guid_valid?(secret)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Takes a guid and returns whether or not it is valid.
|
27
|
+
#
|
28
|
+
# @param guid [String]
|
29
|
+
# @return [Boolean]
|
30
|
+
def guid_valid?(guid)
|
31
|
+
guid.match(/^\{?[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12}\}?$/i)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns whether or not this object is authed.
|
35
|
+
#
|
36
|
+
# @return [Boolean]
|
37
|
+
def authenticated?
|
38
|
+
respond_to?(:id)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Generic GET call function that other submodules can use to hit the API.
|
42
|
+
#
|
43
|
+
# @param url [String] Target URL to fetch data from.
|
44
|
+
# @param params [Hash] Parameters to send
|
45
|
+
# @return data [Hash] Parsed JSON data from the call
|
46
|
+
def call_api(url, params = {})
|
47
|
+
url = API_ROOT+url unless url.match(/^#{API_ROOT}/) #in case api root is included,
|
48
|
+
#as would happen in a recursive redirect call.
|
49
|
+
|
50
|
+
if async
|
51
|
+
#UNTESTED
|
52
|
+
#if async is true, we expect you to be using EM::Synchrony submodule and to be in an eventloop,
|
53
|
+
#like with a thin server using the Cramp framework. Otherwise, this method blows up.
|
54
|
+
response = EM::Synchrony.sync EventMachine::HttpRequest.new(url).aget :redirects => 2, :query => params
|
55
|
+
response = response.response
|
56
|
+
else
|
57
|
+
#synchronous version of the call.
|
58
|
+
url_obj = URI.parse(url)
|
59
|
+
url_obj.query = URI.encode_www_form(params)
|
60
|
+
|
61
|
+
http = Net::HTTP.new(url_obj.host, url_obj.port)
|
62
|
+
http.use_ssl = true
|
63
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
64
|
+
response = http.get(url_obj.request_uri)
|
65
|
+
|
66
|
+
if response.is_a?(Net::HTTPTemporaryRedirect)
|
67
|
+
#for some reason, we always get redirected when calling server first time.
|
68
|
+
#so if we do, we scan body for the redirect url, and the scan returns
|
69
|
+
#an array of arrays. So we grab the array we know has what we need,
|
70
|
+
#and grab the first element.
|
71
|
+
redirect_url_array = response.body.scan(/<a href=\"([^>]+)\">/i)[1]
|
72
|
+
redirect_url = redirect_url_array.first
|
73
|
+
return call_api(redirect_url, params)
|
74
|
+
end
|
75
|
+
|
76
|
+
response = response.body
|
77
|
+
end
|
78
|
+
|
79
|
+
# For some reason, this API returns true/false instead of JSON responses for certain calls.
|
80
|
+
# We catch this here.
|
81
|
+
return true if response.match(/^true/i)
|
82
|
+
return false if response.match(/^false/i)
|
83
|
+
|
84
|
+
#We rescue this because sometimes the API returns HTML pages(which can't be JSON parsed)
|
85
|
+
#This mostly happens when people use expired tokens. So we go ahead and raise an exception
|
86
|
+
#About it if it gets caught.
|
87
|
+
begin
|
88
|
+
unconverted_response = JSON.parse(response)
|
89
|
+
#it's all String keys in CamelCase above, so...
|
90
|
+
# IF we got a hash back, convert it directly, if its an array, convert each item which is a hash
|
91
|
+
# into snake case
|
92
|
+
converted_response = unconverted_response.is_a?(Hash) ?
|
93
|
+
Hash.lr_convert_hash_keys(unconverted_response).symbolize_keys! :
|
94
|
+
unconverted_response.map { |item| Hash.lr_convert_hash_keys(item).symbolize_keys! }
|
95
|
+
|
96
|
+
return converted_response
|
97
|
+
rescue JSON::ParserError => e
|
98
|
+
raise LoginRadius::Exception.new("A JSON parsing error occured because the API returned an HTML page instead of JSON. This happens mostly when you're using an expired Token. Specifics: #{e.message}")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|