twitter.rb 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class Channel::Driver::Twitter
  3. =begin
  4. fetch tweets from twitter account
  5. options = {
  6. adapter: 'twitter',
  7. auth: {
  8. consumer_key: consumer_key,
  9. consumer_secret: consumer_secret,
  10. oauth_token: armin_theo_token,
  11. oauth_token_secret: armin_theo_token_secret,
  12. },
  13. sync: {
  14. search: [
  15. {
  16. term: '#citheo42',
  17. group_id: 2,
  18. },
  19. {
  20. term: '#citheo24',
  21. group_id: 1,
  22. },
  23. ],
  24. mentions: {
  25. group_id: 2,
  26. },
  27. direct_messages: {
  28. group_id: 2,
  29. }
  30. }
  31. }
  32. instance = Channel::Driver::Twitter.new
  33. result = instance.fetch(options, channel)
  34. returns
  35. {
  36. result: 'ok',
  37. }
  38. =end
  39. def fetch(options, channel)
  40. options = self.class.check_external_credential(options)
  41. @client = TwitterSync.new(options[:auth])
  42. @sync = options[:sync]
  43. @channel = channel
  44. Rails.logger.debug { 'twitter fetch started' }
  45. fetch_search
  46. disconnect
  47. Rails.logger.debug { 'twitter fetch completed' }
  48. {
  49. result: 'ok',
  50. notice: '',
  51. }
  52. end
  53. =begin
  54. instance = Channel::Driver::Twitter.new
  55. instance.fetchable?(channel)
  56. =end
  57. def fetchable?(channel)
  58. return true if Rails.env.test?
  59. # only fetch once in 30 minutes
  60. return true if !channel.preferences
  61. return true if !channel.preferences[:last_fetch]
  62. return false if channel.preferences[:last_fetch] > 20.minutes.ago
  63. true
  64. end
  65. =begin
  66. instance = Channel::Driver::Twitter.new
  67. instance.send(
  68. {
  69. adapter: 'twitter',
  70. auth: {
  71. consumer_key: consumer_key,
  72. consumer_secret: consumer_secret,
  73. oauth_token: armin_theo_token,
  74. oauth_token_secret: armin_theo_token_secret,
  75. },
  76. },
  77. twitter_attributes,
  78. notification
  79. )
  80. =end
  81. def deliver(options, article, _notification = false)
  82. # return if we run import mode
  83. return if Setting.get('import_mode')
  84. options = self.class.check_external_credential(options)
  85. @client = TwitterSync.new(options[:auth])
  86. tweet = @client.from_article(article)
  87. disconnect
  88. tweet
  89. end
  90. def disconnect
  91. @client&.disconnect
  92. end
  93. =begin
  94. Channel::Driver::Twitter.streamable?
  95. returns
  96. true|false
  97. =end
  98. def self.streamable?
  99. false
  100. end
  101. =begin
  102. Channel::Driver::Twitter.process(payload, channel)
  103. =end
  104. def process(_adapter_options, payload, channel)
  105. @client = TwitterSync.new(channel.options[:auth], payload)
  106. @client.process_webhook(channel)
  107. end
  108. def self.check_external_credential(options)
  109. if options[:auth] && options[:auth][:external_credential_id]
  110. external_credential = ExternalCredential.find_by(id: options[:auth][:external_credential_id])
  111. raise "No such ExternalCredential.find(#{options[:auth][:external_credential_id]})" if !external_credential
  112. options[:auth][:consumer_key] = external_credential.credentials['consumer_key']
  113. options[:auth][:consumer_secret] = external_credential.credentials['consumer_secret']
  114. end
  115. options
  116. end
  117. private
  118. def fetch_search
  119. return if @sync[:search].blank?
  120. @sync[:search].each do |search|
  121. next if search[:term].blank?
  122. next if search[:term] == '#'
  123. next if search[:group_id].blank?
  124. result_type = search[:type] || 'mixed'
  125. Rails.logger.debug { " - searching for '#{search[:term]}'" }
  126. Rails.logger.debug { " - result_type '#{result_type}'" }
  127. older_import = 0
  128. older_import_max = 20
  129. search_result = @client.client.search(search[:term], result_type: result_type)
  130. Rails.logger.debug { " - found #{search_result.attrs[:statuses].count} tweets" }
  131. search_result.collect do |tweet|
  132. next if !track_retweets? && tweet.retweet?
  133. # ignore older messages
  134. if @sync[:import_older_tweets] != true && ((@channel.created_at - 15.days) > tweet.created_at.dup.utc || older_import >= older_import_max)
  135. older_import += 1
  136. Rails.logger.debug { "tweet to old: #{tweet.id}/#{tweet.created_at}" }
  137. next
  138. end
  139. next if @client.locale_sender?(tweet)
  140. next if Ticket::Article.exists?(message_id: tweet.id)
  141. break if @client.tweet_limit_reached(tweet)
  142. @client.to_group(tweet, search[:group_id], @channel)
  143. end
  144. end
  145. end
  146. def track_retweets?
  147. @channel.options && @channel.options['sync'] && @channel.options['sync']['track_retweets']
  148. end
  149. end