Mercurial > pumpbridge
view src/facebook.coffee @ 13:58a069d12b0c
edit INSTALL.md and use correct params in pumpbridge.json
author | Mathias Gebbe <mgebbe@intevation.de> |
---|---|
date | Thu, 12 Jun 2014 10:34:02 +0200 |
parents | f190abf340ef |
children | c1b736a859c9 |
line wrap: on
line source
# Copyright (C) 2014 by Intevation GmbH # Author: Mathias Gebbe <mgebbe@intevation.de> # # This file is Free Software under the Apache License, Version 2.0; # and comes with NO WARRANTY! # See the documentation coming with pumpbridge 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?) or posts.length is 0 #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 is 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) -> if (dbuser[0]?) Sync.postParser post, dbuser[0], 'facebook', callback else return (parsed, callback) -> Pump.postUser bridgeid, me, parsed, callback (pumppost, callback) -> pumppost = JSON.parse(pumppost) if (post.actions[1].link?) postlink = post.actions[1].link else postlink = post.actions[0].link FromESN.create postid: post.id + "@facebook" sourceUser: post.from.id sourcePost: postlink 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) -> if fromesn.sourcePost.indexOf('www.facebook.com') is -1 return Usermap.search {id: me + '_to_' + me}, cb (pumpuser, cb) -> Pump.getNote(pumpuser[0], fromesn.pumpPost, cb) (note, cb) -> return if not (note?) if 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) -> interval = config.interval if not (interval?) interval = 15 * 60 * 1000 # 900 000 ms (15min) ti = new Date().getTime() - interval async.eachSeries feed.items, ((post, callback) -> # do for each post ts = Date.parse(post.updated) if (ts >= ti and 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 not (post.object.deleted?) 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", () -> if (data?) try user = JSON.parse(data) ### with app id ### Routes.updateUserDB(user.id+'@facebook',user.name,user.name,user.link,user.picture.data.url) if user? ### with link ### Routes.updateUserDB(user.link,user.name,user.name,user.link,user.picture.data.url) if user? catch err console.log "User Error" return ).on "error", (e) -> console.log "Got error: " + e.message return ############################################## ###### get facebook likes ###### ############################################## getFriends = (user) -> me = user.user_pumpio token = user.oauth_token FB.setAccessToken token FB.api "me/friends?limit=5000", fields: [ "id" ] , (res) -> console.log res if not res or res.error console.log (if not res then "error occurred" else res.error) _.each res.data, (person) -> getUserById(me,person.id,token) return return ####################################### ###### get user facebook3 ##### ####################################### getFriends3 = (user) -> data = "" id = user.user_ESN.substr(0,user.user_ESN.indexOf('@')) token = user.oauth_token options = host: 'graph.facebook.com' port: 443 path: 'me/friends?limit=5000&access_token=' + token + '&client_id='+ appid + '&client_secret=' + secret https.get(options, (res) -> console.log "Got response: " + res.statusCode res.on "data", (chunk) -> data += chunk return res.on "end", () -> console.log data return ).on "error", (e) -> console.log "Got error: " + e.message return ############################################## ###### get facebook friends2 ###### ############################################## getFriends2 = (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) -> console.log 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) return return return ############################################## ###### get facebook likes ###### ############################################## getPages = (user) -> me = user.user_pumpio token = user.oauth_token FB.setAccessToken token FB.api "me/likes?limit=5000", 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) return return ####################################### ###### get facebook stream ###### ####################################### getStream = (user,callback) -> token = user.oauth_token interval = config.interval if not (interval?) interval = 15 * 60 * 1000 # 900 000 ms (15min) ts = Math.round(((new Date()).getTime() - interval)/1000) FB.setAccessToken token FB.api "me/home?limit=35&?since="+ts, 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 text = "" FB.setAccessToken token return if not post.object.content? or post.object.content is "" ToESN.search {uid: post.object.id + "@facebook"}, (err, result) -> if result.length is 0 body = post.object.content.replace(/<(?:.|\n)*?>/gm, '') + " " + post.object.url if post.verb is "share" text = post.object.author.url + " wrotes:" FB.api "me/feed", "post", message: text + 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 + "@facebook" 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 + '&client_secret=' + secret + '&' + 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) if data? #### with app user id ### if user? Routes.updateUserDB(user.id+'@facebook',user.name,user.name,user.link,user.picture.data.url) EdgeControl.addEdge(me,user.id+'@facebook') #### with profile url ### Routes.updateUserDB(user.link,user.name,user.name,user.link,user.picture.data.url) EdgeControl.addEdge(me,user.link) 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