Refactoring: Migrated last Delayed::Job classes to ActiveJob.
This commit is contained in:
parent
3033002ae5
commit
5f3a8dc581
48 changed files with 735 additions and 660 deletions
|
@ -48,4 +48,3 @@ before_script:
|
|||
- source /etc/profile.d/rvm.sh
|
||||
- bundle install -j $(nproc) --path vendor
|
||||
- bundle exec ruby script/build/database_config.rb
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ RSpec/ContextWording:
|
|||
- 'spec/db/migrate/issue_2345_es_attachment_max_size_in_mb_setting_lower_default_spec.rb'
|
||||
- 'spec/db/migrate/issue_2368_add_indices_to_histories_and_tickets_spec.rb'
|
||||
- 'spec/db/migrate/issue_2541_fix_notification_email_without_body_spec.rb'
|
||||
- 'spec/jobs/communicate_twitter_job_spec.rb'
|
||||
- 'spec/jobs/concerns/has_active_job_lock_spec.rb'
|
||||
- 'spec/jobs/concerns/has_collection_update_spec.rb'
|
||||
- 'spec/jobs/concerns/has_ticket_create_screen_impact_spec.rb'
|
||||
|
@ -116,7 +117,6 @@ RSpec/ContextWording:
|
|||
- 'spec/models/object_manager/attribute/validation/required_spec.rb'
|
||||
- 'spec/models/object_manager/attribute/validation_spec.rb'
|
||||
- 'spec/models/object_manager/attribute_spec.rb'
|
||||
- 'spec/models/observer/ticket/article/communicate_twitter/background_job_spec.rb'
|
||||
- 'spec/models/observer/ticket/article/communicate_twitter_spec.rb'
|
||||
- 'spec/models/overview_spec.rb'
|
||||
- 'spec/models/role_spec.rb'
|
||||
|
@ -170,7 +170,9 @@ RSpec/ExampleLength:
|
|||
- 'spec/db/migrate/issue_2867_footer_header_public_link_spec.rb'
|
||||
- 'spec/db/migrate/object_manager_attribute_date_remove_future_past_spec.rb'
|
||||
- 'spec/db/migrate/rename_locale_on_users_spec.rb'
|
||||
- 'spec/jobs/communicate_twitter_job_spec.rb'
|
||||
- 'spec/jobs/concerns/has_active_job_lock_spec.rb'
|
||||
- 'spec/jobs/migrate_ldap_samaccountname_to_uid_job_spec.rb'
|
||||
- 'spec/jobs/ticket_user_ticket_counter_job_spec.rb'
|
||||
- 'spec/jobs/user_device_log_job_spec.rb'
|
||||
- 'spec/lib/auth/internal_spec.rb'
|
||||
|
@ -209,7 +211,6 @@ RSpec/ExampleLength:
|
|||
- 'spec/lib/ldap/group_spec.rb'
|
||||
- 'spec/lib/ldap/user_spec.rb'
|
||||
- 'spec/lib/ldap_spec.rb'
|
||||
- 'spec/lib/migration_job/ldap_samaccountname_to_uid_spec.rb'
|
||||
- 'spec/lib/notification_factory/mailer_spec.rb'
|
||||
- 'spec/lib/notification_factory/renderer_spec.rb'
|
||||
- 'spec/lib/notification_factory/slack_spec.rb'
|
||||
|
@ -249,7 +250,6 @@ RSpec/ExampleLength:
|
|||
- 'spec/models/history_spec.rb'
|
||||
- 'spec/models/import_job_spec.rb'
|
||||
- 'spec/models/object_manager/attribute_spec.rb'
|
||||
- 'spec/models/observer/ticket/article/communicate_twitter/background_job_spec.rb'
|
||||
- 'spec/models/overview_spec.rb'
|
||||
- 'spec/models/recent_view_spec.rb'
|
||||
- 'spec/models/role_group_spec.rb'
|
||||
|
@ -357,6 +357,7 @@ RSpec/InstanceVariable:
|
|||
|
||||
RSpec/LetSetup:
|
||||
Exclude:
|
||||
- 'spec/jobs/communicate_twitter_job_spec.rb'
|
||||
- 'spec/jobs/ticket_online_notification_seen_job_spec.rb'
|
||||
- 'spec/lib/external_credential/google_spec.rb'
|
||||
- 'spec/lib/external_credential/office365_spec.rb'
|
||||
|
@ -367,7 +368,6 @@ RSpec/LetSetup:
|
|||
- 'spec/models/cti/caller_id_spec.rb'
|
||||
- 'spec/models/cti/driver/base_spec.rb'
|
||||
- 'spec/models/cti/log_spec.rb'
|
||||
- 'spec/models/observer/ticket/article/communicate_twitter/background_job_spec.rb'
|
||||
- 'spec/models/organization_spec.rb'
|
||||
- 'spec/models/role_group_spec.rb'
|
||||
- 'spec/models/tag_spec.rb'
|
||||
|
@ -431,7 +431,6 @@ RSpec/MessageSpies:
|
|||
- 'spec/lib/ldap/guid_spec.rb'
|
||||
- 'spec/lib/ldap/user_spec.rb'
|
||||
- 'spec/lib/ldap_spec.rb'
|
||||
- 'spec/lib/migration_job/ldap_samaccountname_to_uid_spec.rb'
|
||||
- 'spec/lib/sequencer/sequence/import/ldap/users_spec.rb'
|
||||
- 'spec/lib/sequencer/unit/common/attribute_mapper_spec.rb'
|
||||
- 'spec/lib/sequencer/unit/import/common/mapping/flat_keys_spec.rb'
|
||||
|
@ -468,7 +467,9 @@ RSpec/MultipleExpectations:
|
|||
- 'spec/db/migrate/issue_1905_exchange_login_from_remote_id_spec.rb'
|
||||
- 'spec/db/migrate/object_manager_attribute_date_remove_future_past_spec.rb'
|
||||
- 'spec/db/migrate/rename_locale_on_users_spec.rb'
|
||||
- 'spec/jobs/communicate_twitter_job_spec.rb'
|
||||
- 'spec/jobs/concerns/has_active_job_lock_spec.rb'
|
||||
- 'spec/jobs/migrate_ldap_samaccountname_to_uid_job_spec.rb'
|
||||
- 'spec/jobs/search_index_job_spec.rb'
|
||||
- 'spec/jobs/ticket_user_ticket_counter_job_spec.rb'
|
||||
- 'spec/lib/auth/developer_spec.rb'
|
||||
|
@ -505,7 +506,6 @@ RSpec/MultipleExpectations:
|
|||
- 'spec/lib/ldap/guid_spec.rb'
|
||||
- 'spec/lib/ldap/user_spec.rb'
|
||||
- 'spec/lib/ldap_spec.rb'
|
||||
- 'spec/lib/migration_job/ldap_samaccountname_to_uid_spec.rb'
|
||||
- 'spec/lib/notification_factory/mailer_spec.rb'
|
||||
- 'spec/lib/password_hash_spec.rb'
|
||||
- 'spec/lib/secure_mailing/smime_spec.rb'
|
||||
|
@ -538,7 +538,6 @@ RSpec/MultipleExpectations:
|
|||
- 'spec/models/object_manager/attribute/validation/backend_spec.rb'
|
||||
- 'spec/models/object_manager/attribute/validation_spec.rb'
|
||||
- 'spec/models/object_manager/attribute_spec.rb'
|
||||
- 'spec/models/observer/ticket/article/communicate_twitter/background_job_spec.rb'
|
||||
- 'spec/models/overview_spec.rb'
|
||||
- 'spec/models/scheduler_spec.rb'
|
||||
- 'spec/models/smime_certificate_spec.rb'
|
||||
|
@ -613,6 +612,7 @@ RSpec/NamedSubject:
|
|||
RSpec/NestedGroups:
|
||||
Exclude:
|
||||
- 'spec/db/migrate/issue_2541_fix_notification_email_without_body_spec.rb'
|
||||
- 'spec/jobs/communicate_twitter_job_spec.rb'
|
||||
- 'spec/jobs/concerns/has_collection_update_spec.rb'
|
||||
- 'spec/jobs/concerns/has_ticket_create_screen_impact_spec.rb'
|
||||
- 'spec/lib/application_handle_info_spec.rb'
|
||||
|
@ -656,7 +656,6 @@ RSpec/NestedGroups:
|
|||
- 'spec/models/object_manager/attribute/validation/required_spec.rb'
|
||||
- 'spec/models/object_manager/attribute/validation_spec.rb'
|
||||
- 'spec/models/object_manager/attribute_spec.rb'
|
||||
- 'spec/models/observer/ticket/article/communicate_twitter/background_job_spec.rb'
|
||||
- 'spec/models/organization_spec.rb'
|
||||
- 'spec/models/recent_view_spec.rb'
|
||||
- 'spec/models/role_spec.rb'
|
||||
|
@ -727,6 +726,7 @@ RSpec/SubjectStub:
|
|||
RSpec/VerifiedDoubles:
|
||||
Exclude:
|
||||
- 'spec/db/migrate/issue_2460_fix_corrupted_twitter_ids_spec.rb'
|
||||
- 'spec/jobs/communicate_twitter_job_spec.rb'
|
||||
- 'spec/lib/auth/ldap_spec.rb'
|
||||
- 'spec/lib/external_sync_spec.rb'
|
||||
- 'spec/lib/import/zendesk/object_attribute/base_examples.rb'
|
||||
|
@ -744,7 +744,6 @@ RSpec/VerifiedDoubles:
|
|||
- 'spec/lib/sequencer/unit/import/zendesk/sub_sequence/base_examples.rb'
|
||||
- 'spec/lib/sequencer/unit/import/zendesk/ticket/comment/attachment/request_spec.rb'
|
||||
- 'spec/lib/sequencer/unit/import/zendesk/ticket/comment/source_based_spec.rb'
|
||||
- 'spec/models/observer/ticket/article/communicate_twitter/background_job_spec.rb'
|
||||
- 'spec/models/ticket/number_spec.rb'
|
||||
|
||||
RSpec/MultipleMemoizedHelpers:
|
||||
|
|
|
@ -75,8 +75,13 @@ Metrics/AbcSize:
|
|||
- 'app/controllers/users_controller.rb'
|
||||
- 'app/helpers/knowledge_base_rich_text_helper.rb'
|
||||
- 'app/jobs/collection_update_job.rb'
|
||||
- 'app/jobs/communicate_facebook_job.rb'
|
||||
- 'app/jobs/communicate_sms_job.rb'
|
||||
- 'app/jobs/communicate_telegram_job.rb'
|
||||
- 'app/jobs/communicate_twitter_job.rb'
|
||||
- 'app/jobs/concerns/has_active_job_lock.rb'
|
||||
- 'app/jobs/imap_authentication_migration_cleanup_job.rb'
|
||||
- 'app/jobs/migrate_ldap_samaccountname_to_uid_job.rb'
|
||||
- 'app/jobs/ticket_article_communicate_email_job.rb'
|
||||
- 'app/jobs/ticket_user_ticket_counter_job.rb'
|
||||
- 'app/models/activity_stream.rb'
|
||||
|
@ -154,13 +159,9 @@ Metrics/AbcSize:
|
|||
- 'app/models/observer/sla/ticket_rebuild_escalation.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_email.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_facebook.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_facebook/background_job.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_sms.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_sms/background_job.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_telegram.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_telegram/background_job.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_twitter.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_twitter/background_job.rb'
|
||||
- 'app/models/observer/ticket/article/fillup_from_email.rb'
|
||||
- 'app/models/observer/ticket/article/fillup_from_general.rb'
|
||||
- 'app/models/observer/ticket/article/fillup_from_origin_by_id.rb'
|
||||
|
@ -290,7 +291,6 @@ Metrics/AbcSize:
|
|||
- 'lib/knowledge_base/menu_item_update_action.rb'
|
||||
- 'lib/ldap/group.rb'
|
||||
- 'lib/ldap/user.rb'
|
||||
- 'lib/migration_job/ldap_samaccountname_to_uid.rb'
|
||||
- 'lib/models.rb'
|
||||
- 'lib/notification_factory/mailer.rb'
|
||||
- 'lib/notification_factory/renderer.rb'
|
||||
|
@ -486,6 +486,10 @@ Metrics/CyclomaticComplexity:
|
|||
- 'app/controllers/user_access_token_controller.rb'
|
||||
- 'app/controllers/users_controller.rb'
|
||||
- 'app/jobs/collection_update_job.rb'
|
||||
- 'app/jobs/communicate_facebook_job.rb'
|
||||
- 'app/jobs/communicate_sms_job.rb'
|
||||
- 'app/jobs/communicate_telegram_job.rb'
|
||||
- 'app/jobs/communicate_twitter_job.rb'
|
||||
- 'app/jobs/ticket_article_communicate_email_job.rb'
|
||||
- 'app/jobs/ticket_create_screen_job.rb'
|
||||
- 'app/jobs/ticket_user_ticket_counter_job.rb'
|
||||
|
@ -545,12 +549,8 @@ Metrics/CyclomaticComplexity:
|
|||
- 'app/models/observer/sla/ticket_rebuild_escalation.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_email.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_facebook.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_facebook/background_job.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_sms.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_sms/background_job.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_telegram/background_job.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_twitter.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_twitter/background_job.rb'
|
||||
- 'app/models/observer/ticket/article/fillup_from_email.rb'
|
||||
- 'app/models/observer/ticket/article/fillup_from_general.rb'
|
||||
- 'app/models/observer/ticket/article/fillup_from_origin_by_id.rb'
|
||||
|
@ -720,6 +720,10 @@ Metrics/PerceivedComplexity:
|
|||
- 'app/controllers/time_accountings_controller.rb'
|
||||
- 'app/controllers/users_controller.rb'
|
||||
- 'app/jobs/collection_update_job.rb'
|
||||
- 'app/jobs/communicate_facebook_job.rb'
|
||||
- 'app/jobs/communicate_sms_job.rb'
|
||||
- 'app/jobs/communicate_telegram_job.rb'
|
||||
- 'app/jobs/communicate_twitter_job.rb'
|
||||
- 'app/jobs/ticket_article_communicate_email_job.rb'
|
||||
- 'app/models/activity_stream/assets.rb'
|
||||
- 'app/models/application_model/can_assets.rb'
|
||||
|
@ -775,12 +779,8 @@ Metrics/PerceivedComplexity:
|
|||
- 'app/models/observer/sla/ticket_rebuild_escalation.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_email.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_facebook.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_facebook/background_job.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_sms.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_sms/background_job.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_telegram/background_job.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_twitter.rb'
|
||||
- 'app/models/observer/ticket/article/communicate_twitter/background_job.rb'
|
||||
- 'app/models/observer/ticket/article/fillup_from_email.rb'
|
||||
- 'app/models/observer/ticket/article/fillup_from_general.rb'
|
||||
- 'app/models/observer/ticket/article/fillup_from_origin_by_id.rb'
|
||||
|
|
|
@ -22,7 +22,7 @@ module Integration::ImportJobBase
|
|||
def job_start_create
|
||||
if !ImportJob.exists?(name: backend, finished_at: nil)
|
||||
job = ImportJob.create(name: backend)
|
||||
job.delay.start
|
||||
AsyncImportJob.perform_later(job)
|
||||
end
|
||||
render json: {
|
||||
result: 'ok',
|
||||
|
|
|
@ -115,7 +115,7 @@ class ImportOtrsController < ApplicationController
|
|||
end
|
||||
|
||||
# start migration
|
||||
Import::OTRS.delay.start_bg
|
||||
AsyncOtrsImportJob.perform_later
|
||||
|
||||
render json: {
|
||||
result: 'ok',
|
||||
|
|
|
@ -98,7 +98,7 @@ class ImportZendeskController < ApplicationController
|
|||
Setting.set('import_backend', 'zendesk')
|
||||
|
||||
job = ImportJob.create(name: 'Import::Zendesk')
|
||||
job.delay.start
|
||||
AsyncImportJob.perform_later(job)
|
||||
|
||||
render json: {
|
||||
result: 'ok',
|
||||
|
|
5
app/jobs/async_import_job.rb
Normal file
5
app/jobs/async_import_job.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class AsyncImportJob < ApplicationJob
|
||||
def perform(import_job)
|
||||
import_job.start
|
||||
end
|
||||
end
|
5
app/jobs/async_otrs_import_job.rb
Normal file
5
app/jobs/async_otrs_import_job.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class AsyncOtrsImportJob < ApplicationJob
|
||||
def perform
|
||||
Import::OTRS.start_bg
|
||||
end
|
||||
end
|
34
app/jobs/chat_leave_job.rb
Normal file
34
app/jobs/chat_leave_job.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
class ChatLeaveJob < ApplicationJob
|
||||
def perform(chat_session_id, client_id, session)
|
||||
|
||||
# check if customer has permanently left the conversation
|
||||
chat_session = Chat::Session.find_by(id: chat_session_id)
|
||||
return if !chat_session
|
||||
return if chat_session.recipients_active?
|
||||
|
||||
chat_session.state = 'closed'
|
||||
chat_session.save
|
||||
|
||||
realname = 'Anonymous'
|
||||
|
||||
# if it is a agent session, use the realname if the agent for close message
|
||||
if session && session['id'] && chat_session.user_id
|
||||
agent_user = chat_session.agent_user
|
||||
if agent_user[:name]
|
||||
realname = agent_user[:name]
|
||||
end
|
||||
end
|
||||
|
||||
# notify participants
|
||||
message = {
|
||||
event: 'chat_session_left',
|
||||
data: {
|
||||
realname: realname,
|
||||
session_id: chat_session.session_id,
|
||||
},
|
||||
}
|
||||
chat_session.send_to_recipients(message, client_id)
|
||||
|
||||
Chat.broadcast_agent_state_update([chat_session.chat_id])
|
||||
end
|
||||
end
|
94
app/jobs/communicate_facebook_job.rb
Normal file
94
app/jobs/communicate_facebook_job.rb
Normal file
|
@ -0,0 +1,94 @@
|
|||
class CommunicateFacebookJob < 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 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, "Channel.find(#{channel.id}) isn't a twitter channel!") if !channel.options[:adapter].match?(/\Afacebook/i)
|
||||
|
||||
# check source object id
|
||||
if !ticket.preferences['channel_fb_object_id']
|
||||
log_error(article, "fb object id is missing in ticket.preferences['channel_fb_object_id'] for Ticket.find(#{ticket.id})")
|
||||
end
|
||||
|
||||
# fill in_reply_to
|
||||
if article.in_reply_to.blank?
|
||||
article.in_reply_to = ticket.articles.first.message_id
|
||||
end
|
||||
|
||||
begin
|
||||
facebook = Channel::Driver::Facebook.new
|
||||
post = facebook.send(
|
||||
channel.options,
|
||||
ticket.preferences[:channel_fb_object_id],
|
||||
{
|
||||
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 !post
|
||||
log_error(article, 'Got no post!')
|
||||
return
|
||||
end
|
||||
|
||||
# fill article with post info
|
||||
article.from = post['from']['name']
|
||||
article.message_id = post['id']
|
||||
|
||||
# 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 facebook 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 post: #{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
|
110
app/jobs/communicate_sms_job.rb
Normal file
110
app/jobs/communicate_sms_job.rb
Normal file
|
@ -0,0 +1,110 @@
|
|||
class CommunicateSmsJob < 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 article.preferences for Ticket::Article.find(#{article.id})") if !article.preferences
|
||||
|
||||
# if sender is system, take article channel
|
||||
if article.sender.name == 'System'
|
||||
log_error(article, "Can't find article.preferences['sms_recipients'] for Ticket::Article.find(#{article.id})") if !article.preferences['sms_recipients']
|
||||
log_error(article, "Can't find article.preferences['channel_id'] for Ticket::Article.find(#{article.id})") if !article.preferences['channel_id']
|
||||
channel = Channel.lookup(id: article.preferences['channel_id'])
|
||||
log_error(article, "No such channel id #{article.preferences['channel_id']}") if !channel
|
||||
|
||||
# if sender is agent, take create channel
|
||||
else
|
||||
log_error(article, "Can't find ticket.preferences['channel_id'] for Ticket.find(#{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
|
||||
end
|
||||
|
||||
begin
|
||||
if article.sender.name == 'System'
|
||||
article.preferences['sms_recipients'].each do |recipient|
|
||||
channel.deliver(
|
||||
recipient: recipient,
|
||||
message: article.body.first(160),
|
||||
)
|
||||
end
|
||||
else
|
||||
channel.deliver(
|
||||
recipient: article.to,
|
||||
message: article.body.first(160),
|
||||
)
|
||||
end
|
||||
rescue => e
|
||||
log_error(article, e.message)
|
||||
return
|
||||
end
|
||||
|
||||
log_success(article)
|
||||
|
||||
return if article.sender.name == 'Agent'
|
||||
|
||||
log_history(article, ticket, 'sms', article.to)
|
||||
end
|
||||
|
||||
# log successful delivery
|
||||
def log_success(article)
|
||||
article.preferences['delivery_status_message'] = nil
|
||||
article.preferences['delivery_status'] = 'success'
|
||||
article.preferences['delivery_status_date'] = Time.zone.now
|
||||
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'] >= max_attempts
|
||||
Ticket::Article.create(
|
||||
ticket_id: local_record.ticket_id,
|
||||
content_type: 'text/plain',
|
||||
body: "#{log_error_prefix}: #{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
|
||||
|
||||
def log_history(article, ticket, history_type, recipient_list)
|
||||
return if recipient_list.blank?
|
||||
|
||||
History.add(
|
||||
o_id: article.id,
|
||||
history_type: history_type,
|
||||
history_object: 'Ticket::Article',
|
||||
related_o_id: ticket.id,
|
||||
related_history_object: 'Ticket',
|
||||
value_from: article.subject,
|
||||
value_to: recipient_list,
|
||||
created_by_id: article.created_by_id,
|
||||
)
|
||||
end
|
||||
|
||||
def log_error_prefix
|
||||
'Unable to send sms message'
|
||||
end
|
||||
end
|
113
app/jobs/communicate_telegram_job.rb
Normal file
113
app/jobs/communicate_telegram_job.rb
Normal file
|
@ -0,0 +1,113 @@
|
|||
class CommunicateTelegramJob < 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 for Ticket.find(#{article.ticket_id})") if !ticket.preferences
|
||||
log_error(article, "Can't find ticket.preferences['telegram'] for Ticket.find(#{article.ticket_id})") if !ticket.preferences['telegram']
|
||||
log_error(article, "Can't find ticket.preferences['telegram']['chat_id'] for Ticket.find(#{article.ticket_id})") if !ticket.preferences['telegram']['chat_id']
|
||||
if ticket.preferences['telegram'] && ticket.preferences['telegram']['bid']
|
||||
channel = Telegram.bot_by_bot_id(ticket.preferences['telegram']['bid'])
|
||||
end
|
||||
if !channel
|
||||
channel = Channel.lookup(id: ticket.preferences['channel_id'])
|
||||
end
|
||||
log_error(article, "No such channel for bot #{ticket.preferences['bid']} or channel id #{ticket.preferences['channel_id']}") if !channel
|
||||
#log_error(article, "Channel.find(#{channel.id}) isn't a telegram channel!") if channel.options[:adapter] !~ /\Atelegram/i
|
||||
log_error(article, "Channel.find(#{channel.id}) has not telegram api token!") if channel.options[:api_token].blank?
|
||||
|
||||
begin
|
||||
api = TelegramAPI.new(channel.options[:api_token])
|
||||
chat_id = ticket.preferences[:telegram][:chat_id]
|
||||
result = api.sendMessage(chat_id, article.body)
|
||||
me = api.getMe()
|
||||
article.attachments.each do |file|
|
||||
parts = file.filename.split(/^(.*)(\..+?)$/)
|
||||
t = Tempfile.new([parts[1], parts[2]])
|
||||
t.binmode
|
||||
t.write(file.content)
|
||||
t.rewind
|
||||
api.sendDocument(chat_id, t.path.to_s)
|
||||
end
|
||||
rescue => e
|
||||
log_error(article, e.message)
|
||||
return
|
||||
end
|
||||
|
||||
Rails.logger.debug { "result info: #{result}" }
|
||||
|
||||
# only private, group messages. channel messages do not have from key
|
||||
if result['from'] && result['chat']
|
||||
# fill article with message info
|
||||
article.from = "@#{result['from']['username']}"
|
||||
article.to = "@#{result['chat']['username']}"
|
||||
|
||||
article.preferences['telegram'] = {
|
||||
date: result['date'],
|
||||
from_id: result['from']['id'],
|
||||
chat_id: result['chat']['id'],
|
||||
message_id: result['message_id']
|
||||
}
|
||||
else
|
||||
# fill article with message info (telegram channel)
|
||||
article.from = "@#{me['username']}"
|
||||
article.to = "#{result['chat']['title']} Channel"
|
||||
|
||||
article.preferences['telegram'] = {
|
||||
date: result['date'],
|
||||
from_id: me['id'],
|
||||
chat_id: result['chat']['id'],
|
||||
message_id: result['message_id']
|
||||
}
|
||||
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 = "telegram.#{result['message_id']}.#{result['chat']['id']}"
|
||||
|
||||
article.save!
|
||||
|
||||
Rails.logger.info "Send telegram message 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 telegram message: #{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
|
156
app/jobs/communicate_twitter_job.rb
Normal file
156
app/jobs/communicate_twitter_job.rb
Normal file
|
@ -0,0 +1,156 @@
|
|||
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?, /\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?(Hash)
|
||||
tweet_type = 'DirectMessage'
|
||||
article.message_id = tweet[:event][:id].to_s
|
||||
if tweet[:event] && tweet[:event][:type] == 'message_create'
|
||||
#article.from = "@#{tweet.sender.screen_name}"
|
||||
#article.to = "@#{tweet.recipient.screen_name}"
|
||||
|
||||
article.preferences['twitter'] = {
|
||||
recipient_id: tweet[:event][:message_create][:target][:recipient_id],
|
||||
sender_id: tweet[:event][:message_create][:sender_id],
|
||||
}
|
||||
|
||||
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',
|
||||
},
|
||||
]
|
||||
end
|
||||
|
||||
# regular tweet
|
||||
elsif tweet.instance_of?(Twitter::Tweet)
|
||||
tweet_type = 'Tweet'
|
||||
tweet_id = tweet.id.to_s
|
||||
article.from = "@#{tweet.user.screen_name}"
|
||||
if tweet.user_mentions
|
||||
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
|
||||
article.preferences['links'] = [
|
||||
{
|
||||
url: TwitterSync::STATUS_URL_TEMPLATE % tweet.id,
|
||||
target: '_blank',
|
||||
name: 'on Twitter',
|
||||
},
|
||||
]
|
||||
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.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
|
56
app/jobs/migrate_ldap_samaccountname_to_uid_job.rb
Normal file
56
app/jobs/migrate_ldap_samaccountname_to_uid_job.rb
Normal file
|
@ -0,0 +1,56 @@
|
|||
require_dependency 'ldap'
|
||||
require_dependency 'ldap/user'
|
||||
|
||||
class MigrateLdapSamaccountnameToUidJob < ApplicationJob
|
||||
|
||||
def perform
|
||||
Rails.logger.info 'Checking for active LDAP configuration...'
|
||||
|
||||
if ldap_config.blank?
|
||||
Rails.logger.info 'Blank LDAP configuration. Exiting.'
|
||||
return
|
||||
end
|
||||
|
||||
Rails.logger.info 'Checking for different LDAP uid attribute...'
|
||||
if uid_attribute_obsolete == uid_attribute_new
|
||||
Rails.logger.info 'Equal LDAP uid attributes. Exiting.'
|
||||
return
|
||||
end
|
||||
|
||||
Rails.logger.info 'Starting to migrate LDAP config to new uid attribute...'
|
||||
migrate_ldap_config
|
||||
Rails.logger.info 'LDAP uid attribute migration completed.'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ldap
|
||||
@ldap ||= ::Ldap.new(ldap_config)
|
||||
end
|
||||
|
||||
def ldap_config
|
||||
@ldap_config ||= Import::Ldap.config
|
||||
end
|
||||
|
||||
def uid_attribute_new
|
||||
@uid_attribute_new ||= begin
|
||||
config = {
|
||||
filter: ldap_config['user_filter']
|
||||
}
|
||||
|
||||
::Ldap::User.new(config, ldap: ldap).uid_attribute
|
||||
end
|
||||
end
|
||||
|
||||
def uid_attribute_obsolete
|
||||
@uid_attribute_obsolete ||= ldap_config['user_uid']
|
||||
end
|
||||
|
||||
def migrate_ldap_config
|
||||
ldap_config_new = ldap_config.merge(
|
||||
'user_uid' => uid_attribute_new
|
||||
)
|
||||
|
||||
Setting.set('ldap_config', ldap_config_new)
|
||||
end
|
||||
end
|
26
app/jobs/transaction_job.rb
Normal file
26
app/jobs/transaction_job.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
class TransactionJob < ApplicationJob
|
||||
|
||||
=begin
|
||||
{
|
||||
object: 'Ticket',
|
||||
type: 'update',
|
||||
ticket_id: 123,
|
||||
interface_handle: 'application_server', # application_server|websocket|scheduler
|
||||
changes: {
|
||||
'attribute1' => [before,now],
|
||||
'attribute2' => [before,now],
|
||||
},
|
||||
created_at: Time.zone.now,
|
||||
user_id: 123,
|
||||
},
|
||||
=end
|
||||
|
||||
def perform(item, params = {})
|
||||
Setting.where(area: 'Transaction::Backend::Async').order(:name).each do |setting|
|
||||
backend = Setting.get(setting.name)
|
||||
next if params[:disable]&.include?(backend)
|
||||
|
||||
Observer::Transaction.execute_singel_backend(backend.constantize, item, params)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -75,12 +75,12 @@ class ImportJob < ApplicationModel
|
|||
return if exists?(name: params[:name], dry_run: true, finished_at: nil)
|
||||
|
||||
params[:dry_run] = true
|
||||
instance = create(params.except(:delay))
|
||||
job = create(params.except(:delay))
|
||||
|
||||
if params.fetch(:delay, true)
|
||||
instance.delay.start
|
||||
AsyncImportJob.perform_later(job)
|
||||
else
|
||||
instance.start
|
||||
job.start
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -6,36 +6,10 @@ class Observer::Chat::Leave::BackgroundJob
|
|||
end
|
||||
|
||||
def perform
|
||||
|
||||
# check if customer has permanently left the conversation
|
||||
chat_session = Chat::Session.find_by(id: @chat_session_id)
|
||||
return if !chat_session
|
||||
return if chat_session.recipients_active?
|
||||
|
||||
chat_session.state = 'closed'
|
||||
chat_session.save
|
||||
|
||||
realname = 'Anonymous'
|
||||
|
||||
# if it is a agent session, use the realname if the agent for close message
|
||||
if @session && @session['id'] && chat_session.user_id
|
||||
agent_user = chat_session.agent_user
|
||||
if agent_user[:name]
|
||||
realname = agent_user[:name]
|
||||
end
|
||||
if Gem::Version.new(Version.get) >= Gem::Version.new('4.0.x')
|
||||
ActiveSupport::Deprecation.warn("This file has been migrated to the ActiveJob 'ChatLeaveJob' and is therefore deprecated and should get removed.")
|
||||
end
|
||||
|
||||
# notify participants
|
||||
message = {
|
||||
event: 'chat_session_left',
|
||||
data: {
|
||||
realname: realname,
|
||||
session_id: chat_session.session_id,
|
||||
},
|
||||
}
|
||||
chat_session.send_to_recipients(message, @client_id)
|
||||
|
||||
Chat.broadcast_agent_state_update([chat_session.chat_id])
|
||||
ChatLeaveJob.perform_now(@chat_session_id, @client_id, @session)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -25,7 +25,7 @@ class Observer::Ticket::Article::CommunicateFacebook < ActiveRecord::Observer
|
|||
return true if type.nil?
|
||||
return true if !type.name.start_with?('facebook')
|
||||
|
||||
Delayed::Job.enqueue(Observer::Ticket::Article::CommunicateFacebook::BackgroundJob.new(record.id))
|
||||
CommunicateFacebookJob.perform_later(record.id)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -4,102 +4,10 @@ class Observer::Ticket::Article::CommunicateFacebook::BackgroundJob
|
|||
end
|
||||
|
||||
def perform
|
||||
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 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, "Channel.find(#{channel.id}) isn't a twitter channel!") if !channel.options[:adapter].match?(/\Afacebook/i)
|
||||
|
||||
# check source object id
|
||||
if !ticket.preferences['channel_fb_object_id']
|
||||
log_error(article, "fb object id is missing in ticket.preferences['channel_fb_object_id'] for Ticket.find(#{ticket.id})")
|
||||
if Gem::Version.new(Version.get) >= Gem::Version.new('4.0.x')
|
||||
ActiveSupport::Deprecation.warn("This file has been migrated to the ActiveJob 'CommunicateFacebookJob' and is therefore deprecated and should get removed.")
|
||||
end
|
||||
|
||||
# fill in_reply_to
|
||||
if article.in_reply_to.blank?
|
||||
article.in_reply_to = ticket.articles.first.message_id
|
||||
end
|
||||
|
||||
begin
|
||||
facebook = Channel::Driver::Facebook.new
|
||||
post = facebook.send(
|
||||
channel.options,
|
||||
ticket.preferences[:channel_fb_object_id],
|
||||
{
|
||||
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 !post
|
||||
log_error(article, 'Got no post!')
|
||||
return
|
||||
end
|
||||
|
||||
# fill article with post info
|
||||
article.from = post['from']['name']
|
||||
article.message_id = post['id']
|
||||
|
||||
# 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 facebook 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 post: #{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
|
||||
|
||||
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
|
||||
CommunicateFacebookJob.perform_now(@article_id)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,6 +20,6 @@ class Observer::Ticket::Article::CommunicateSms < ActiveRecord::Observer
|
|||
return true if type.nil?
|
||||
return true if type.name != 'sms'
|
||||
|
||||
Delayed::Job.enqueue(Observer::Ticket::Article::CommunicateSms::BackgroundJob.new(record.id))
|
||||
CommunicateSmsJob.perform_later(record.id)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,119 +4,10 @@ class Observer::Ticket::Article::CommunicateSms::BackgroundJob
|
|||
end
|
||||
|
||||
def perform
|
||||
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 article.preferences for Ticket::Article.find(#{article.id})") if !article.preferences
|
||||
|
||||
# if sender is system, take article channel
|
||||
if article.sender.name == 'System'
|
||||
log_error(article, "Can't find article.preferences['sms_recipients'] for Ticket::Article.find(#{article.id})") if !article.preferences['sms_recipients']
|
||||
log_error(article, "Can't find article.preferences['channel_id'] for Ticket::Article.find(#{article.id})") if !article.preferences['channel_id']
|
||||
channel = Channel.lookup(id: article.preferences['channel_id'])
|
||||
log_error(article, "No such channel id #{article.preferences['channel_id']}") if !channel
|
||||
|
||||
# if sender is agent, take create channel
|
||||
else
|
||||
log_error(article, "Can't find ticket.preferences['channel_id'] for Ticket.find(#{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
|
||||
if Gem::Version.new(Version.get) >= Gem::Version.new('4.0.x')
|
||||
ActiveSupport::Deprecation.warn("This file has been migrated to the ActiveJob 'CommunicateSmsJob' and is therefore deprecated and should get removed.")
|
||||
end
|
||||
|
||||
begin
|
||||
if article.sender.name == 'System'
|
||||
article.preferences['sms_recipients'].each do |recipient|
|
||||
channel.deliver(
|
||||
recipient: recipient,
|
||||
message: article.body.first(160),
|
||||
)
|
||||
end
|
||||
else
|
||||
channel.deliver(
|
||||
recipient: article.to,
|
||||
message: article.body.first(160),
|
||||
)
|
||||
end
|
||||
rescue => e
|
||||
log_error(article, e.message)
|
||||
return
|
||||
end
|
||||
|
||||
log_success(article)
|
||||
|
||||
return if article.sender.name == 'Agent'
|
||||
|
||||
log_history(article, ticket, 'sms', article.to)
|
||||
CommunicateSmsJob.perform_now(@article_id)
|
||||
end
|
||||
|
||||
# log successful delivery
|
||||
def log_success(article)
|
||||
article.preferences['delivery_status_message'] = nil
|
||||
article.preferences['delivery_status'] = 'success'
|
||||
article.preferences['delivery_status_date'] = Time.zone.now
|
||||
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'] >= max_attempts
|
||||
Ticket::Article.create(
|
||||
ticket_id: local_record.ticket_id,
|
||||
content_type: 'text/plain',
|
||||
body: "#{log_error_prefix}: #{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
|
||||
|
||||
def log_history(article, ticket, history_type, recipient_list)
|
||||
return if recipient_list.blank?
|
||||
|
||||
History.add(
|
||||
o_id: article.id,
|
||||
history_type: history_type,
|
||||
history_object: 'Ticket::Article',
|
||||
related_o_id: ticket.id,
|
||||
related_history_object: 'Ticket',
|
||||
value_from: article.subject,
|
||||
value_to: recipient_list,
|
||||
created_by_id: article.created_by_id,
|
||||
)
|
||||
end
|
||||
|
||||
def log_error_prefix
|
||||
'Unable to send sms 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
|
||||
|
|
|
@ -21,7 +21,7 @@ class Observer::Ticket::Article::CommunicateTelegram < ActiveRecord::Observer
|
|||
type = Ticket::Article::Type.lookup(id: record.type_id)
|
||||
return true if !type.name.match?(/\Atelegram/i)
|
||||
|
||||
Delayed::Job.enqueue(Observer::Ticket::Article::CommunicateTelegram::BackgroundJob.new(record.id))
|
||||
CommunicateTelegramJob.perform_later(record.id)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -4,121 +4,10 @@ class Observer::Ticket::Article::CommunicateTelegram::BackgroundJob
|
|||
end
|
||||
|
||||
def perform
|
||||
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 for Ticket.find(#{article.ticket_id})") if !ticket.preferences
|
||||
log_error(article, "Can't find ticket.preferences['telegram'] for Ticket.find(#{article.ticket_id})") if !ticket.preferences['telegram']
|
||||
log_error(article, "Can't find ticket.preferences['telegram']['chat_id'] for Ticket.find(#{article.ticket_id})") if !ticket.preferences['telegram']['chat_id']
|
||||
if ticket.preferences['telegram'] && ticket.preferences['telegram']['bid']
|
||||
channel = Telegram.bot_by_bot_id(ticket.preferences['telegram']['bid'])
|
||||
end
|
||||
if !channel
|
||||
channel = Channel.lookup(id: ticket.preferences['channel_id'])
|
||||
end
|
||||
log_error(article, "No such channel for bot #{ticket.preferences['bid']} or channel id #{ticket.preferences['channel_id']}") if !channel
|
||||
#log_error(article, "Channel.find(#{channel.id}) isn't a telegram channel!") if channel.options[:adapter] !~ /\Atelegram/i
|
||||
log_error(article, "Channel.find(#{channel.id}) has not telegram api token!") if channel.options[:api_token].blank?
|
||||
|
||||
begin
|
||||
api = TelegramAPI.new(channel.options[:api_token])
|
||||
chat_id = ticket.preferences[:telegram][:chat_id]
|
||||
result = api.sendMessage(chat_id, article.body)
|
||||
me = api.getMe()
|
||||
article.attachments.each do |file|
|
||||
parts = file.filename.split(/^(.*)(\..+?)$/)
|
||||
t = Tempfile.new([parts[1], parts[2]])
|
||||
t.binmode
|
||||
t.write(file.content)
|
||||
t.rewind
|
||||
api.sendDocument(chat_id, t.path.to_s)
|
||||
end
|
||||
rescue => e
|
||||
log_error(article, e.message)
|
||||
return
|
||||
if Gem::Version.new(Version.get) >= Gem::Version.new('4.0.x')
|
||||
ActiveSupport::Deprecation.warn("This file has been migrated to the ActiveJob 'CommunicateTelegramJob' and is therefore deprecated and should get removed.")
|
||||
end
|
||||
|
||||
Rails.logger.debug { "result info: #{result}" }
|
||||
|
||||
# only private, group messages. channel messages do not have from key
|
||||
if result['from'] && result['chat']
|
||||
# fill article with message info
|
||||
article.from = "@#{result['from']['username']}"
|
||||
article.to = "@#{result['chat']['username']}"
|
||||
|
||||
article.preferences['telegram'] = {
|
||||
date: result['date'],
|
||||
from_id: result['from']['id'],
|
||||
chat_id: result['chat']['id'],
|
||||
message_id: result['message_id']
|
||||
}
|
||||
else
|
||||
# fill article with message info (telegram channel)
|
||||
article.from = "@#{me['username']}"
|
||||
article.to = "#{result['chat']['title']} Channel"
|
||||
|
||||
article.preferences['telegram'] = {
|
||||
date: result['date'],
|
||||
from_id: me['id'],
|
||||
chat_id: result['chat']['id'],
|
||||
message_id: result['message_id']
|
||||
}
|
||||
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 = "telegram.#{result['message_id']}.#{result['chat']['id']}"
|
||||
|
||||
article.save!
|
||||
|
||||
Rails.logger.info "Send telegram message 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 telegram message: #{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
|
||||
|
||||
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
|
||||
CommunicateTelegramJob.perform_now(@article_id)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,7 +28,7 @@ class Observer::Ticket::Article::CommunicateTwitter < ActiveRecord::Observer
|
|||
|
||||
raise Exceptions::UnprocessableEntity, 'twitter to: parameter is missing' if record.to.blank? && type['name'] == 'twitter direct-message'
|
||||
|
||||
Delayed::Job.enqueue(Observer::Ticket::Article::CommunicateTwitter::BackgroundJob.new(record.id))
|
||||
CommunicateTwitterJob.perform_later(record.id)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -4,163 +4,10 @@ class Observer::Ticket::Article::CommunicateTwitter::BackgroundJob
|
|||
end
|
||||
|
||||
def perform
|
||||
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
|
||||
if Gem::Version.new(Version.get) >= Gem::Version.new('4.0.x')
|
||||
ActiveSupport::Deprecation.warn("This file has been migrated to the ActiveJob 'CommunicateTwitterJob' and is therefore deprecated and should get removed.")
|
||||
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?, /\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?(Hash)
|
||||
tweet_type = 'DirectMessage'
|
||||
article.message_id = tweet[:event][:id].to_s
|
||||
if tweet[:event] && tweet[:event][:type] == 'message_create'
|
||||
#article.from = "@#{tweet.sender.screen_name}"
|
||||
#article.to = "@#{tweet.recipient.screen_name}"
|
||||
|
||||
article.preferences['twitter'] = {
|
||||
recipient_id: tweet[:event][:message_create][:target][:recipient_id],
|
||||
sender_id: tweet[:event][:message_create][:sender_id],
|
||||
}
|
||||
|
||||
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',
|
||||
},
|
||||
]
|
||||
end
|
||||
|
||||
# regular tweet
|
||||
elsif tweet.instance_of?(Twitter::Tweet)
|
||||
tweet_type = 'Tweet'
|
||||
article.from = "@#{tweet.user.screen_name}"
|
||||
if tweet.user_mentions
|
||||
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,
|
||||
)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
CommunicateTwitterJob.perform_now(@article_id)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -49,7 +49,7 @@ class Observer::Transaction < ActiveRecord::Observer
|
|||
end
|
||||
|
||||
# execute async backends
|
||||
Delayed::Job.enqueue(Transaction::BackgroundJob.new(item, params))
|
||||
TransactionJob.perform_later(item, params)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -179,7 +179,7 @@ returns
|
|||
end
|
||||
|
||||
# send notification
|
||||
Transaction::BackgroundJob.run(
|
||||
TransactionJob.perform_now(
|
||||
object: 'Ticket',
|
||||
type: 'reminder_reached',
|
||||
object_id: ticket.id,
|
||||
|
@ -220,7 +220,7 @@ returns
|
|||
|
||||
# send escalation
|
||||
if ticket.escalation_at < Time.zone.now
|
||||
Transaction::BackgroundJob.run(
|
||||
TransactionJob.perform_now(
|
||||
object: 'Ticket',
|
||||
type: 'escalation',
|
||||
object_id: ticket.id,
|
||||
|
@ -232,7 +232,7 @@ returns
|
|||
end
|
||||
|
||||
# check if warning need to be sent
|
||||
Transaction::BackgroundJob.run(
|
||||
TransactionJob.perform_now(
|
||||
object: 'Ticket',
|
||||
type: 'escalation_warning',
|
||||
object_id: ticket.id,
|
||||
|
@ -1067,7 +1067,7 @@ perform active triggers on ticket
|
|||
local_options[:reset_user_id] = true
|
||||
local_options[:disable] = ['Transaction::Notification']
|
||||
local_options[:trigger_ids] ||= {}
|
||||
local_options[:trigger_ids][ticket.id] ||= []
|
||||
local_options[:trigger_ids][ticket.id.to_s] ||= []
|
||||
local_options[:loop_count] ||= 0
|
||||
local_options[:loop_count] += 1
|
||||
|
||||
|
@ -1220,11 +1220,11 @@ perform active triggers on ticket
|
|||
end
|
||||
end
|
||||
|
||||
if local_options[:trigger_ids][ticket.id].include?(trigger.id)
|
||||
if local_options[:trigger_ids][ticket.id.to_s].include?(trigger.id)
|
||||
logger.info { "Skip trigger (#{trigger.name}/#{trigger.id}) because was already executed for this object (Ticket:#{ticket.id}/Loop:#{local_options[:loop_count]})" }
|
||||
next
|
||||
end
|
||||
local_options[:trigger_ids][ticket.id].push trigger.id
|
||||
local_options[:trigger_ids][ticket.id.to_s].push trigger.id
|
||||
logger.info { "Execute trigger (#{trigger.name}/#{trigger.id}) for this object (Ticket:#{ticket.id}/Loop:#{local_options[:loop_count]})" }
|
||||
|
||||
ticket.perform_changes(trigger.perform, 'trigger', item, user_id)
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Transaction::BackgroundJob
|
||||
def initialize(item, params = {})
|
||||
|
||||
|
@ -23,17 +21,10 @@ class Transaction::BackgroundJob
|
|||
end
|
||||
|
||||
def perform
|
||||
Setting.where(area: 'Transaction::Backend::Async').order(:name).each do |setting|
|
||||
backend = Setting.get(setting.name)
|
||||
next if @params[:disable]&.include?(backend)
|
||||
|
||||
Observer::Transaction.execute_singel_backend(backend.constantize, @item, @params)
|
||||
if Gem::Version.new(Version.get) >= Gem::Version.new('4.0.x')
|
||||
ActiveSupport::Deprecation.warn("This file has been migrated to the ActiveJob 'TransactionJob' and is therefore deprecated and should get removed.")
|
||||
end
|
||||
end
|
||||
|
||||
def self.run(item, params = {})
|
||||
generic = new(item, params)
|
||||
generic.perform
|
||||
TransactionJob.perform_now(@item, @params)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
# Required workaround to serialize ActiveSupport::TimeWithZone, Time, Date and DateTime for ActiveJob
|
||||
# until Rails 6 is used. See:
|
||||
# - https://github.com/rails/rails/issues/18519
|
||||
# - https://github.com/rails/rails/pull/32026
|
||||
# - https://github.com/rails/rails/tree/6-0-stable/activejob/lib/active_job/serializers
|
||||
|
||||
class ActiveSupport::TimeWithZone
|
||||
include GlobalID::Identification
|
||||
|
||||
alias id iso8601
|
||||
|
||||
def self.find(iso8601)
|
||||
Time.iso8601(iso8601).in_time_zone
|
||||
end
|
||||
end
|
||||
|
||||
class Time
|
||||
include GlobalID::Identification
|
||||
|
||||
alias id iso8601
|
||||
|
||||
def self.find(iso8601)
|
||||
Time.iso8601(iso8601)
|
||||
end
|
||||
end
|
||||
|
||||
class Date
|
||||
include GlobalID::Identification
|
||||
|
||||
alias id iso8601
|
||||
|
||||
def self.find(iso8601)
|
||||
Date.iso8601(iso8601)
|
||||
end
|
||||
end
|
||||
|
||||
class DateTime
|
||||
include GlobalID::Identification
|
||||
|
||||
alias id iso8601
|
||||
|
||||
def self.find(iso8601)
|
||||
DateTime.iso8601(iso8601)
|
||||
end
|
||||
end
|
|
@ -4,7 +4,7 @@ class LdapSamaccountnameToUid < ActiveRecord::Migration[5.1]
|
|||
# return if it's a new setup to avoid running the migration
|
||||
return if !Setting.exists?(name: 'system_init_done')
|
||||
|
||||
Delayed::Job.enqueue MigrationJob::LdapSamaccountnameToUid.new
|
||||
MigrateLdapSamaccountnameToUidJob.perform_later
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
require_dependency 'ldap'
|
||||
require_dependency 'ldap/user'
|
||||
|
||||
module MigrationJob
|
||||
class LdapSamaccountnameToUid
|
||||
|
||||
def perform
|
||||
Rails.logger.info 'Checking for active LDAP configuration...'
|
||||
|
||||
if ldap_config.blank?
|
||||
Rails.logger.info 'Blank LDAP configuration. Exiting.'
|
||||
return
|
||||
end
|
||||
|
||||
Rails.logger.info 'Checking for different LDAP uid attribute...'
|
||||
if uid_attribute_obsolete == uid_attribute_new
|
||||
Rails.logger.info 'Equal LDAP uid attributes. Exiting.'
|
||||
return
|
||||
end
|
||||
|
||||
Rails.logger.info 'Starting to migrate LDAP config to new uid attribute...'
|
||||
migrate_ldap_config
|
||||
Rails.logger.info 'LDAP uid attribute migration completed.'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ldap
|
||||
@ldap ||= ::Ldap.new(ldap_config)
|
||||
end
|
||||
|
||||
def ldap_config
|
||||
@ldap_config ||= Import::Ldap.config
|
||||
end
|
||||
|
||||
def uid_attribute_new
|
||||
@uid_attribute_new ||= begin
|
||||
config = {
|
||||
filter: ldap_config['user_filter']
|
||||
}
|
||||
|
||||
::Ldap::User.new(config, ldap: ldap).uid_attribute
|
||||
end
|
||||
end
|
||||
|
||||
def uid_attribute_obsolete
|
||||
@uid_attribute_obsolete ||= ldap_config['user_uid']
|
||||
end
|
||||
|
||||
def migrate_ldap_config
|
||||
ldap_config_new = ldap_config.merge(
|
||||
'user_uid' => uid_attribute_new
|
||||
)
|
||||
|
||||
Setting.set('ldap_config', ldap_config_new)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,12 +6,7 @@ class Sessions::Event::ChatSessionLeaveTemporary < Sessions::Event::ChatBase
|
|||
|
||||
chat_session = current_chat_session
|
||||
|
||||
Delayed::Job.enqueue(
|
||||
Observer::Chat::Leave::BackgroundJob.new(chat_session.id, @client_id, @session),
|
||||
{
|
||||
run_at: Time.zone.now + 0.5.minutes
|
||||
}
|
||||
)
|
||||
ChatLeaveJob.set(wait: 0.5.minutes).perform_later(chat_session.id, @client_id, @session)
|
||||
|
||||
false
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Observer::Ticket::Article::CommunicateTwitter::BackgroundJob, type: :job do
|
||||
RSpec.describe CommunicateTwitterJob, type: :job do
|
||||
|
||||
let(:article) { create(:twitter_article, **(try(:factory_options) || {})) }
|
||||
|
||||
describe 'core behavior', :use_vcr do
|
||||
|
@ -37,12 +38,12 @@ RSpec.describe Observer::Ticket::Article::CommunicateTwitter::BackgroundJob, typ
|
|||
end
|
||||
|
||||
it 'increments the "delivery_retry" preference' do
|
||||
expect { described_class.new(article.id).perform }
|
||||
expect { described_class.perform_now(article.id) }
|
||||
.to change { article.reload.preferences[:delivery_retry] }.to(1)
|
||||
end
|
||||
|
||||
it 'dispatches the tweet' do
|
||||
described_class.new(article.id).perform
|
||||
described_class.perform_now(article.id)
|
||||
|
||||
expect(WebMock)
|
||||
.to have_requested(:post, 'https://api.twitter.com/1.1/statuses/update.json')
|
||||
|
@ -50,14 +51,14 @@ RSpec.describe Observer::Ticket::Article::CommunicateTwitter::BackgroundJob, typ
|
|||
end
|
||||
|
||||
it 'updates the article with tweet attributes' do
|
||||
expect { described_class.new(article.id).perform }
|
||||
expect { described_class.perform_now(article.id) }
|
||||
.to change { article.reload.message_id }.to('1244937367435108360')
|
||||
.and change { article.reload.preferences[:twitter] }.to(hash_including(tweet_attributes))
|
||||
.and change { article.reload.preferences[:links] }.to(links_array)
|
||||
end
|
||||
|
||||
it 'sets the appropriate delivery status attributes' do
|
||||
expect { described_class.new(article.id).perform }
|
||||
expect { described_class.perform_now(article.id) }
|
||||
.to change { article.reload.preferences[:delivery_status] }.to('success')
|
||||
.and change { article.reload.preferences[:delivery_status_date] }.to(an_instance_of(ActiveSupport::TimeWithZone))
|
||||
.and not_change { article.reload.preferences[:delivery_status_message] }.from(nil)
|
||||
|
@ -67,7 +68,7 @@ RSpec.describe Observer::Ticket::Article::CommunicateTwitter::BackgroundJob, typ
|
|||
let(:factory_options) { { body: '@twitter @twitterlive Don’t mind me, just testing the API' } }
|
||||
|
||||
it 'updates the article with tweet recipients' do
|
||||
expect { described_class.new(article.id).perform }
|
||||
expect { described_class.perform_now(article.id) }
|
||||
.to change { article.reload.to }.to('@Twitter @TwitterLive')
|
||||
end
|
||||
end
|
||||
|
@ -105,12 +106,12 @@ RSpec.describe Observer::Ticket::Article::CommunicateTwitter::BackgroundJob, typ
|
|||
end
|
||||
|
||||
it 'increments the "delivery_retry" preference' do
|
||||
expect { described_class.new(article.id).perform }
|
||||
expect { described_class.perform_now(article.id) }
|
||||
.to change { article.reload.preferences[:delivery_retry] }.to(1)
|
||||
end
|
||||
|
||||
it 'dispatches the DM' do
|
||||
described_class.new(article.id).perform
|
||||
described_class.perform_now(article.id)
|
||||
|
||||
expect(WebMock)
|
||||
.to have_requested(:post, 'https://api.twitter.com/1.1/direct_messages/events/new.json')
|
||||
|
@ -118,14 +119,14 @@ RSpec.describe Observer::Ticket::Article::CommunicateTwitter::BackgroundJob, typ
|
|||
end
|
||||
|
||||
it 'updates the article with DM attributes' do
|
||||
expect { described_class.new(article.id).perform }
|
||||
expect { described_class.perform_now(article.id) }
|
||||
.to change { article.reload.message_id }.to('1244953398509617156')
|
||||
.and change { article.reload.preferences[:twitter] }.to(hash_including(dm_attributes))
|
||||
.and change { article.reload.preferences[:links] }.to(links_array)
|
||||
end
|
||||
|
||||
it 'sets the appropriate delivery status attributes' do
|
||||
expect { described_class.new(article.id).perform }
|
||||
expect { described_class.perform_now(article.id) }
|
||||
.to change { article.reload.preferences[:delivery_status] }.to('success')
|
||||
.and change { article.reload.preferences[:delivery_status_date] }.to(an_instance_of(ActiveSupport::TimeWithZone))
|
||||
.and not_change { article.reload.preferences[:delivery_status_message] }.from(nil)
|
||||
|
@ -135,9 +136,8 @@ RSpec.describe Observer::Ticket::Article::CommunicateTwitter::BackgroundJob, typ
|
|||
describe 'failure cases' do
|
||||
shared_examples 'for failure cases' do
|
||||
it 'raises an error and sets the appropriate delivery status messages' do
|
||||
expect { described_class.new(article.id).perform }
|
||||
.to raise_error(error_message)
|
||||
.and change { article.reload.preferences[:delivery_status] }.to('fail')
|
||||
expect { described_class.perform_now(article.id) }
|
||||
.to change { article.reload.preferences[:delivery_status] }.to('fail')
|
||||
.and change { article.reload.preferences[:delivery_status_date] }.to(an_instance_of(ActiveSupport::TimeWithZone))
|
||||
.and change { article.reload.preferences[:delivery_status_message] }.to(error_message)
|
||||
end
|
||||
|
@ -166,7 +166,7 @@ RSpec.describe Observer::Ticket::Article::CommunicateTwitter::BackgroundJob, typ
|
|||
let!(:new_channel) { create(:twitter_channel, custom_options: { user: { screen_name: channel.options[:user][:screen_name] } }) }
|
||||
|
||||
it 'uses that channel' do
|
||||
described_class.new(article.id).perform
|
||||
described_class.perform_now(article.id)
|
||||
|
||||
expect(WebMock)
|
||||
.to have_requested(:post, 'https://api.twitter.com/1.1/statuses/update.json')
|
||||
|
@ -216,9 +216,8 @@ RSpec.describe Observer::Ticket::Article::CommunicateTwitter::BackgroundJob, typ
|
|||
let(:factory_options) { { preferences: { delivery_retry: 3 } } }
|
||||
|
||||
it 'adds a delivery failure note (article) to the ticket' do
|
||||
expect { described_class.new(article.id).perform }
|
||||
.to raise_error(error_message)
|
||||
.and change { article.ticket.reload.articles.count }.by(1)
|
||||
expect { described_class.perform_now(article.id) }
|
||||
.to change { article.ticket.reload.articles.count }.by(1)
|
||||
|
||||
expect(Ticket::Article.last.attributes).to include(
|
||||
'content_type' => 'text/plain',
|
|
@ -1,12 +1,14 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe MigrationJob::LdapSamaccountnameToUid do
|
||||
RSpec.describe MigrateLdapSamaccountnameToUidJob, type: :job do
|
||||
|
||||
it 'performs no changes if no LDAP config present' do
|
||||
allow(Setting).to receive(:set)
|
||||
allow(Import::Ldap).to receive(:config).and_return(nil)
|
||||
|
||||
described_class.new.perform
|
||||
described_class.perform_now
|
||||
|
||||
expect(Import::Ldap).to have_received(:config)
|
||||
expect(Setting).not_to have_received(:set)
|
||||
end
|
||||
|
||||
|
@ -24,8 +26,12 @@ RSpec.describe MigrationJob::LdapSamaccountnameToUid do
|
|||
|
||||
allow(::Ldap).to receive(:new)
|
||||
|
||||
described_class.new.perform
|
||||
described_class.perform_now
|
||||
|
||||
expect(Setting).not_to have_received(:set)
|
||||
expect(Import::Ldap).to have_received(:config)
|
||||
expect(ldap_user).to have_received(:uid_attribute)
|
||||
expect(::Ldap::User).to have_received(:new)
|
||||
end
|
||||
|
||||
it 'performs Setting change if uid attribute differ' do
|
||||
|
@ -37,6 +43,7 @@ RSpec.describe MigrationJob::LdapSamaccountnameToUid do
|
|||
}
|
||||
|
||||
allow(Setting).to receive(:set)
|
||||
allow(Setting).to receive(:set).with('ldap_config', ldap_config_new)
|
||||
|
||||
allow(Import::Ldap).to receive(:config).and_return(ldap_config_obsolete)
|
||||
|
||||
|
@ -46,8 +53,9 @@ RSpec.describe MigrationJob::LdapSamaccountnameToUid do
|
|||
|
||||
allow(::Ldap).to receive(:new)
|
||||
|
||||
described_class.new.perform
|
||||
described_class.perform_now
|
||||
|
||||
expect(Setting).to have_received(:set).with('ldap_config', ldap_config_new)
|
||||
expect(ldap_user).to have_received(:uid_attribute)
|
||||
end
|
||||
end
|
|
@ -677,7 +677,7 @@ RSpec.describe Channel::Driver::Twitter do
|
|||
describe '#send', :use_vcr do
|
||||
shared_examples 'for #send' do
|
||||
# Channel#deliver takes a hash in the following format
|
||||
# (see Observer::Ticket::Article::CommunicateTwitter::BackgroundJob#perform)
|
||||
# (see CommunicateTwitterJob#perform)
|
||||
#
|
||||
# Why not just accept the whole article?
|
||||
# Presumably so all channels have a consistent interface...
|
||||
|
@ -990,10 +990,7 @@ RSpec.describe Channel::Driver::Twitter do
|
|||
# and then manually copied into the existing VCR cassette for this example.
|
||||
|
||||
context '…but before the BG job has "synced" article.message_id with tweet.id)' do
|
||||
let(:twitter_job) { Delayed::Job.find_by(handler: <<~YML) }
|
||||
--- !ruby/object:Observer::Ticket::Article::CommunicateTwitter::BackgroundJob
|
||||
article_id: #{tweet.id}
|
||||
YML
|
||||
let(:twitter_job) { Delayed::Job.where("handler LIKE '%job_class: CommunicateTwitterJob%#{tweet.id}%'").first }
|
||||
|
||||
around do |example|
|
||||
# Run BG job (Why not use Scheduler.worker?
|
||||
|
|
|
@ -1,27 +1,19 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Observer::Ticket::Article::CommunicateTwitter do
|
||||
RSpec.describe Observer::Ticket::Article::CommunicateTwitter, performs_jobs: true do
|
||||
before { allow(Delayed::Job).to receive(:enqueue).and_call_original }
|
||||
|
||||
let(:article) { create(:ticket_article, **(try(:factory_options) || {})) }
|
||||
|
||||
shared_examples 'for no-op' do
|
||||
it 'is a no-op' do
|
||||
expect(Delayed::Job)
|
||||
.not_to receive(:enqueue)
|
||||
.with(instance_of(Observer::Ticket::Article::CommunicateTwitter::BackgroundJob))
|
||||
|
||||
article
|
||||
expect { article }.not_to have_enqueued_job(CommunicateTwitterJob)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'for success' do
|
||||
it 'enqueues the Twitter background job' do
|
||||
expect(Delayed::Job)
|
||||
.to receive(:enqueue)
|
||||
.with(an_instance_of(Observer::Ticket::Article::CommunicateTwitter::BackgroundJob))
|
||||
|
||||
article
|
||||
expect { article }.to have_enqueued_job(CommunicateTwitterJob)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue