Moved to background job for sending twitter messages.
This commit is contained in:
parent
3b9f7b28df
commit
081034a15a
3 changed files with 126 additions and 42 deletions
|
@ -17,48 +17,7 @@ class Observer::Ticket::Article::CommunicateTwitter < ActiveRecord::Observer
|
||||||
type = Ticket::Article::Type.lookup(id: record.type_id)
|
type = Ticket::Article::Type.lookup(id: record.type_id)
|
||||||
return if type['name'] !~ /\Atwitter/i
|
return if type['name'] !~ /\Atwitter/i
|
||||||
|
|
||||||
ticket = Ticket.lookup(id: record.ticket_id)
|
Delayed::Job.enqueue(Observer::Ticket::Article::CommunicateTwitter::BackgroundJob.new(record.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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -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
|
|
@ -125,6 +125,10 @@ class TwitterTest < ActiveSupport::TestCase
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_by_id: 1,
|
created_by_id: 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Scheduler.worker(true)
|
||||||
|
|
||||||
|
article = Ticket::Article.find(article.id)
|
||||||
assert(article, "outbound article created, text: #{text}")
|
assert(article, "outbound article created, text: #{text}")
|
||||||
assert_equal(system_login, article.from, 'ticket article from')
|
assert_equal(system_login, article.from, 'ticket article from')
|
||||||
assert_equal('', article.to, 'ticket article to')
|
assert_equal('', article.to, 'ticket article to')
|
||||||
|
@ -223,6 +227,10 @@ class TwitterTest < ActiveSupport::TestCase
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_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(article, "outbound article created, text: #{reply_text}")
|
||||||
assert_equal(system_login, article.from, 'ticket article from')
|
assert_equal(system_login, article.from, 'ticket article from')
|
||||||
assert_equal(customer_login, article.to, 'ticket article to')
|
assert_equal(customer_login, article.to, 'ticket article to')
|
||||||
|
@ -306,6 +314,10 @@ class TwitterTest < ActiveSupport::TestCase
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_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(outbound_article, 'outbound article created')
|
||||||
assert_equal(2, outbound_article.ticket.articles.count, 'ticket article outbound count')
|
assert_equal(2, outbound_article.ticket.articles.count, 'ticket article outbound count')
|
||||||
assert_equal(system_login, outbound_article.from, 'ticket article from')
|
assert_equal(system_login, outbound_article.from, 'ticket article from')
|
||||||
|
@ -445,6 +457,10 @@ class TwitterTest < ActiveSupport::TestCase
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_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(article, "outbound article created, text: #{reply_text}")
|
||||||
assert_equal(system_login, article.from, 'ticket article from')
|
assert_equal(system_login, article.from, 'ticket article from')
|
||||||
assert_equal('', article.to, 'ticket article to')
|
assert_equal('', article.to, 'ticket article to')
|
||||||
|
|
Loading…
Reference in a new issue