Mercurial > pumpbridge
comparison src/facebook.coffee @ 0:b73191efc65b
Initial import of pumpbridge (bloody bloody alpha)
author | Mathias Gebbe <mgebbe@intevation.de> |
---|---|
date | Thu, 05 Jun 2014 10:35:15 +0200 |
parents | |
children | 98a070c98982 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:b73191efc65b |
---|---|
1 # Copyright (C) 2014 by Intevation GmbH | |
2 # Author: Mathias Gebbe <mgebbe@intevation.de> | |
3 # | |
4 # This file is Free Software under the Apache License, Version 2.0 | |
5 # (the "License"); and comes with ABSOLUTELY NO WARRANTY! | |
6 # You may not use this file except in compliance with the License. | |
7 # See LICENSE for details. | |
8 | |
9 https = require("https") | |
10 async = require("async") | |
11 _ = require("underscore") | |
12 Routes = require("./routes") | |
13 FB = require('fb') | |
14 EdgeControl = require("./edgecontrol") | |
15 Edge = require("./edge") | |
16 CommentToESN = require("./commenttoesn") | |
17 ToESN = require("./toESN") | |
18 FromESN = require("./fromESN") | |
19 Pump = require("./pumpio") | |
20 User = require("./user") | |
21 Sync = require("./sync") | |
22 Usermap = require("./usermap") | |
23 Config = require("./config") | |
24 | |
25 config = Config.config | |
26 | |
27 bridgeid = config.bridgeid | |
28 secret = config.fbSECRET | |
29 appid = config.fbAPPID | |
30 | |
31 ####################################### | |
32 ###### facebook sync ##### | |
33 ####################################### | |
34 | |
35 sync = (user) -> | |
36 me = user.user_pumpio | |
37 id = user.user_ESN.substr(0,user.user_ESN.indexOf('@')) | |
38 pubuser = "" | |
39 post = "" | |
40 | |
41 # GET NEW POSTS | |
42 #### | |
43 async.waterfall [ | |
44 (callback) -> | |
45 getFriends(user) | |
46 getPages(user) | |
47 getUser(user) | |
48 getStream user,callback | |
49 ], (err, posts) -> | |
50 return if not (posts?) | |
51 #console.log JSON.stringify(posts) # all posts from network (100) | |
52 async.eachSeries posts, ((post, callback) -> | |
53 | |
54 async.waterfall [ | |
55 (callback) -> | |
56 FromESN.search {uid: post.id + "@facebook_to_" + me, recipientUser: me}, callback | |
57 (result, callback) -> | |
58 return if result.length isnt 0 or post.from.id == id | |
59 #console.log "postid: " + post.from.id + "id:" + id | |
60 # if this is your own post return!!! | |
61 getPublicUserInfo(post.from.id , callback) | |
62 (pubuser, callback) -> | |
63 pubuser = pubuser | |
64 User.search {id: pubuser.id + "@facebook"}, callback | |
65 (dbuser, callback) -> | |
66 Sync.postParser post, dbuser[0], 'facebook', callback | |
67 (parsed, callback) -> | |
68 Pump.postUser bridgeid, me, parsed, callback | |
69 (pumppost, callback) -> | |
70 pumppost = JSON.parse(pumppost) | |
71 FromESN.create | |
72 postid: post.id + "@facebook" | |
73 sourceUser: post.from.id | |
74 sourcePost: post.actions[0].link | |
75 pumpPost: pumppost.object.id | |
76 recipientUser: me | |
77 created: Date.now() | |
78 , callback | |
79 ], (err, result) -> | |
80 #console.log result | |
81 #console.log 'done.' | |
82 callback null, 'done' | |
83 ), (err) -> | |
84 if err | |
85 console.log 'one post fail to process' | |
86 else | |
87 console.log 'all posts processed' | |
88 return | |
89 #### | |
90 # TO DO: GET NEW COMMENTS | |
91 # for each fromESN check the comments | |
92 # if comment author = me | |
93 # post comment | |
94 # if comment author != me | |
95 # post comment with 'user schreibt' | |
96 async.waterfall [ | |
97 (callback) -> | |
98 FromESN.search {recipientUser: me}, callback | |
99 (allESN, callback) -> | |
100 async.each allESN, ((fromesn, callback) -> | |
101 async.waterfall [ | |
102 (cb) -> | |
103 cb (true) if fromesn.sourcePost.indexOf('www.facebook.com') is -1 | |
104 Usermap.search {id: me + '_to_' + me}, cb | |
105 (pumpuser, cb) -> | |
106 Pump.getNote(pumpuser[0], fromesn.pumpPost, cb) | |
107 (note, cb) -> | |
108 if note.liked is not undefined and note.liked is true | |
109 obj = fromesn.postid.substr(0,fromesn.postid.indexOf('@')) | |
110 postLike(user,obj) | |
111 if (note.replies?) | |
112 reply = JSON.stringify(note.replies) | |
113 rep = JSON.parse(reply) | |
114 if rep.totalItems >= 1 | |
115 async.each rep.items, ((r, callback) -> | |
116 if r.author.id is "acct:" + me | |
117 obj = fromesn.postid.substr(0,fromesn.postid.indexOf('@')) | |
118 postComment(user, obj, r.id , r.content) | |
119 callback null, 'done' | |
120 ), (err) -> | |
121 cb null, 'done' | |
122 ], (err, result) -> | |
123 #done | |
124 ), (err) -> | |
125 callback null, 'done' | |
126 ], (err, result) -> | |
127 #done | |
128 | |
129 | |
130 # GET PUBLIC PUMP POSTS AND POST THEM | |
131 async.waterfall [ | |
132 (callback) -> | |
133 Usermap.search {id: me + '_to_' + me}, callback | |
134 (user, callback) -> | |
135 Pump.getUserFeed(user[0],callback) | |
136 (feed, callback) -> | |
137 async.eachSeries feed.items, ((post, callback) -> | |
138 # do for each post | |
139 if (post.verb is "post" or post.verb is "share") and (post.object.objectType is "note" or post.object.objectType is "image") and (Pump.isPublicActivity(post)) and (typeof post.object.deleted is "undefined") | |
140 postStream(user,post) | |
141 callback null, 'done' | |
142 ), (err) -> | |
143 callback null, 'done' | |
144 ],(err, result) -> | |
145 #console.log 'done.' | |
146 | |
147 return | |
148 | |
149 | |
150 ####################################### | |
151 ###### get user facebook ##### | |
152 ####################################### | |
153 getUser = (user) -> | |
154 data = "" | |
155 id = user.user_ESN.substr(0,user.user_ESN.indexOf('@')) | |
156 token = user.oauth_token | |
157 fields = 'fields=id,name,picture,link' | |
158 options = | |
159 host: 'graph.facebook.com' | |
160 port: 443 | |
161 path: '/' + id + '?access_token=' + token + '&' + fields | |
162 | |
163 https.get(options, (res) -> | |
164 #console.log "Got response: " + res.statusCode | |
165 | |
166 res.on "data", (chunk) -> | |
167 data += chunk | |
168 return | |
169 | |
170 res.on "end", () -> | |
171 user = JSON.parse(data) | |
172 ### with app id ### | |
173 Routes.updateUserDB(user.id+'@facebook',user.name,user.name,user.link,user.picture.data.url) unless typeof user is "undefined" | |
174 ### with link ### | |
175 Routes.updateUserDB(user.link,user.name,user.name,user.link,user.picture.data.url) unless typeof user is "undefined" | |
176 return | |
177 | |
178 ).on "error", (e) -> | |
179 console.log "Got error: " + e.message | |
180 | |
181 return | |
182 | |
183 ############################################## | |
184 ###### get facebook friends /remove all ###### | |
185 ############################################## | |
186 getFriends = (user) -> | |
187 me = user.user_pumpio | |
188 id = user.user_ESN.substr(0,user.user_ESN.indexOf('@')) | |
189 token = user.oauth_token | |
190 | |
191 EdgeControl.removeEdges(me,'@facebook') | |
192 EdgeControl.removeEdges(me,'www.facebook.com') | |
193 | |
194 FB.setAccessToken token | |
195 FB.api "fql", | |
196 q: "SELECT uid2 FROM friend WHERE uid1 = me()" | |
197 , (res) -> | |
198 if not res or res.error | |
199 console.log (if not res then "error occurred" else res.error) | |
200 return | |
201 | |
202 _.each res.data, (user) -> | |
203 getUserById(me,user.uid2,token) unless typeof user.id is "undefined" | |
204 return | |
205 | |
206 return | |
207 | |
208 return | |
209 | |
210 ############################################## | |
211 ###### get facebook likes ###### | |
212 ############################################## | |
213 getPages = (user) -> | |
214 me = user.user_pumpio | |
215 token = user.oauth_token | |
216 | |
217 FB.setAccessToken token | |
218 | |
219 FB.api "me/likes?limit=1000&", | |
220 fields: [ | |
221 "id" | |
222 ] | |
223 , (res) -> | |
224 if not res or res.error | |
225 console.log (if not res then "error occurred" else res.error) | |
226 | |
227 _.each res.data, (page) -> | |
228 getUserById(me,page.id,token) unless typeof user.id is "undefined" | |
229 return | |
230 | |
231 | |
232 return | |
233 | |
234 | |
235 ####################################### | |
236 ###### get facebook stream ###### | |
237 ####################################### | |
238 getStream = (user,callback) -> | |
239 token = user.oauth_token | |
240 | |
241 FB.setAccessToken token | |
242 | |
243 FB.api "me/home?limit=25&", | |
244 fields: [ | |
245 "id" | |
246 "type" | |
247 "from" | |
248 "privacy" | |
249 "message" | |
250 "picture" | |
251 "link" | |
252 "status_type" | |
253 "caption" | |
254 "created_time" | |
255 "updated_time" | |
256 "picture" | |
257 "actions" | |
258 ] | |
259 , (res) -> | |
260 if not res or res.error | |
261 console.log (if not res then "error occurred" else res.error) | |
262 callback null, null | |
263 | |
264 newposts = new Array() | |
265 _.each res.data, (post) -> | |
266 newposts.push(post) if (post.type is 'status' or post.type is 'photo' or post.type is 'link' or post.type is 'video') and (post.status_type is 'mobile_status_update' or post.status_type is 'added_photos' or post.status_type is 'shared_story') | |
267 | |
268 callback null, newposts.reverse() | |
269 | |
270 ####################################### | |
271 ###### post facebook stream ###### | |
272 ####################################### | |
273 postStream = (user, post) -> | |
274 token = user.oauth_token | |
275 | |
276 FB.setAccessToken token | |
277 | |
278 return if typeof post.object.content is "undefined" or post.object.content is "" | |
279 ToESN.search {uid: post.object.id }, (err, result) -> | |
280 if result.length is 0 | |
281 body = post.object.content.replace(/<(?:.|\n)*?>/gm, '') + " " + post.object.url | |
282 | |
283 FB.api "me/feed", "post", | |
284 message: body | |
285 , (res) -> | |
286 if not res or res.error | |
287 console.log (if not res then "error occurred" else res.error) | |
288 return | |
289 | |
290 async.waterfall [ | |
291 (callback) -> | |
292 savePost = new ToESN() | |
293 savePost.uid = post.object.id | |
294 savePost.sourceUser = post.actor.id | |
295 savePost.sourcePost = post.object.id | |
296 savePost.targetUser = user.user_ESN | |
297 savePost.targetPost = res.id | |
298 savePost.recipientUser = 'public' | |
299 savePost.updated = Date.now() | |
300 savePost.save callback | |
301 ], (err, result) -> | |
302 | |
303 return | |
304 | |
305 return | |
306 | |
307 ################################################## | |
308 ###### post comment to facebook stream ###### | |
309 ################################################## | |
310 postComment = (user, object_id, pumpid, text) -> | |
311 | |
312 # check if the comment is allready posted (search bla return) | |
313 | |
314 CommentToESN.search { uid: pumpid + "_to_" + "https://facebook.com/" + object_id}, (err, result) -> | |
315 if result.length is 0 | |
316 token = user.oauth_token | |
317 text = text.replace /<(?:.|\n)*?>/g, "" | |
318 | |
319 FB.setAccessToken token | |
320 | |
321 FB.api "" + object_id + "/comments", "POST", | |
322 message: text | |
323 , (res) -> | |
324 if not res or res.error | |
325 console.log (if not res then "error occurred" else res.error) | |
326 return | |
327 | |
328 CommentToESN.create | |
329 ESNPost: "https://facebook.com/" + object_id | |
330 pumpComment: pumpid | |
331 created: Date.now() | |
332 , (err, result) -> | |
333 console.log 'comment saved' | |
334 | |
335 return | |
336 | |
337 ################################################## | |
338 ###### like post on facebook stream ###### | |
339 ################################################## | |
340 postLike = (user, object_id) -> | |
341 token = user.oauth_token | |
342 FB.setAccessToken token | |
343 | |
344 FB.api "" + object_id + "/likes", "POST" | |
345 , (res) -> | |
346 if not res or res.error | |
347 console.log (if not res then "error occurred" else res.error) | |
348 return | |
349 | |
350 console.log 'liked' | |
351 return | |
352 | |
353 return | |
354 | |
355 | |
356 ###################################################################### | |
357 ###### get user facebook by id and add him to UserDB and EDGES ##### | |
358 ###################################################################### | |
359 getUserById = (me,id,token) -> | |
360 data = "" | |
361 token = token | |
362 fields = 'fields=id,name,picture,link' | |
363 options = | |
364 host: 'graph.facebook.com' | |
365 port: 443 | |
366 path: '/' + id + '?access_token=' + token + '&' + fields | |
367 | |
368 https.get(options, (res) -> | |
369 #console.log "Got response: " + res.statusCode | |
370 | |
371 res.on "data", (chunk) -> | |
372 data += chunk | |
373 return | |
374 | |
375 res.on "end", () -> | |
376 user = JSON.parse(data) unless data isnt "undefined" | |
377 | |
378 #### with app user id ### | |
379 Routes.updateUserDB(user.id+'@facebook',user.name,user.name,user.link,user.picture.data.url) unless typeof user is "undefined" | |
380 EdgeControl.addEdge(me,user.id+'@facebook') unless typeof user is "undefined" | |
381 | |
382 #### with profile url ### | |
383 Routes.updateUserDB(user.link,user.name,user.name,user.link,user.picture.data.url) unless typeof user is "undefined" | |
384 EdgeControl.addEdge(me,user.link) unless typeof user is "undefined" | |
385 | |
386 | |
387 return | |
388 | |
389 ).on "error", (e) -> | |
390 console.log "Got error: " + e.message | |
391 | |
392 return | |
393 | |
394 | |
395 ###################################################################### | |
396 ###### get user facebook by id and add him to UserDB and EDGES ##### | |
397 ###################################################################### | |
398 getPublicUserInfo = (id, callback) -> | |
399 | |
400 FB.api ""+id, | |
401 (res) -> | |
402 if not res or res.error | |
403 console.log (if not res then "error occurred" else res.error) | |
404 callback null,res | |
405 | |
406 return | |
407 | |
408 ###################################################################### | |
409 ###### get facebook long lived token ##### | |
410 ###################################################################### | |
411 getLongLivedToken = (token, callback) -> | |
412 data = "" | |
413 options = | |
414 host: 'graph.facebook.com' | |
415 port: 443 | |
416 path: '/oauth/access_token?' + 'grant_type=fb_exchange_token&client_id='+ appid + '&client_secret=' + secret + '&fb_exchange_token=' + token + '' | |
417 | |
418 https.get(options, (res) -> | |
419 res.on "data", (chunk) -> | |
420 data += chunk | |
421 return | |
422 | |
423 res.on "end", () -> | |
424 # returns --> "access_token=CAAK9efmXh2IBAAm9abitB98TvF6HHF5ducYDkV5PBrooG6MVNoP9eOy06yvyL0hMKQVzh1xvJPM8XMAYe8L0ZARzZCdolahSymrZCDXN2ZAfr0aIFbWocr8K5DMLu64ZD&expires=5183792" | |
425 ltoken = JSON.stringify(data) | |
426 callback ltoken.substring(ltoken.indexOf('=')+1,ltoken.indexOf('&')) | |
427 return | |
428 | |
429 ).on "error", (e) -> | |
430 console.log "Got error: " + e.message | |
431 | |
432 return | |
433 | |
434 exports.getUser = getUser | |
435 exports.getPages = getPages | |
436 exports.getStream = getStream | |
437 exports.getFriends = getFriends | |
438 exports.postStream = postStream | |
439 exports.getLongLivedToken = getLongLivedToken | |
440 exports.getPublicUserInfo = getPublicUserInfo | |
441 exports.getUserById = getUserById | |
442 exports.sync = sync |