Mercurial > pumpbridge
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/facebook.coffee Thu Jun 05 10:35:15 2014 +0200 @@ -0,0 +1,442 @@ +# Copyright (C) 2014 by Intevation GmbH +# Author: Mathias Gebbe <mgebbe@intevation.de> +# +# This file is Free Software under the Apache License, Version 2.0 +# (the "License"); and comes with ABSOLUTELY NO WARRANTY! +# You may not use this file except in compliance with the License. +# See LICENSE for details. + +https = require("https") +async = require("async") +_ = require("underscore") +Routes = require("./routes") +FB = require('fb') +EdgeControl = require("./edgecontrol") +Edge = require("./edge") +CommentToESN = require("./commenttoesn") +ToESN = require("./toESN") +FromESN = require("./fromESN") +Pump = require("./pumpio") +User = require("./user") +Sync = require("./sync") +Usermap = require("./usermap") +Config = require("./config") + +config = Config.config + +bridgeid = config.bridgeid +secret = config.fbSECRET +appid = config.fbAPPID + +####################################### +###### facebook sync ##### +####################################### + +sync = (user) -> + me = user.user_pumpio + id = user.user_ESN.substr(0,user.user_ESN.indexOf('@')) + pubuser = "" + post = "" + + # GET NEW POSTS + #### + async.waterfall [ + (callback) -> + getFriends(user) + getPages(user) + getUser(user) + getStream user,callback + ], (err, posts) -> + return if not (posts?) + #console.log JSON.stringify(posts) # all posts from network (100) + async.eachSeries posts, ((post, callback) -> + + async.waterfall [ + (callback) -> + FromESN.search {uid: post.id + "@facebook_to_" + me, recipientUser: me}, callback + (result, callback) -> + return if result.length isnt 0 or post.from.id == id + #console.log "postid: " + post.from.id + "id:" + id + # if this is your own post return!!! + getPublicUserInfo(post.from.id , callback) + (pubuser, callback) -> + pubuser = pubuser + User.search {id: pubuser.id + "@facebook"}, callback + (dbuser, callback) -> + Sync.postParser post, dbuser[0], 'facebook', callback + (parsed, callback) -> + Pump.postUser bridgeid, me, parsed, callback + (pumppost, callback) -> + pumppost = JSON.parse(pumppost) + FromESN.create + postid: post.id + "@facebook" + sourceUser: post.from.id + sourcePost: post.actions[0].link + pumpPost: pumppost.object.id + recipientUser: me + created: Date.now() + , callback + ], (err, result) -> + #console.log result + #console.log 'done.' + callback null, 'done' + ), (err) -> + if err + console.log 'one post fail to process' + else + console.log 'all posts processed' + return + #### + # TO DO: GET NEW COMMENTS + # for each fromESN check the comments + # if comment author = me + # post comment + # if comment author != me + # post comment with 'user schreibt' + async.waterfall [ + (callback) -> + FromESN.search {recipientUser: me}, callback + (allESN, callback) -> + async.each allESN, ((fromesn, callback) -> + async.waterfall [ + (cb) -> + cb (true) if fromesn.sourcePost.indexOf('www.facebook.com') is -1 + Usermap.search {id: me + '_to_' + me}, cb + (pumpuser, cb) -> + Pump.getNote(pumpuser[0], fromesn.pumpPost, cb) + (note, cb) -> + if note.liked is not undefined and note.liked is true + obj = fromesn.postid.substr(0,fromesn.postid.indexOf('@')) + postLike(user,obj) + if (note.replies?) + reply = JSON.stringify(note.replies) + rep = JSON.parse(reply) + if rep.totalItems >= 1 + async.each rep.items, ((r, callback) -> + if r.author.id is "acct:" + me + obj = fromesn.postid.substr(0,fromesn.postid.indexOf('@')) + postComment(user, obj, r.id , r.content) + callback null, 'done' + ), (err) -> + cb null, 'done' + ], (err, result) -> + #done + ), (err) -> + callback null, 'done' + ], (err, result) -> + #done + + + # GET PUBLIC PUMP POSTS AND POST THEM + async.waterfall [ + (callback) -> + Usermap.search {id: me + '_to_' + me}, callback + (user, callback) -> + Pump.getUserFeed(user[0],callback) + (feed, callback) -> + async.eachSeries feed.items, ((post, callback) -> + # do for each post + 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") + postStream(user,post) + callback null, 'done' + ), (err) -> + callback null, 'done' + ],(err, result) -> + #console.log 'done.' + + return + + +####################################### +###### get user facebook ##### +####################################### +getUser = (user) -> + data = "" + id = user.user_ESN.substr(0,user.user_ESN.indexOf('@')) + token = user.oauth_token + fields = 'fields=id,name,picture,link' + options = + host: 'graph.facebook.com' + port: 443 + path: '/' + id + '?access_token=' + token + '&' + fields + + https.get(options, (res) -> + #console.log "Got response: " + res.statusCode + + res.on "data", (chunk) -> + data += chunk + return + + res.on "end", () -> + user = JSON.parse(data) + ### with app id ### + Routes.updateUserDB(user.id+'@facebook',user.name,user.name,user.link,user.picture.data.url) unless typeof user is "undefined" + ### with link ### + Routes.updateUserDB(user.link,user.name,user.name,user.link,user.picture.data.url) unless typeof user is "undefined" + return + + ).on "error", (e) -> + console.log "Got error: " + e.message + + return + +############################################## +###### get facebook friends /remove all ###### +############################################## +getFriends = (user) -> + me = user.user_pumpio + id = user.user_ESN.substr(0,user.user_ESN.indexOf('@')) + token = user.oauth_token + + EdgeControl.removeEdges(me,'@facebook') + EdgeControl.removeEdges(me,'www.facebook.com') + + FB.setAccessToken token + FB.api "fql", + q: "SELECT uid2 FROM friend WHERE uid1 = me()" + , (res) -> + if not res or res.error + console.log (if not res then "error occurred" else res.error) + return + + _.each res.data, (user) -> + getUserById(me,user.uid2,token) unless typeof user.id is "undefined" + return + + return + + return + +############################################## +###### get facebook likes ###### +############################################## +getPages = (user) -> + me = user.user_pumpio + token = user.oauth_token + + FB.setAccessToken token + + FB.api "me/likes?limit=1000&", + fields: [ + "id" + ] + , (res) -> + if not res or res.error + console.log (if not res then "error occurred" else res.error) + + _.each res.data, (page) -> + getUserById(me,page.id,token) unless typeof user.id is "undefined" + return + + + return + + +####################################### +###### get facebook stream ###### +####################################### +getStream = (user,callback) -> + token = user.oauth_token + + FB.setAccessToken token + + FB.api "me/home?limit=25&", + fields: [ + "id" + "type" + "from" + "privacy" + "message" + "picture" + "link" + "status_type" + "caption" + "created_time" + "updated_time" + "picture" + "actions" + ] + , (res) -> + if not res or res.error + console.log (if not res then "error occurred" else res.error) + callback null, null + + newposts = new Array() + _.each res.data, (post) -> + 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') + + callback null, newposts.reverse() + +####################################### +###### post facebook stream ###### +####################################### +postStream = (user, post) -> + token = user.oauth_token + + FB.setAccessToken token + + return if typeof post.object.content is "undefined" or post.object.content is "" + ToESN.search {uid: post.object.id }, (err, result) -> + if result.length is 0 + body = post.object.content.replace(/<(?:.|\n)*?>/gm, '') + " " + post.object.url + + FB.api "me/feed", "post", + message: body + , (res) -> + if not res or res.error + console.log (if not res then "error occurred" else res.error) + return + + async.waterfall [ + (callback) -> + savePost = new ToESN() + savePost.uid = post.object.id + savePost.sourceUser = post.actor.id + savePost.sourcePost = post.object.id + savePost.targetUser = user.user_ESN + savePost.targetPost = res.id + savePost.recipientUser = 'public' + savePost.updated = Date.now() + savePost.save callback + ], (err, result) -> + + return + + return + +################################################## +###### post comment to facebook stream ###### +################################################## +postComment = (user, object_id, pumpid, text) -> + +# check if the comment is allready posted (search bla return) + + CommentToESN.search { uid: pumpid + "_to_" + "https://facebook.com/" + object_id}, (err, result) -> + if result.length is 0 + token = user.oauth_token + text = text.replace /<(?:.|\n)*?>/g, "" + + FB.setAccessToken token + + FB.api "" + object_id + "/comments", "POST", + message: text + , (res) -> + if not res or res.error + console.log (if not res then "error occurred" else res.error) + return + + CommentToESN.create + ESNPost: "https://facebook.com/" + object_id + pumpComment: pumpid + created: Date.now() + , (err, result) -> + console.log 'comment saved' + + return + +################################################## +###### like post on facebook stream ###### +################################################## +postLike = (user, object_id) -> + token = user.oauth_token + FB.setAccessToken token + + FB.api "" + object_id + "/likes", "POST" + , (res) -> + if not res or res.error + console.log (if not res then "error occurred" else res.error) + return + + console.log 'liked' + return + + return + + +###################################################################### +###### get user facebook by id and add him to UserDB and EDGES ##### +###################################################################### +getUserById = (me,id,token) -> + data = "" + token = token + fields = 'fields=id,name,picture,link' + options = + host: 'graph.facebook.com' + port: 443 + path: '/' + id + '?access_token=' + token + '&' + fields + + https.get(options, (res) -> + #console.log "Got response: " + res.statusCode + + res.on "data", (chunk) -> + data += chunk + return + + res.on "end", () -> + user = JSON.parse(data) unless data isnt "undefined" + + #### with app user id ### + Routes.updateUserDB(user.id+'@facebook',user.name,user.name,user.link,user.picture.data.url) unless typeof user is "undefined" + EdgeControl.addEdge(me,user.id+'@facebook') unless typeof user is "undefined" + + #### with profile url ### + Routes.updateUserDB(user.link,user.name,user.name,user.link,user.picture.data.url) unless typeof user is "undefined" + EdgeControl.addEdge(me,user.link) unless typeof user is "undefined" + + + return + + ).on "error", (e) -> + console.log "Got error: " + e.message + + return + + +###################################################################### +###### get user facebook by id and add him to UserDB and EDGES ##### +###################################################################### +getPublicUserInfo = (id, callback) -> + + FB.api ""+id, + (res) -> + if not res or res.error + console.log (if not res then "error occurred" else res.error) + callback null,res + + return + +###################################################################### +###### get facebook long lived token ##### +###################################################################### +getLongLivedToken = (token, callback) -> + data = "" + options = + host: 'graph.facebook.com' + port: 443 + path: '/oauth/access_token?' + 'grant_type=fb_exchange_token&client_id='+ appid + '&client_secret=' + secret + '&fb_exchange_token=' + token + '' + + https.get(options, (res) -> + res.on "data", (chunk) -> + data += chunk + return + + res.on "end", () -> + # returns --> "access_token=CAAK9efmXh2IBAAm9abitB98TvF6HHF5ducYDkV5PBrooG6MVNoP9eOy06yvyL0hMKQVzh1xvJPM8XMAYe8L0ZARzZCdolahSymrZCDXN2ZAfr0aIFbWocr8K5DMLu64ZD&expires=5183792" + ltoken = JSON.stringify(data) + callback ltoken.substring(ltoken.indexOf('=')+1,ltoken.indexOf('&')) + return + + ).on "error", (e) -> + console.log "Got error: " + e.message + + return + +exports.getUser = getUser +exports.getPages = getPages +exports.getStream = getStream +exports.getFriends = getFriends +exports.postStream = postStream +exports.getLongLivedToken = getLongLivedToken +exports.getPublicUserInfo = getPublicUserInfo +exports.getUserById = getUserById +exports.sync = sync