twitter2.rb 8.7 KB

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