twitter2.rb 8.6 KB

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