twitter2.rb 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. # Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
  2. require 'twitter'
  3. class Channel::Twitter2
  4. def connect(channel)
  5. @client = Twitter::Client.new(
  6. :consumer_key => channel[:options][:consumer_key],
  7. :consumer_secret => channel[:options][:consumer_secret],
  8. :oauth_token => channel[:options][:oauth_token],
  9. :oauth_token_secret => channel[:options][:oauth_token_secret]
  10. )
  11. end
  12. def fetch (channel)
  13. puts "fetching tweets (oauth_token#{channel[:options][:oauth_token]})"
  14. @client = connect(channel)
  15. # search results
  16. if channel[:options][:search]
  17. channel[:options][:search].each { |search|
  18. puts " - searching for #{search[:item]}"
  19. tweets = @client.search( search[:item] )
  20. @article_type = 'twitter status'
  21. fetch_loop(tweets, channel, search[:group])
  22. }
  23. end
  24. # mentions
  25. if channel[:options][:mentions]
  26. puts " - searching for mentions"
  27. tweets = @client.mentions
  28. @article_type = 'twitter status'
  29. fetch_loop(tweets, channel, channel[:options][:mentions][:group])
  30. end
  31. # direct messages
  32. if channel[:options][:direct_messages]
  33. puts " - searching for direct_messages"
  34. tweets = @client.direct_messages
  35. @article_type = 'twitter direct-message'
  36. fetch_loop(tweets, channel, channel[:options][:direct_messages][:group])
  37. end
  38. puts 'done'
  39. end
  40. def fetch_loop(tweets, channel, group)
  41. # get all tweets
  42. all_tweets = []
  43. result_class = tweets.class
  44. if result_class.to_s == 'Array'
  45. all_tweets = tweets
  46. elsif result_class.to_s == 'Twitter::SearchResults'
  47. tweets.results.map do |tweet|
  48. all_tweets.push tweet
  49. end
  50. else
  51. puts 'UNKNOWN: ' + result_class.to_s
  52. end
  53. # find tweets
  54. all_tweets.each do |tweet|
  55. # check if tweet is already imported
  56. article = Ticket::Article.where( :message_id => tweet.id.to_s ).first
  57. # check if sender already exists
  58. next if article
  59. # use transaction
  60. ActiveRecord::Base.transaction do
  61. # reset current_user
  62. UserInfo.current_user_id = 1
  63. puts 'import tweet'
  64. fetch_import( tweet, channel, group )
  65. end
  66. # execute ticket events
  67. Observer::Ticket::Notification.transaction
  68. end
  69. end
  70. def fetch_import(tweet, channel, group)
  71. # do sender lockup if needed
  72. sender = nil
  73. # status (full user data is included)
  74. if tweet['user']
  75. sender = tweet['user']
  76. # direct message (full user data is included)
  77. elsif tweet['sender']
  78. sender = tweet['sender']
  79. # search (no user data is included, do extra lookup)
  80. elsif tweet['from_user_id']
  81. begin
  82. # reconnect for #<Twitter::Error::NotFound: Sorry, that page does not exist> workaround
  83. # @client = connect(channel)
  84. sender = @client.user(tweet.from_user_id)
  85. rescue Exception => e
  86. puts "Exception: twitter: " + e.inspect
  87. return
  88. end
  89. end
  90. # check if parent exists
  91. user = nil, ticket = nil, article = nil
  92. if tweet['in_reply_to_status_id']
  93. puts 'import in_reply_tweet ' + tweet.in_reply_to_status_id.to_s
  94. tweet_sub = @client.status(tweet.in_reply_to_status_id)
  95. # puts tweet_sub.inspect
  96. (user, ticket, article) = fetch_import(tweet_sub, channel, group)
  97. end
  98. # create stuff
  99. user = fetch_user_create(tweet, sender)
  100. if !ticket
  101. puts 'create new ticket...'
  102. ticket = fetch_ticket_create(user, tweet, sender, channel, group)
  103. end
  104. article = fetch_article_create(user, ticket, tweet, sender)
  105. return user, ticket, article
  106. end
  107. def fetch_user_create(tweet, sender)
  108. # create sender in db
  109. # puts tweet.inspect
  110. # user = User.where( :login => tweet.sender.screen_name ).first
  111. auth = Authorization.where( :uid => sender.id, :provider => 'twitter' ).first
  112. user = nil
  113. if auth
  114. puts 'user_id', auth.user_id
  115. user = User.where( :id => auth.user_id ).first
  116. end
  117. if !user
  118. puts 'create user...'
  119. roles = Role.where( :name => 'Customer' )
  120. user = User.create(
  121. :login => sender.screen_name,
  122. :firstname => sender.name,
  123. :lastname => '',
  124. :email => '',
  125. :password => '',
  126. :image => sender.profile_image_url,
  127. :note => sender.description,
  128. :active => true,
  129. :roles => roles,
  130. :updated_by_id => 1,
  131. :created_by_id => 1
  132. )
  133. puts 'autentication create...'
  134. authentication = Authorization.create(
  135. :uid => sender.id,
  136. :username => sender.screen_name,
  137. :user_id => user.id,
  138. :provider => 'twitter'
  139. )
  140. else
  141. puts 'user exists'#, user.inspect
  142. end
  143. # set current user
  144. UserInfo.current_user_id = user.id
  145. return user
  146. end
  147. def fetch_ticket_create(user, tweet, sender, channel, group)
  148. # puts '+++++++++++++++++++++++++++' + tweet.inspect
  149. # check if ticket exists
  150. if tweet['in_reply_to_status_id']
  151. puts 'tweet.in_reply_to_status_id found: ' + tweet.in_reply_to_status_id
  152. article = Ticket::Article.where( :message_id => tweet.in_reply_to_status_id.to_s ).first
  153. if article
  154. puts 'article with id found tweet.in_reply_to_status_id found: ' + tweet.in_reply_to_status_id
  155. return article.ticket
  156. end
  157. end
  158. # find if record already exists
  159. article = Ticket::Article.where( :message_id => tweet.id.to_s ).first
  160. if article
  161. return article.ticket
  162. end
  163. ticket = nil
  164. if @article_type == 'twitter direct-message'
  165. ticket = Ticket.where( :customer_id => user.id ).first
  166. if ticket
  167. ticket_state_type = Ticket::StateType.where( ticket.ticket_state.state_type_id )
  168. if ticket_state_type.name == 'closed' || ticket_state_type.name == 'closed'
  169. ticket = nil
  170. end
  171. end
  172. end
  173. if !ticket
  174. group = Group.where( :name => group ).first
  175. group_id = 1
  176. if group
  177. group_id = group.id
  178. end
  179. state = Ticket::State.where( :name => 'new' ).first
  180. state_id = 1
  181. if state
  182. state_id = state.id
  183. end
  184. priority = Ticket::Priority.where( :name => '2 normal' ).first
  185. priority_id = 1
  186. if priority
  187. priority_id = priority.id
  188. end
  189. ticket = Ticket.create(
  190. :group_id => group_id,
  191. :customer_id => user.id,
  192. :title => tweet.text[0,40],
  193. :ticket_state_id => state_id,
  194. :ticket_priority_id => priority_id,
  195. )
  196. end
  197. return ticket
  198. end
  199. def fetch_article_create(user,ticket,tweet, sender)
  200. # find if record already exists
  201. article = Ticket::Article.where( :message_id => tweet.id.to_s ).first
  202. if article
  203. return article
  204. end
  205. # set ticket state to open if not new
  206. if ticket.ticket_state.name != 'new'
  207. ticket.ticket_state = Ticket::State.where( :name => 'open' ).first
  208. ticket.save
  209. end
  210. # import tweet
  211. to = nil
  212. if tweet['recipient']
  213. to = tweet.recipient.name
  214. end
  215. article = Ticket::Article.create(
  216. :ticket_id => ticket.id,
  217. :ticket_article_type_id => Ticket::Article::Type.where( :name => @article_type ).first.id,
  218. :ticket_article_sender_id => Ticket::Article::Sender.where( :name => 'Customer' ).first.id,
  219. :body => tweet.text,
  220. :from => sender.name,
  221. :to => to,
  222. :message_id => tweet.id,
  223. :internal => false,
  224. )
  225. end
  226. def send(attr, notification = false)
  227. # logger.debug('tweeeeettttt!!!!!!')
  228. channel = Channel.where( :area => 'Twitter::Inbound', :active => true ).first
  229. client = Twitter::Client.new(
  230. :consumer_key => channel[:options][:consumer_key],
  231. :consumer_secret => channel[:options][:consumer_secret],
  232. :oauth_token => channel[:options][:oauth_token],
  233. :oauth_token_secret => channel[:options][:oauth_token_secret]
  234. )
  235. if attr[:type] == 'twitter direct-message'
  236. puts 'to:' + attr[:to].to_s
  237. dm = client.direct_message_create(
  238. attr[:to].to_s,
  239. attr[:body].to_s,
  240. {}
  241. )
  242. # puts dm.inspect
  243. return dm
  244. end
  245. if attr[:type] == 'twitter status'
  246. message = client.update(
  247. attr[:body].to_s,
  248. {
  249. :in_reply_to_status_id => attr[:in_reply_to]
  250. }
  251. )
  252. # puts message.inspect
  253. return message
  254. end
  255. end
  256. end