Mercurial > pumpbridge
view 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 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 # (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