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