Moved to background job for sending twitter messages.

This commit is contained in:
Martin Edenhofer 2016-06-25 22:30:22 +02:00
parent 3b9f7b28df
commit 081034a15a
3 changed files with 126 additions and 42 deletions

View file

@ -17,48 +17,7 @@ class Observer::Ticket::Article::CommunicateTwitter < ActiveRecord::Observer
type = Ticket::Article::Type.lookup(id: record.type_id)
return if type['name'] !~ /\Atwitter/i
ticket = Ticket.lookup(id: record.ticket_id)
raise "Can't find ticket.preferences for Ticket.find(#{record.ticket_id})" if !ticket.preferences
raise "Can't find ticket.preferences['channel_id'] for Ticket.find(#{record.ticket_id})" if !ticket.preferences['channel_id']
channel = Channel.lookup(id: ticket.preferences['channel_id'])
raise "No such channel id #{ticket.preferences['channel_id']}" if !channel
raise "Channel.find(#{channel.id}) isn't a twitter channel!" if channel.options[:adapter] !~ /\Atwitter/i
tweet = channel.deliver(
type: type['name'],
to: record.to,
body: record.body,
in_reply_to: record.in_reply_to
)
# fill article with tweet info
# direct message
if tweet.class == Twitter::DirectMessage
record.from = "@#{tweet.sender.screen_name}"
record.to = "@#{tweet.recipient.screen_name}"
# regular tweet
elsif tweet.class == Twitter::Tweet
record.from = "@#{tweet.user.screen_name}"
if tweet.user_mentions
to = ''
twitter_mention_ids = []
tweet.user_mentions.each {|user|
if to != ''
to += ' '
end
to += "@#{user.screen_name}"
twitter_mention_ids.push user.id
}
record.to = to
record.preferences[:twitter_mention_ids] = twitter_mention_ids
end
else
raise "Unknown tweet type '#{tweet.class}'"
end
record.message_id = tweet.id
record.save
Delayed::Job.enqueue(Observer::Ticket::Article::CommunicateTwitter::BackgroundJob.new(record.id))
end
end

View file

@ -0,0 +1,109 @@
class Observer::Ticket::Article::CommunicateTwitter::BackgroundJob
def initialize(id)
@article_id = id
end
def perform
article = Ticket::Article.find(@article_id)
# set retry count
if !article.preferences['delivery_retry']
article.preferences['delivery_retry'] = 0
end
article.preferences['delivery_retry'] += 1
ticket = Ticket.lookup(id: article.ticket_id)
log_error(article, "Can't find ticket.preferences for Ticket.find(#{article.ticket_id})") if !ticket.preferences
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'])
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] !~ /\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, 'Unable to send message to twitter')
return
end
# fill article with tweet info
# direct message
if tweet.class == Twitter::DirectMessage
article.from = "@#{tweet.sender.screen_name}"
article.to = "@#{tweet.recipient.screen_name}"
# regular tweet
elsif tweet.class == Twitter::Tweet
article.from = "@#{tweet.user.screen_name}"
if tweet.user_mentions
to = ''
twitter_mention_ids = []
tweet.user_mentions.each {|user|
if to != ''
to += ' '
end
to += "@#{user.screen_name}"
twitter_mention_ids.push user.id
}
article.to = to
article.preferences[:twitter_mention_ids] = twitter_mention_ids
end
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.message_id = tweet.id.to_s
article.save
end
def log_error(local_record, message)
local_record.preferences['delivery_status'] = 'fail'
local_record.preferences['delivery_status_message'] = message
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'),
updated_by_id: 1,
created_by_id: 1,
)
return
end
raise message
end
def max_attempts
4
end
def reschedule_at(current_time, attempts)
if Rails.env.production?
return current_time + attempts * 120.seconds
end
current_time + 5.seconds
end
end

View file

@ -125,6 +125,10 @@ class TwitterTest < ActiveSupport::TestCase
updated_by_id: 1,
created_by_id: 1,
)
Scheduler.worker(true)
article = Ticket::Article.find(article.id)
assert(article, "outbound article created, text: #{text}")
assert_equal(system_login, article.from, 'ticket article from')
assert_equal('', article.to, 'ticket article to')
@ -223,6 +227,10 @@ class TwitterTest < ActiveSupport::TestCase
updated_by_id: 1,
created_by_id: 1,
)
Scheduler.worker(true)
article = Ticket::Article.find(article.id)
assert(article, "outbound article created, text: #{reply_text}")
assert_equal(system_login, article.from, 'ticket article from')
assert_equal(customer_login, article.to, 'ticket article to')
@ -306,6 +314,10 @@ class TwitterTest < ActiveSupport::TestCase
updated_by_id: 1,
created_by_id: 1,
)
Scheduler.worker(true)
outbound_article = Ticket::Article.find(outbound_article.id)
assert(outbound_article, 'outbound article created')
assert_equal(2, outbound_article.ticket.articles.count, 'ticket article outbound count')
assert_equal(system_login, outbound_article.from, 'ticket article from')
@ -445,6 +457,10 @@ class TwitterTest < ActiveSupport::TestCase
updated_by_id: 1,
created_by_id: 1,
)
Scheduler.worker(true)
article = Ticket::Article.find(article.id)
assert(article, "outbound article created, text: #{reply_text}")
assert_equal(system_login, article.from, 'ticket article from')
assert_equal('', article.to, 'ticket article to')