1 | var OAuth2 = require('oauth').OAuth2,
|
2 | querystring = require('querystring'),
|
3 | util = require('util'),
|
4 | task = require('./base');
|
5 |
|
6 |
|
7 |
|
8 | var facebookConfig = project.config.consumerConfig.facebook;
|
9 | var facebookScopes = (facebookConfig ? facebookConfig.scopes : null);
|
10 |
|
11 | if (!facebookScopes) {
|
12 |
|
13 | util.extend (facebookConfig, {
|
14 | "scopes": {
|
15 | "profile" : "user_about_me",
|
16 | "email" : "email",
|
17 | "activities" : "user_activities",
|
18 | "birthday" : "user_birthday",
|
19 | "checkins" : "user_checkins",
|
20 | "education_history" : "user_education_history",
|
21 | "events" : "user_events",
|
22 | "groups" : "user_groups",
|
23 | "hometown" : "user_hometown",
|
24 | "interests" : "user_interests",
|
25 | "likes" : "user_likes",
|
26 | "location" : "user_location",
|
27 | "notes" : "user_notes",
|
28 | "online_presence" : "user_online_presence",
|
29 | "photo_video_tags" : "user_photo_video_tags",
|
30 | "photos" : "user_photos",
|
31 | "questions" : "user_questions",
|
32 | "relationships" : "user_relationships",
|
33 | "relationship_details" : "user_relationship_details",
|
34 | "religion_politics" : "user_religion_politics",
|
35 | "status" : "user_status",
|
36 | "videos" : "user_videos",
|
37 | "website" : "user_website",
|
38 | "work_history" : "user_work_history",
|
39 | "contacts" : "read_friendlists",
|
40 | "insights" : "read_insights",
|
41 | "mailbox" : "read_mailbox",
|
42 | "requests" : "read_requests",
|
43 | "stream" : "read_stream",
|
44 | "xmpp_login" : "xmpp_login",
|
45 | "ads_management" : "ads_management",
|
46 | "create_event" : "create_event",
|
47 | "manage_friendlists" : "manage_friendlists",
|
48 | "manage_notifications" : "manage_notifications",
|
49 | "offline_access" : "offline_access",
|
50 | "publish_checkins" : "publish_checkins",
|
51 | "publish_stream" : "publish_stream",
|
52 | "rsvp_event" : "rsvp_event",
|
53 | "publish_actions" : "publish_actions",
|
54 | "publish_stream" : "publish_stream"
|
55 | }
|
56 | });
|
57 |
|
58 | facebookScopes = facebookConfig.scopes;
|
59 |
|
60 |
|
61 | }
|
62 |
|
63 |
|
64 |
|
65 | var facebook = module.exports = function(config) {
|
66 |
|
67 | this.scopes = [
|
68 | "profile",
|
69 | "contacts",
|
70 | "groups"
|
71 | ];
|
72 |
|
73 | this.init (config);
|
74 |
|
75 | };
|
76 |
|
77 | util.inherits (facebook, task);
|
78 |
|
79 | util.extend (facebook.prototype, {
|
80 |
|
81 | run: function() {
|
82 |
|
83 | var self = this;
|
84 | self.failed('use method [login|callback|profile|grouplist]');
|
85 |
|
86 | },
|
87 |
|
88 | login: function () {
|
89 |
|
90 | var self = this;
|
91 | var req = self.req;
|
92 | var res = self.res;
|
93 | var query = req.url.query;
|
94 |
|
95 | var scopes = self.scopes.map(function(scope) {
|
96 | return facebookScopes[scope];
|
97 | });
|
98 |
|
99 | var getParams = {
|
100 | client_id: facebookConfig.appId,
|
101 | redirect_uri: facebookConfig.callbackUrl,
|
102 | scope: scopes.join(',')
|
103 | };
|
104 |
|
105 | var redirectUrl = facebookConfig.requestTokenUrl + "?" + querystring.stringify(getParams);
|
106 |
|
107 | self.completed(redirectUrl);
|
108 | },
|
109 |
|
110 | callback: function() {
|
111 |
|
112 | var self = this,
|
113 | req = self.req;
|
114 | query = req.url.query;
|
115 |
|
116 | req.user.tokens = {};
|
117 |
|
118 | if (query.error || !query.code) {
|
119 |
|
120 | self.completed ({ error : query.error_description || "token was not accepted"});
|
121 | }
|
122 |
|
123 | var oa = new OAuth2(facebookConfig.appId, facebookConfig.appSecret, facebookConfig.baseUrl);
|
124 |
|
125 | oa.getOAuthAccessToken(
|
126 | query.code,
|
127 | {redirect_uri: facebookConfig.callbackUrl},
|
128 | function( error, access_token, refresh_token ){
|
129 |
|
130 | if (error) {
|
131 | self.failed(error);
|
132 | } else {
|
133 |
|
134 | req.user.tokens.oauth_access_token = access_token;
|
135 | if (refresh_token) req.user.tokens.oauth_refresh_token = refresh_token;
|
136 |
|
137 | var redirectUrl = (query.action && query.action != "") ? query.action : "/";
|
138 | self.completed (redirectUrl)
|
139 |
|
140 | }
|
141 | });
|
142 | },
|
143 |
|
144 | profile: function() {
|
145 | var self = this;
|
146 | var req = self.req;
|
147 | var tokens = req.user.tokens;
|
148 |
|
149 | var oa = new OAuth2(
|
150 | facebookConfig.appId,
|
151 | facebookConfig.appSecret,
|
152 | facebookConfig.baseUrl
|
153 | );
|
154 |
|
155 | oa.getProtectedResource(
|
156 | facebookConfig.baseUrl + '/me',
|
157 | tokens.oauth_access_token,
|
158 |
|
159 | function (error, data, response) {
|
160 | if (error) {
|
161 | self.failed(error);
|
162 | } else {
|
163 | try {
|
164 | var user = JSON.parse(data);
|
165 | user.tokens = tokens;
|
166 | self.completed(self.mappingUser(user));
|
167 | } catch (e) {
|
168 | self.failed(e);
|
169 | }
|
170 | }
|
171 | });
|
172 | },
|
173 |
|
174 | mappingUser: function(user) {
|
175 |
|
176 | var mapped = {
|
177 | name: user.name,
|
178 | username: user.username,
|
179 | link: user.link,
|
180 | tokens : user.tokens,
|
181 | authType: 'facebook'
|
182 | };
|
183 |
|
184 | var emailName;
|
185 |
|
186 | if (user.username) {
|
187 | emailName = user.username;
|
188 | mapped.avatar = 'http://graph.facebook.com/' +
|
189 | user.username + '/picture';
|
190 | } else {
|
191 | emailName = user.id;
|
192 | mapped.avatar = '';
|
193 | }
|
194 |
|
195 | mapped.externalId = user.id;
|
196 | mapped.email = user.email || (emailName + '@facebook.com');
|
197 |
|
198 | return mapped;
|
199 | },
|
200 |
|
201 | grouplist: function() {
|
202 |
|
203 | var self = this;
|
204 | var req = self.req;
|
205 | var tokens = req.user.tokens;
|
206 |
|
207 | var oa = new OAuth2(facebookConfig.appId, facebookConfig.appSecret, facebookConfig.baseUrl);
|
208 |
|
209 | oa.getProtectedResource(
|
210 | facebookConfig.baseUrl+"/me/groups",
|
211 | tokens.oauth_access_token,
|
212 | function (error, data, response) {
|
213 |
|
214 | if (error) {
|
215 | self.failed(error);
|
216 | } else {
|
217 | try {
|
218 | var groups = JSON.parse(data);
|
219 | self.completed(self.mappingGroups(groups));
|
220 | } catch (e) {
|
221 | self.failed(e);
|
222 | }
|
223 | }
|
224 | });
|
225 | },
|
226 |
|
227 | mappingGroups: function(groups) {
|
228 |
|
229 | var groupIds = groups.data.map(function(group) {
|
230 | return group.id;
|
231 | });
|
232 |
|
233 | return groupIds;
|
234 |
|
235 | },
|
236 |
|
237 | tmpl: function (str, obj) {
|
238 | return str.replace(
|
239 | /{\$(.+?)}/g,
|
240 | function (_, key) { return obj[key]; }
|
241 | );
|
242 | },
|
243 |
|
244 | searchFriends: function () {
|
245 | var self = this;
|
246 |
|
247 | var queryTpl = [
|
248 | 'SELECT username, name',
|
249 | 'FROM user',
|
250 | 'WHERE uid IN',
|
251 | '(SELECT uid2 FROM friend WHERE uid1 = me())',
|
252 | 'AND (',
|
253 | 'strpos(lower(name), "{$filter}") >= 0',
|
254 | 'OR strpos(lower(username), "{$filter}") >= 0',
|
255 | ')',
|
256 | 'ORDER BY name LIMIT {$start}, {$limit}'
|
257 | ].join(' ');
|
258 |
|
259 | var urlTpl = '/fql?q={$query}';
|
260 |
|
261 | var query = this.tmpl(queryTpl, this.pager);
|
262 | var url = this.tmpl(urlTpl, { query: query });
|
263 |
|
264 | var oa = new OAuth2(
|
265 | facebookConfig.appId,
|
266 | facebookConfig.appSecret,
|
267 | facebookConfig.baseUrl
|
268 | );
|
269 |
|
270 | oa.getProtectedResource(
|
271 | facebookConfig.baseUrl + url,
|
272 | this.req.user.tokens.oauth_access_token,
|
273 |
|
274 | function (error, data, response) {
|
275 | var items = JSON.parse(data);
|
276 |
|
277 | if (!error) {
|
278 | var users = items.data.map(function (user) {
|
279 | return self.mapFields(self.mappingUser(user));
|
280 | });
|
281 | }
|
282 |
|
283 | self.completed({
|
284 | data: users || null,
|
285 | total: users ? users.length : 0,
|
286 | success: !error,
|
287 | error: error
|
288 | });
|
289 | }
|
290 | );
|
291 | },
|
292 |
|
293 | post: function () {
|
294 | this._post('https://graph.facebook.com/me/feed');
|
295 | },
|
296 |
|
297 | customPost: function () {
|
298 | this._post(this.customUrl);
|
299 | },
|
300 |
|
301 | postPhoto: function () {
|
302 |
|
303 | this._post('https://graph.facebook.com/me/photos');
|
304 | },
|
305 |
|
306 | _post : function (url) {
|
307 | var self = this;
|
308 | var req = this.req;
|
309 | var tokens = req.user.tokens;
|
310 | var msg = this.message;
|
311 |
|
312 | var oa = new OAuth2(
|
313 | facebookConfig.appId,
|
314 | facebookConfig.appSecret,
|
315 | facebookConfig.baseUrl
|
316 | );
|
317 |
|
318 | var post_headers= {
|
319 | 'Content-Type': 'application/x-www-form-urlencoded'
|
320 | };
|
321 | var post_data = msg;
|
322 |
|
323 | oa._request(
|
324 | 'POST', url,
|
325 | post_headers, post_data, req.user.tokens.oauth_access_token,
|
326 | function (error, data) {
|
327 | if (error) {
|
328 | self.failed(error);
|
329 | } else {
|
330 | self.completed(JSON.parse(data));
|
331 | }
|
332 | }
|
333 | );
|
334 |
|
335 | }
|
336 | });
|