login_radius 0.0.1
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.
- 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
|