123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- class CommunicateTwitterJob < ApplicationJob
- retry_on StandardError, attempts: 4, wait: lambda { |executions|
- executions * 120.seconds
- }
- def perform(article_id)
- article = Ticket::Article.find(article_id)
- # set retry count
- article.preferences['delivery_retry'] ||= 0
- article.preferences['delivery_retry'] += 1
- ticket = Ticket.lookup(id: article.ticket_id)
- log_error(article, "Can't find ticket.preferences['channel_id'] for Ticket.find(#{article.ticket_id})") if !ticket.preferences['channel_id']
- channel = Channel.lookup(id: ticket.preferences['channel_id'])
- # search for same channel channel_screen_name, in case the channel got re-added
- if !channel
- Channel.where(area: 'Twitter::Account', active: true).each do |local_channel|
- next if ticket.preferences[:channel_screen_name].blank?
- next if !local_channel.options
- next if local_channel.options[:user].blank?
- next if local_channel.options[:user][:screen_name].blank?
- next if local_channel.options[:user][:screen_name] != ticket.preferences[:channel_screen_name]
- channel = local_channel
- break
- end
- end
- log_error(article, "No such channel id #{ticket.preferences['channel_id']}") if !channel
- log_error(article, "Channel.find(#{channel.id}) isn't a twitter channel!") if !channel.options[:adapter].try(:match?, %r{\Atwitter}i)
- begin
- tweet = channel.deliver(
- type: article.type.name,
- to: article.to,
- body: article.body,
- in_reply_to: article.in_reply_to
- )
- rescue => e
- log_error(article, e.message)
- return
- end
- if !tweet
- log_error(article, 'Got no tweet!')
- return
- end
- # fill article with tweet info
- # direct message
- if tweet.is_a?(Twitter::DirectMessage)
- tweet_type = 'DirectMessage'
- article.message_id = tweet.id.to_s
- article.preferences['twitter'] = {
- recipient_id: tweet.recipient_id.to_s,
- sender_id: tweet.sender_id.to_s,
- }
- article.preferences['links'] = [
- {
- url: TwitterSync::DM_URL_TEMPLATE % article.preferences[:twitter].slice(:recipient_id, :sender_id).values.map(&:to_i).sort.join('-'),
- target: '_blank',
- name: 'on Twitter',
- },
- ]
- # regular tweet
- elsif tweet.instance_of?(Twitter::Tweet)
- tweet_type = 'Tweet'
- article.from = "@#{tweet.user.screen_name}"
- to = ''
- mention_ids = []
- tweet.user_mentions.each do |user|
- if to != ''
- to += ' '
- end
- to += "@#{user.screen_name}"
- mention_ids.push user.id
- end
- article.to = to
- article.preferences['twitter'] = TwitterSync.preferences_cleanup(
- mention_ids: mention_ids,
- geo: tweet.geo,
- retweeted: tweet.retweeted?,
- possibly_sensitive: tweet.possibly_sensitive?,
- in_reply_to_user_id: tweet.in_reply_to_user_id,
- place: tweet.place,
- retweet_count: tweet.retweet_count,
- source: tweet.source,
- favorited: tweet.favorited?,
- truncated: tweet.truncated?,
- created_at: tweet.created_at,
- )
- article.message_id = tweet.id.to_s
- article.preferences['links'] = [
- {
- url: TwitterSync::STATUS_URL_TEMPLATE % tweet.id,
- target: '_blank',
- name: 'on Twitter',
- },
- ]
- else
- raise "Unknown tweet type '#{tweet.class}'"
- end
- # set delivery status
- article.preferences['delivery_status_message'] = nil
- article.preferences['delivery_status'] = 'success'
- article.preferences['delivery_status_date'] = Time.zone.now
- article.save!
- Rails.logger.info "Send twitter (#{tweet_type}) to: '#{article.to}' (from #{article.from})"
- article
- end
- def log_error(local_record, message)
- local_record.preferences['delivery_status'] = 'fail'
- local_record.preferences['delivery_status_message'] = message.encode!('UTF-8', 'UTF-8', invalid: :replace, replace: '?')
- local_record.preferences['delivery_status_date'] = Time.zone.now
- local_record.save
- Rails.logger.error message
- if local_record.preferences['delivery_retry'] > 3
- Ticket::Article.create(
- ticket_id: local_record.ticket_id,
- content_type: 'text/plain',
- body: "Unable to send tweet: #{message}",
- internal: true,
- sender: Ticket::Article::Sender.find_by(name: 'System'),
- type: Ticket::Article::Type.find_by(name: 'note'),
- preferences: {
- delivery_article_id_related: local_record.id,
- delivery_message: true,
- },
- updated_by_id: 1,
- created_by_id: 1,
- )
- end
- raise message
- end
- end
|