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
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)