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
|
- source /etc/profile.d/rvm.sh
|
||||||
- bundle install -j $(nproc) --path vendor
|
- bundle install -j $(nproc) --path vendor
|
||||||
- bundle exec ruby script/build/database_config.rb
|
- 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_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_2368_add_indices_to_histories_and_tickets_spec.rb'
|
||||||
- 'spec/db/migrate/issue_2541_fix_notification_email_without_body_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_active_job_lock_spec.rb'
|
||||||
- 'spec/jobs/concerns/has_collection_update_spec.rb'
|
- 'spec/jobs/concerns/has_collection_update_spec.rb'
|
||||||
- 'spec/jobs/concerns/has_ticket_create_screen_impact_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/required_spec.rb'
|
||||||
- 'spec/models/object_manager/attribute/validation_spec.rb'
|
- 'spec/models/object_manager/attribute/validation_spec.rb'
|
||||||
- 'spec/models/object_manager/attribute_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/observer/ticket/article/communicate_twitter_spec.rb'
|
||||||
- 'spec/models/overview_spec.rb'
|
- 'spec/models/overview_spec.rb'
|
||||||
- 'spec/models/role_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/issue_2867_footer_header_public_link_spec.rb'
|
||||||
- 'spec/db/migrate/object_manager_attribute_date_remove_future_past_spec.rb'
|
- 'spec/db/migrate/object_manager_attribute_date_remove_future_past_spec.rb'
|
||||||
- 'spec/db/migrate/rename_locale_on_users_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/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/ticket_user_ticket_counter_job_spec.rb'
|
||||||
- 'spec/jobs/user_device_log_job_spec.rb'
|
- 'spec/jobs/user_device_log_job_spec.rb'
|
||||||
- 'spec/lib/auth/internal_spec.rb'
|
- 'spec/lib/auth/internal_spec.rb'
|
||||||
|
@ -209,7 +211,6 @@ RSpec/ExampleLength:
|
||||||
- 'spec/lib/ldap/group_spec.rb'
|
- 'spec/lib/ldap/group_spec.rb'
|
||||||
- 'spec/lib/ldap/user_spec.rb'
|
- 'spec/lib/ldap/user_spec.rb'
|
||||||
- 'spec/lib/ldap_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/mailer_spec.rb'
|
||||||
- 'spec/lib/notification_factory/renderer_spec.rb'
|
- 'spec/lib/notification_factory/renderer_spec.rb'
|
||||||
- 'spec/lib/notification_factory/slack_spec.rb'
|
- 'spec/lib/notification_factory/slack_spec.rb'
|
||||||
|
@ -249,7 +250,6 @@ RSpec/ExampleLength:
|
||||||
- 'spec/models/history_spec.rb'
|
- 'spec/models/history_spec.rb'
|
||||||
- 'spec/models/import_job_spec.rb'
|
- 'spec/models/import_job_spec.rb'
|
||||||
- 'spec/models/object_manager/attribute_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/overview_spec.rb'
|
||||||
- 'spec/models/recent_view_spec.rb'
|
- 'spec/models/recent_view_spec.rb'
|
||||||
- 'spec/models/role_group_spec.rb'
|
- 'spec/models/role_group_spec.rb'
|
||||||
|
@ -357,6 +357,7 @@ RSpec/InstanceVariable:
|
||||||
|
|
||||||
RSpec/LetSetup:
|
RSpec/LetSetup:
|
||||||
Exclude:
|
Exclude:
|
||||||
|
- 'spec/jobs/communicate_twitter_job_spec.rb'
|
||||||
- 'spec/jobs/ticket_online_notification_seen_job_spec.rb'
|
- 'spec/jobs/ticket_online_notification_seen_job_spec.rb'
|
||||||
- 'spec/lib/external_credential/google_spec.rb'
|
- 'spec/lib/external_credential/google_spec.rb'
|
||||||
- 'spec/lib/external_credential/office365_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/caller_id_spec.rb'
|
||||||
- 'spec/models/cti/driver/base_spec.rb'
|
- 'spec/models/cti/driver/base_spec.rb'
|
||||||
- 'spec/models/cti/log_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/organization_spec.rb'
|
||||||
- 'spec/models/role_group_spec.rb'
|
- 'spec/models/role_group_spec.rb'
|
||||||
- 'spec/models/tag_spec.rb'
|
- 'spec/models/tag_spec.rb'
|
||||||
|
@ -431,7 +431,6 @@ RSpec/MessageSpies:
|
||||||
- 'spec/lib/ldap/guid_spec.rb'
|
- 'spec/lib/ldap/guid_spec.rb'
|
||||||
- 'spec/lib/ldap/user_spec.rb'
|
- 'spec/lib/ldap/user_spec.rb'
|
||||||
- 'spec/lib/ldap_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/sequence/import/ldap/users_spec.rb'
|
||||||
- 'spec/lib/sequencer/unit/common/attribute_mapper_spec.rb'
|
- 'spec/lib/sequencer/unit/common/attribute_mapper_spec.rb'
|
||||||
- 'spec/lib/sequencer/unit/import/common/mapping/flat_keys_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/issue_1905_exchange_login_from_remote_id_spec.rb'
|
||||||
- 'spec/db/migrate/object_manager_attribute_date_remove_future_past_spec.rb'
|
- 'spec/db/migrate/object_manager_attribute_date_remove_future_past_spec.rb'
|
||||||
- 'spec/db/migrate/rename_locale_on_users_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/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/search_index_job_spec.rb'
|
||||||
- 'spec/jobs/ticket_user_ticket_counter_job_spec.rb'
|
- 'spec/jobs/ticket_user_ticket_counter_job_spec.rb'
|
||||||
- 'spec/lib/auth/developer_spec.rb'
|
- 'spec/lib/auth/developer_spec.rb'
|
||||||
|
@ -505,7 +506,6 @@ RSpec/MultipleExpectations:
|
||||||
- 'spec/lib/ldap/guid_spec.rb'
|
- 'spec/lib/ldap/guid_spec.rb'
|
||||||
- 'spec/lib/ldap/user_spec.rb'
|
- 'spec/lib/ldap/user_spec.rb'
|
||||||
- 'spec/lib/ldap_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/mailer_spec.rb'
|
||||||
- 'spec/lib/password_hash_spec.rb'
|
- 'spec/lib/password_hash_spec.rb'
|
||||||
- 'spec/lib/secure_mailing/smime_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/backend_spec.rb'
|
||||||
- 'spec/models/object_manager/attribute/validation_spec.rb'
|
- 'spec/models/object_manager/attribute/validation_spec.rb'
|
||||||
- 'spec/models/object_manager/attribute_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/overview_spec.rb'
|
||||||
- 'spec/models/scheduler_spec.rb'
|
- 'spec/models/scheduler_spec.rb'
|
||||||
- 'spec/models/smime_certificate_spec.rb'
|
- 'spec/models/smime_certificate_spec.rb'
|
||||||
|
@ -613,6 +612,7 @@ RSpec/NamedSubject:
|
||||||
RSpec/NestedGroups:
|
RSpec/NestedGroups:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'spec/db/migrate/issue_2541_fix_notification_email_without_body_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_collection_update_spec.rb'
|
- 'spec/jobs/concerns/has_collection_update_spec.rb'
|
||||||
- 'spec/jobs/concerns/has_ticket_create_screen_impact_spec.rb'
|
- 'spec/jobs/concerns/has_ticket_create_screen_impact_spec.rb'
|
||||||
- 'spec/lib/application_handle_info_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/required_spec.rb'
|
||||||
- 'spec/models/object_manager/attribute/validation_spec.rb'
|
- 'spec/models/object_manager/attribute/validation_spec.rb'
|
||||||
- 'spec/models/object_manager/attribute_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/organization_spec.rb'
|
||||||
- 'spec/models/recent_view_spec.rb'
|
- 'spec/models/recent_view_spec.rb'
|
||||||
- 'spec/models/role_spec.rb'
|
- 'spec/models/role_spec.rb'
|
||||||
|
@ -727,6 +726,7 @@ RSpec/SubjectStub:
|
||||||
RSpec/VerifiedDoubles:
|
RSpec/VerifiedDoubles:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'spec/db/migrate/issue_2460_fix_corrupted_twitter_ids_spec.rb'
|
- '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/auth/ldap_spec.rb'
|
||||||
- 'spec/lib/external_sync_spec.rb'
|
- 'spec/lib/external_sync_spec.rb'
|
||||||
- 'spec/lib/import/zendesk/object_attribute/base_examples.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/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/attachment/request_spec.rb'
|
||||||
- 'spec/lib/sequencer/unit/import/zendesk/ticket/comment/source_based_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'
|
- 'spec/models/ticket/number_spec.rb'
|
||||||
|
|
||||||
RSpec/MultipleMemoizedHelpers:
|
RSpec/MultipleMemoizedHelpers:
|
||||||
|
|
|
@ -75,8 +75,13 @@ Metrics/AbcSize:
|
||||||
- 'app/controllers/users_controller.rb'
|
- 'app/controllers/users_controller.rb'
|
||||||
- 'app/helpers/knowledge_base_rich_text_helper.rb'
|
- 'app/helpers/knowledge_base_rich_text_helper.rb'
|
||||||
- 'app/jobs/collection_update_job.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/concerns/has_active_job_lock.rb'
|
||||||
- 'app/jobs/imap_authentication_migration_cleanup_job.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_article_communicate_email_job.rb'
|
||||||
- 'app/jobs/ticket_user_ticket_counter_job.rb'
|
- 'app/jobs/ticket_user_ticket_counter_job.rb'
|
||||||
- 'app/models/activity_stream.rb'
|
- 'app/models/activity_stream.rb'
|
||||||
|
@ -154,13 +159,9 @@ Metrics/AbcSize:
|
||||||
- 'app/models/observer/sla/ticket_rebuild_escalation.rb'
|
- 'app/models/observer/sla/ticket_rebuild_escalation.rb'
|
||||||
- 'app/models/observer/ticket/article/communicate_email.rb'
|
- 'app/models/observer/ticket/article/communicate_email.rb'
|
||||||
- 'app/models/observer/ticket/article/communicate_facebook.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.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.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.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_email.rb'
|
||||||
- 'app/models/observer/ticket/article/fillup_from_general.rb'
|
- 'app/models/observer/ticket/article/fillup_from_general.rb'
|
||||||
- 'app/models/observer/ticket/article/fillup_from_origin_by_id.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/knowledge_base/menu_item_update_action.rb'
|
||||||
- 'lib/ldap/group.rb'
|
- 'lib/ldap/group.rb'
|
||||||
- 'lib/ldap/user.rb'
|
- 'lib/ldap/user.rb'
|
||||||
- 'lib/migration_job/ldap_samaccountname_to_uid.rb'
|
|
||||||
- 'lib/models.rb'
|
- 'lib/models.rb'
|
||||||
- 'lib/notification_factory/mailer.rb'
|
- 'lib/notification_factory/mailer.rb'
|
||||||
- 'lib/notification_factory/renderer.rb'
|
- 'lib/notification_factory/renderer.rb'
|
||||||
|
@ -486,6 +486,10 @@ Metrics/CyclomaticComplexity:
|
||||||
- 'app/controllers/user_access_token_controller.rb'
|
- 'app/controllers/user_access_token_controller.rb'
|
||||||
- 'app/controllers/users_controller.rb'
|
- 'app/controllers/users_controller.rb'
|
||||||
- 'app/jobs/collection_update_job.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_article_communicate_email_job.rb'
|
||||||
- 'app/jobs/ticket_create_screen_job.rb'
|
- 'app/jobs/ticket_create_screen_job.rb'
|
||||||
- 'app/jobs/ticket_user_ticket_counter_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/sla/ticket_rebuild_escalation.rb'
|
||||||
- 'app/models/observer/ticket/article/communicate_email.rb'
|
- 'app/models/observer/ticket/article/communicate_email.rb'
|
||||||
- 'app/models/observer/ticket/article/communicate_facebook.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.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.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_email.rb'
|
||||||
- 'app/models/observer/ticket/article/fillup_from_general.rb'
|
- 'app/models/observer/ticket/article/fillup_from_general.rb'
|
||||||
- 'app/models/observer/ticket/article/fillup_from_origin_by_id.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/time_accountings_controller.rb'
|
||||||
- 'app/controllers/users_controller.rb'
|
- 'app/controllers/users_controller.rb'
|
||||||
- 'app/jobs/collection_update_job.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_article_communicate_email_job.rb'
|
||||||
- 'app/models/activity_stream/assets.rb'
|
- 'app/models/activity_stream/assets.rb'
|
||||||
- 'app/models/application_model/can_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/sla/ticket_rebuild_escalation.rb'
|
||||||
- 'app/models/observer/ticket/article/communicate_email.rb'
|
- 'app/models/observer/ticket/article/communicate_email.rb'
|
||||||
- 'app/models/observer/ticket/article/communicate_facebook.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.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.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_email.rb'
|
||||||
- 'app/models/observer/ticket/article/fillup_from_general.rb'
|
- 'app/models/observer/ticket/article/fillup_from_general.rb'
|
||||||
- 'app/models/observer/ticket/article/fillup_from_origin_by_id.rb'
|
- 'app/models/observer/ticket/article/fillup_from_origin_by_id.rb'
|
||||||
|
|
|
@ -22,7 +22,7 @@ module Integration::ImportJobBase
|
||||||
def job_start_create
|
def job_start_create
|
||||||
if !ImportJob.exists?(name: backend, finished_at: nil)
|
if !ImportJob.exists?(name: backend, finished_at: nil)
|
||||||
job = ImportJob.create(name: backend)
|
job = ImportJob.create(name: backend)
|
||||||
job.delay.start
|
AsyncImportJob.perform_later(job)
|
||||||
end
|
end
|
||||||
render json: {
|
render json: {
|
||||||
result: 'ok',
|
result: 'ok',
|
||||||
|
|
|
@ -115,7 +115,7 @@ class ImportOtrsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
# start migration
|
# start migration
|
||||||
Import::OTRS.delay.start_bg
|
AsyncOtrsImportJob.perform_later
|
||||||
|
|
||||||
render json: {
|
render json: {
|
||||||
result: 'ok',
|
result: 'ok',
|
||||||
|
|
|
@ -98,7 +98,7 @@ class ImportZendeskController < ApplicationController
|
||||||
Setting.set('import_backend', 'zendesk')
|
Setting.set('import_backend', 'zendesk')
|
||||||
|
|
||||||
job = ImportJob.create(name: 'Import::Zendesk')
|
job = ImportJob.create(name: 'Import::Zendesk')
|
||||||
job.delay.start
|
AsyncImportJob.perform_later(job)
|
||||||
|
|
||||||
render json: {
|
render json: {
|
||||||
result: 'ok',
|
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)
|
return if exists?(name: params[:name], dry_run: true, finished_at: nil)
|
||||||
|
|
||||||
params[:dry_run] = true
|
params[:dry_run] = true
|
||||||
instance = create(params.except(:delay))
|
job = create(params.except(:delay))
|
||||||
|
|
||||||
if params.fetch(:delay, true)
|
if params.fetch(:delay, true)
|
||||||
instance.delay.start
|
AsyncImportJob.perform_later(job)
|
||||||
else
|
else
|
||||||
instance.start
|
job.start
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,36 +6,10 @@ class Observer::Chat::Leave::BackgroundJob
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
|
if Gem::Version.new(Version.get) >= Gem::Version.new('4.0.x')
|
||||||
# check if customer has permanently left the conversation
|
ActiveSupport::Deprecation.warn("This file has been migrated to the ActiveJob 'ChatLeaveJob' and is therefore deprecated and should get removed.")
|
||||||
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
|
end
|
||||||
|
|
||||||
# notify participants
|
ChatLeaveJob.perform_now(@chat_session_id, @client_id, @session)
|
||||||
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
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,7 +25,7 @@ class Observer::Ticket::Article::CommunicateFacebook < ActiveRecord::Observer
|
||||||
return true if type.nil?
|
return true if type.nil?
|
||||||
return true if !type.name.start_with?('facebook')
|
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
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,102 +4,10 @@ class Observer::Ticket::Article::CommunicateFacebook::BackgroundJob
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
article = Ticket::Article.find(@article_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.")
|
||||||
# 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
|
end
|
||||||
|
|
||||||
# fill in_reply_to
|
CommunicateFacebookJob.perform_now(@article_id)
|
||||||
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
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,6 +20,6 @@ class Observer::Ticket::Article::CommunicateSms < ActiveRecord::Observer
|
||||||
return true if type.nil?
|
return true if type.nil?
|
||||||
return true if type.name != 'sms'
|
return true if type.name != 'sms'
|
||||||
|
|
||||||
Delayed::Job.enqueue(Observer::Ticket::Article::CommunicateSms::BackgroundJob.new(record.id))
|
CommunicateSmsJob.perform_later(record.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,119 +4,10 @@ class Observer::Ticket::Article::CommunicateSms::BackgroundJob
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
article = Ticket::Article.find(@article_id)
|
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.")
|
||||||
# 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
|
end
|
||||||
|
|
||||||
begin
|
CommunicateSmsJob.perform_now(@article_id)
|
||||||
if article.sender.name == 'System'
|
|
||||||
article.preferences['sms_recipients'].each do |recipient|
|
|
||||||
channel.deliver(
|
|
||||||
recipient: recipient,
|
|
||||||
message: article.body.first(160),
|
|
||||||
)
|
|
||||||
end
|
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
|
|
||||||
|
|
||||||
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
|
end
|
||||||
|
|
|
@ -21,7 +21,7 @@ class Observer::Ticket::Article::CommunicateTelegram < ActiveRecord::Observer
|
||||||
type = Ticket::Article::Type.lookup(id: record.type_id)
|
type = Ticket::Article::Type.lookup(id: record.type_id)
|
||||||
return true if !type.name.match?(/\Atelegram/i)
|
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
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,121 +4,10 @@ class Observer::Ticket::Article::CommunicateTelegram::BackgroundJob
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
article = Ticket::Article.find(@article_id)
|
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.")
|
||||||
# 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
|
end
|
||||||
|
|
||||||
Rails.logger.debug { "result info: #{result}" }
|
CommunicateTelegramJob.perform_now(@article_id)
|
||||||
|
|
||||||
# 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
|
|
||||||
end
|
end
|
||||||
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'
|
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
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,163 +4,10 @@ class Observer::Ticket::Article::CommunicateTwitter::BackgroundJob
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
article = Ticket::Article.find(@article_id)
|
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.")
|
||||||
# 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
|
end
|
||||||
|
|
||||||
log_error(article, "No such channel id #{ticket.preferences['channel_id']}") if !channel
|
CommunicateTwitterJob.perform_now(@article_id)
|
||||||
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
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -49,7 +49,7 @@ class Observer::Transaction < ActiveRecord::Observer
|
||||||
end
|
end
|
||||||
|
|
||||||
# execute async backends
|
# execute async backends
|
||||||
Delayed::Job.enqueue(Transaction::BackgroundJob.new(item, params))
|
TransactionJob.perform_later(item, params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -179,7 +179,7 @@ returns
|
||||||
end
|
end
|
||||||
|
|
||||||
# send notification
|
# send notification
|
||||||
Transaction::BackgroundJob.run(
|
TransactionJob.perform_now(
|
||||||
object: 'Ticket',
|
object: 'Ticket',
|
||||||
type: 'reminder_reached',
|
type: 'reminder_reached',
|
||||||
object_id: ticket.id,
|
object_id: ticket.id,
|
||||||
|
@ -220,7 +220,7 @@ returns
|
||||||
|
|
||||||
# send escalation
|
# send escalation
|
||||||
if ticket.escalation_at < Time.zone.now
|
if ticket.escalation_at < Time.zone.now
|
||||||
Transaction::BackgroundJob.run(
|
TransactionJob.perform_now(
|
||||||
object: 'Ticket',
|
object: 'Ticket',
|
||||||
type: 'escalation',
|
type: 'escalation',
|
||||||
object_id: ticket.id,
|
object_id: ticket.id,
|
||||||
|
@ -232,7 +232,7 @@ returns
|
||||||
end
|
end
|
||||||
|
|
||||||
# check if warning need to be sent
|
# check if warning need to be sent
|
||||||
Transaction::BackgroundJob.run(
|
TransactionJob.perform_now(
|
||||||
object: 'Ticket',
|
object: 'Ticket',
|
||||||
type: 'escalation_warning',
|
type: 'escalation_warning',
|
||||||
object_id: ticket.id,
|
object_id: ticket.id,
|
||||||
|
@ -1067,7 +1067,7 @@ perform active triggers on ticket
|
||||||
local_options[:reset_user_id] = true
|
local_options[:reset_user_id] = true
|
||||||
local_options[:disable] = ['Transaction::Notification']
|
local_options[:disable] = ['Transaction::Notification']
|
||||||
local_options[:trigger_ids] ||= {}
|
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] ||= 0
|
||||||
local_options[:loop_count] += 1
|
local_options[:loop_count] += 1
|
||||||
|
|
||||||
|
@ -1220,11 +1220,11 @@ perform active triggers on ticket
|
||||||
end
|
end
|
||||||
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]})" }
|
logger.info { "Skip trigger (#{trigger.name}/#{trigger.id}) because was already executed for this object (Ticket:#{ticket.id}/Loop:#{local_options[:loop_count]})" }
|
||||||
next
|
next
|
||||||
end
|
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]})" }
|
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)
|
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
|
class Transaction::BackgroundJob
|
||||||
def initialize(item, params = {})
|
def initialize(item, params = {})
|
||||||
|
|
||||||
|
@ -23,17 +21,10 @@ class Transaction::BackgroundJob
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
Setting.where(area: 'Transaction::Backend::Async').order(:name).each do |setting|
|
if Gem::Version.new(Version.get) >= Gem::Version.new('4.0.x')
|
||||||
backend = Setting.get(setting.name)
|
ActiveSupport::Deprecation.warn("This file has been migrated to the ActiveJob 'TransactionJob' and is therefore deprecated and should get removed.")
|
||||||
next if @params[:disable]&.include?(backend)
|
|
||||||
|
|
||||||
Observer::Transaction.execute_singel_backend(backend.constantize, @item, @params)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.run(item, params = {})
|
TransactionJob.perform_now(@item, @params)
|
||||||
generic = new(item, params)
|
|
||||||
generic.perform
|
|
||||||
end
|
end
|
||||||
|
|
||||||
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 it's a new setup to avoid running the migration
|
||||||
return if !Setting.exists?(name: 'system_init_done')
|
return if !Setting.exists?(name: 'system_init_done')
|
||||||
|
|
||||||
Delayed::Job.enqueue MigrationJob::LdapSamaccountnameToUid.new
|
MigrateLdapSamaccountnameToUidJob.perform_later
|
||||||
end
|
end
|
||||||
|
|
||||||
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
|
chat_session = current_chat_session
|
||||||
|
|
||||||
Delayed::Job.enqueue(
|
ChatLeaveJob.set(wait: 0.5.minutes).perform_later(chat_session.id, @client_id, @session)
|
||||||
Observer::Chat::Leave::BackgroundJob.new(chat_session.id, @client_id, @session),
|
|
||||||
{
|
|
||||||
run_at: Time.zone.now + 0.5.minutes
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
require 'rails_helper'
|
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) || {})) }
|
let(:article) { create(:twitter_article, **(try(:factory_options) || {})) }
|
||||||
|
|
||||||
describe 'core behavior', :use_vcr do
|
describe 'core behavior', :use_vcr do
|
||||||
|
@ -37,12 +38,12 @@ RSpec.describe Observer::Ticket::Article::CommunicateTwitter::BackgroundJob, typ
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'increments the "delivery_retry" preference' do
|
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)
|
.to change { article.reload.preferences[:delivery_retry] }.to(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'dispatches the tweet' do
|
it 'dispatches the tweet' do
|
||||||
described_class.new(article.id).perform
|
described_class.perform_now(article.id)
|
||||||
|
|
||||||
expect(WebMock)
|
expect(WebMock)
|
||||||
.to have_requested(:post, 'https://api.twitter.com/1.1/statuses/update.json')
|
.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
|
end
|
||||||
|
|
||||||
it 'updates the article with tweet attributes' do
|
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')
|
.to change { article.reload.message_id }.to('1244937367435108360')
|
||||||
.and change { article.reload.preferences[:twitter] }.to(hash_including(tweet_attributes))
|
.and change { article.reload.preferences[:twitter] }.to(hash_including(tweet_attributes))
|
||||||
.and change { article.reload.preferences[:links] }.to(links_array)
|
.and change { article.reload.preferences[:links] }.to(links_array)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets the appropriate delivery status attributes' do
|
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')
|
.to change { article.reload.preferences[:delivery_status] }.to('success')
|
||||||
.and change { article.reload.preferences[:delivery_status_date] }.to(an_instance_of(ActiveSupport::TimeWithZone))
|
.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)
|
.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' } }
|
let(:factory_options) { { body: '@twitter @twitterlive Don’t mind me, just testing the API' } }
|
||||||
|
|
||||||
it 'updates the article with tweet recipients' do
|
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')
|
.to change { article.reload.to }.to('@Twitter @TwitterLive')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -105,12 +106,12 @@ RSpec.describe Observer::Ticket::Article::CommunicateTwitter::BackgroundJob, typ
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'increments the "delivery_retry" preference' do
|
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)
|
.to change { article.reload.preferences[:delivery_retry] }.to(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'dispatches the DM' do
|
it 'dispatches the DM' do
|
||||||
described_class.new(article.id).perform
|
described_class.perform_now(article.id)
|
||||||
|
|
||||||
expect(WebMock)
|
expect(WebMock)
|
||||||
.to have_requested(:post, 'https://api.twitter.com/1.1/direct_messages/events/new.json')
|
.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
|
end
|
||||||
|
|
||||||
it 'updates the article with DM attributes' do
|
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')
|
.to change { article.reload.message_id }.to('1244953398509617156')
|
||||||
.and change { article.reload.preferences[:twitter] }.to(hash_including(dm_attributes))
|
.and change { article.reload.preferences[:twitter] }.to(hash_including(dm_attributes))
|
||||||
.and change { article.reload.preferences[:links] }.to(links_array)
|
.and change { article.reload.preferences[:links] }.to(links_array)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets the appropriate delivery status attributes' do
|
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')
|
.to change { article.reload.preferences[:delivery_status] }.to('success')
|
||||||
.and change { article.reload.preferences[:delivery_status_date] }.to(an_instance_of(ActiveSupport::TimeWithZone))
|
.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)
|
.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
|
describe 'failure cases' do
|
||||||
shared_examples 'for failure cases' do
|
shared_examples 'for failure cases' do
|
||||||
it 'raises an error and sets the appropriate delivery status messages' do
|
it 'raises an error and sets the appropriate delivery status messages' do
|
||||||
expect { described_class.new(article.id).perform }
|
expect { described_class.perform_now(article.id) }
|
||||||
.to raise_error(error_message)
|
.to change { article.reload.preferences[:delivery_status] }.to('fail')
|
||||||
.and 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_date] }.to(an_instance_of(ActiveSupport::TimeWithZone))
|
||||||
.and change { article.reload.preferences[:delivery_status_message] }.to(error_message)
|
.and change { article.reload.preferences[:delivery_status_message] }.to(error_message)
|
||||||
end
|
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] } }) }
|
let!(:new_channel) { create(:twitter_channel, custom_options: { user: { screen_name: channel.options[:user][:screen_name] } }) }
|
||||||
|
|
||||||
it 'uses that channel' do
|
it 'uses that channel' do
|
||||||
described_class.new(article.id).perform
|
described_class.perform_now(article.id)
|
||||||
|
|
||||||
expect(WebMock)
|
expect(WebMock)
|
||||||
.to have_requested(:post, 'https://api.twitter.com/1.1/statuses/update.json')
|
.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 } } }
|
let(:factory_options) { { preferences: { delivery_retry: 3 } } }
|
||||||
|
|
||||||
it 'adds a delivery failure note (article) to the ticket' do
|
it 'adds a delivery failure note (article) to the ticket' do
|
||||||
expect { described_class.new(article.id).perform }
|
expect { described_class.perform_now(article.id) }
|
||||||
.to raise_error(error_message)
|
.to change { article.ticket.reload.articles.count }.by(1)
|
||||||
.and change { article.ticket.reload.articles.count }.by(1)
|
|
||||||
|
|
||||||
expect(Ticket::Article.last.attributes).to include(
|
expect(Ticket::Article.last.attributes).to include(
|
||||||
'content_type' => 'text/plain',
|
'content_type' => 'text/plain',
|
|
@ -1,12 +1,14 @@
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe MigrationJob::LdapSamaccountnameToUid do
|
RSpec.describe MigrateLdapSamaccountnameToUidJob, type: :job do
|
||||||
|
|
||||||
it 'performs no changes if no LDAP config present' do
|
it 'performs no changes if no LDAP config present' do
|
||||||
allow(Setting).to receive(:set)
|
allow(Setting).to receive(:set)
|
||||||
allow(Import::Ldap).to receive(:config).and_return(nil)
|
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)
|
expect(Setting).not_to have_received(:set)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -24,8 +26,12 @@ RSpec.describe MigrationJob::LdapSamaccountnameToUid do
|
||||||
|
|
||||||
allow(::Ldap).to receive(:new)
|
allow(::Ldap).to receive(:new)
|
||||||
|
|
||||||
described_class.new.perform
|
described_class.perform_now
|
||||||
|
|
||||||
expect(Setting).not_to have_received(:set)
|
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
|
end
|
||||||
|
|
||||||
it 'performs Setting change if uid attribute differ' do
|
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)
|
||||||
|
allow(Setting).to receive(:set).with('ldap_config', ldap_config_new)
|
||||||
|
|
||||||
allow(Import::Ldap).to receive(:config).and_return(ldap_config_obsolete)
|
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)
|
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(Setting).to have_received(:set).with('ldap_config', ldap_config_new)
|
||||||
|
expect(ldap_user).to have_received(:uid_attribute)
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -677,7 +677,7 @@ RSpec.describe Channel::Driver::Twitter do
|
||||||
describe '#send', :use_vcr do
|
describe '#send', :use_vcr do
|
||||||
shared_examples 'for #send' do
|
shared_examples 'for #send' do
|
||||||
# Channel#deliver takes a hash in the following format
|
# 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?
|
# Why not just accept the whole article?
|
||||||
# Presumably so all channels have a consistent interface...
|
# 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.
|
# 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
|
context '…but before the BG job has "synced" article.message_id with tweet.id)' do
|
||||||
let(:twitter_job) { Delayed::Job.find_by(handler: <<~YML) }
|
let(:twitter_job) { Delayed::Job.where("handler LIKE '%job_class: CommunicateTwitterJob%#{tweet.id}%'").first }
|
||||||
--- !ruby/object:Observer::Ticket::Article::CommunicateTwitter::BackgroundJob
|
|
||||||
article_id: #{tweet.id}
|
|
||||||
YML
|
|
||||||
|
|
||||||
around do |example|
|
around do |example|
|
||||||
# Run BG job (Why not use Scheduler.worker?
|
# Run BG job (Why not use Scheduler.worker?
|
||||||
|
|
|
@ -1,27 +1,19 @@
|
||||||
require 'rails_helper'
|
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 }
|
before { allow(Delayed::Job).to receive(:enqueue).and_call_original }
|
||||||
|
|
||||||
let(:article) { create(:ticket_article, **(try(:factory_options) || {})) }
|
let(:article) { create(:ticket_article, **(try(:factory_options) || {})) }
|
||||||
|
|
||||||
shared_examples 'for no-op' do
|
shared_examples 'for no-op' do
|
||||||
it 'is a no-op' do
|
it 'is a no-op' do
|
||||||
expect(Delayed::Job)
|
expect { article }.not_to have_enqueued_job(CommunicateTwitterJob)
|
||||||
.not_to receive(:enqueue)
|
|
||||||
.with(instance_of(Observer::Ticket::Article::CommunicateTwitter::BackgroundJob))
|
|
||||||
|
|
||||||
article
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
shared_examples 'for success' do
|
shared_examples 'for success' do
|
||||||
it 'enqueues the Twitter background job' do
|
it 'enqueues the Twitter background job' do
|
||||||
expect(Delayed::Job)
|
expect { article }.to have_enqueued_job(CommunicateTwitterJob)
|
||||||
.to receive(:enqueue)
|
|
||||||
.with(an_instance_of(Observer::Ticket::Article::CommunicateTwitter::BackgroundJob))
|
|
||||||
|
|
||||||
article
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue