view src/twitter.coffee @ 7:2123f355ab68

go back interval or 15 min, delete credentials, layout
author Mathias Gebbe <mgebbe@intevation.de>
date Wed, 11 Jun 2014 02:32:53 +0200
parents af9f5b94c019
children 6fd0a307850f
line wrap: on
line source
# twitter.js
#
# data object representing twitter.com
#
# Copyright 2013, E14N (https://e14n.com/)
# all changes Copyright 2014, Intevation GmbH (https://intevation.org)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

_ = require("underscore")
async = require("async")
OAuth = require("oauth").OAuth
PumpIOClientApp = require("pump.io-client-app")
DatabankObject = require("databank").DatabankObject
RequestToken = PumpIOClientApp.RequestToken
Usermap = require("./usermap")
Pump = require("./pumpio")
FromESN = require("./fromESN")
ToESN = require("./toESN")
Sync = require("./sync")

module.exports = (config) ->
  bridgeid = config.bridgeid
  client_id = config.twclient_id
  client_secret = config.twclient_secret
  interval = config.interval
  if not (interval?)
    interval =  15 * 60 * 1000
  request_token_endpoint = "https://api.twitter.com/oauth/request_token"
  access_token_endpoint = "https://api.twitter.com/oauth/access_token"
  authorization_endpoint = "https://api.twitter.com/oauth/authorize"
  whoami_endpoint = "https://api.twitter.com/1.1/account/verify_credentials.json"
  hostname = "twitter.com"

  Twitter =
    getRequestToken: (site, callback) ->
      oa = Twitter.getOAuth(site)
      async.waterfall [
        (callback) ->
          oa.getOAuthRequestToken callback
        (token, secret, other, callback) ->
          RequestToken.create
            token: token
            secret: secret
            hostname: hostname
          , callback
      ], callback
      return

    authorizeURL: (rt) ->
      separator = undefined
      if _.contains(authorization_endpoint, "?")
        separator = "&"
      else
        separator = "?"
      authorization_endpoint + separator + "oauth_token=" + rt.token

    getAccessToken: (site, rt, verifier, callback) ->
      oa = Twitter.getOAuth(site)
      oa.getOAuthAccessToken rt.token, rt.secret, verifier, callback
      return

    whoami: (site, token, secret, callback) ->
      oa = Twitter.getOAuth(site)
      async.waterfall [(callback) ->
        oa.get whoami_endpoint, token, secret, callback
        return
      ], (err, doc, response) ->
        obj = undefined
        if err
          callback err, null
        else
          try
            obj = JSON.parse(doc)
            callback null, obj
          catch e
            callback e, null
        return

      return

    sync: (user) ->
      me = user.user_pumpio
      id = user.user_ESN.substr(0,user.user_ESN.indexOf('@'))
      token = user.oauth_token
      secret = user.extra_token
      util = require("util")
      twitter = require("twitter")
      twit = new twitter(
        consumer_key: client_id
        consumer_secret: client_secret
        access_token_key: token
        access_token_secret: secret
      )

      # 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) ->
          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 (typeof post.object.deleted is "undefined")
              ToESN.search {uid: post.object.id + "@twitter"}, (err, result) ->
                if result.length is 0
                  # post to twitter
                  status = ""
                  text = post.object.content.replace(/<(?:.|\n)*?>/gm, '')
                  if post.verb is "share"
                    status = post.object.author.url + " wrotes: "
                  if text.length <= 140
                    status += text
                  else
                    status += text.substr(0, 140 - (post.object.url.length + 2)) + ".." + post.object.url
                  twit.verifyCredentials((data) ->
                    #console.log util.inspect(data)
                    return
                  ).updateStatus status, (data) ->
                    async.waterfall [
                      (callback) ->
                        savePost = new ToESN()
                        savePost.uid = post.object.id + "@twitter"
                        savePost.sourceUser = post.actor.id
                        savePost.sourcePost = post.object.id
                        savePost.targetUser = user.user_ESN
                        savePost.targetPost = data.id
                        savePost.recipientUser = 'public'
                        savePost.updated = Date.now()
                        savePost.save callback
                    ], (err, result) ->
                    #console.log util.inspect(data)
                    return
            callback null, 'done'
          ), (err) ->
            callback null, 'done'
      ],(err, result) ->
    
      ######################################
      # get tweets and post them to pump.io#
      ######################################
      twit.verifyCredentials((data) ->
        #console.log util.inspect(data)
        return
      ).getHomeTimeline {include_rts: true, count: 20 }, (data) ->
        #console.log util.inspect(data)
        ti = (new Date().getTime() - interval)
        _.each data, (tweet) ->
          async.waterfall [
            (callback) ->
              FromESN.search {uid: tweet.id + "@twitter_to_" + me, recipientUser: me}, callback
            (result, callback) ->
              return if result.length isnt 0 or tweet.user.id_str is id
              twitterdate = new Date(Date.parse(tweet.created_at.replace(/( +)/, " UTC$1")))
              ts = Date.parse(twitterdate)
              if (ts >= ti)
                Sync.postParser tweet, null, 'twitter', callback
              return
            (parsed, callback) ->
              Pump.postUser bridgeid, me, parsed, callback
            (pumppost, callback) ->
              pumppost = JSON.parse(pumppost)
              FromESN.create
                postid: tweet.id + "@twitter"
                sourceUser: tweet.user.id
                sourcePost: 'https://twitter.com/'+tweet.user.name+"/status/" + tweet.id
                pumpPost: pumppost.object.id
                recipientUser: me
                created: Date.now()
              , callback
          ], (err, result) ->
              #console.log result
        # end
        return
      return

      return
 
    parseTwitterDate : (text) ->

    getOAuth: (site) ->
      new OAuth(request_token_endpoint, access_token_endpoint, client_id, client_secret, "1.0", site.url("/authorized-for-twitter"), "HMAC-SHA1", null, # nonce size; use default
        "User-Agent": site.userAgent()
      )

  Twitter
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)