From 2ce02b7397ad8779fd70342e906b1d82eb6701ec Mon Sep 17 00:00:00 2001 From: John Manuel Derecho Date: Fri, 24 May 2024 03:36:17 +0800 Subject: [PATCH 1/2] rubocop fix --- .rubocop.yml | 1 + .../conversations/smart_actions_controller.rb | 4 +-- .../conversations/activity_message_job.rb | 10 +++---- app/mailers/conversation_reply_mailer.rb | 4 +-- .../conversation_reply_mailer_helper.rb | 15 ++++++---- app/models/conversation.rb | 2 ++ .../hook_execution_service.rb | 13 +++++---- .../search_by_email.json.jbuilder | 4 ++- ...29092744_add_inbox_notification_enabled.rb | 2 +- ..._add_audio_notification_enable_to_inbox.rb | 2 +- ...6135628_transfer_csat_settings_to_inbox.rb | 2 +- ...emove_csat_template_enabled_for_account.rb | 2 +- db/migrate/20240119112918_fix_old_dt_url.rb | 2 ++ .../20240122104127_add_webhook_enabled.rb | 2 +- .../20240122135344_clear_chatwoot_labels.rb | 4 +++ .../20240128123047_inbox_required_label.rb | 2 +- ...0240131060216_add_auto_reply_on_message.rb | 2 +- ...308131440_add_archived_on_conversations.rb | 2 +- .../20240403124715_add_custom_message.rb | 2 +- db/migrate/20240517140740_log_conversation.rb | 14 ++++----- lib/digitaltolk/add_conversation_service.rb | 2 +- .../auto_assign_conversation_service.rb | 2 ++ lib/digitaltolk/change_contact_service.rb | 29 ++++++++++--------- .../find_conversation_by_email_service.rb | 2 +- 24 files changed, 71 insertions(+), 55 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 1cdfbc713ab3b..3dcebb172d1c1 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -62,6 +62,7 @@ Metrics/ModuleLength: Exclude: - lib/seeders/message_seeder.rb - spec/support/slack_stubs.rb + - app/models/concerns/activity_message_handler.rb Rails/ApplicationController: Exclude: - 'app/controllers/api/v1/widget/messages_controller.rb' diff --git a/app/controllers/api/v1/accounts/conversations/smart_actions_controller.rb b/app/controllers/api/v1/accounts/conversations/smart_actions_controller.rb index d472cf62996a9..c5917a6af55c9 100644 --- a/app/controllers/api/v1/accounts/conversations/smart_actions_controller.rb +++ b/app/controllers/api/v1/accounts/conversations/smart_actions_controller.rb @@ -14,13 +14,13 @@ def create end def event_data - # todo move to service action + # TODO: move to service action case params[:event] when 'ask_copilot' event = @conversation.smart_actions.ask_copilot.last render json: event.present? ? event.event_data : {} else - render json: {success: false} + render json: { success: false } end end end diff --git a/app/jobs/conversations/activity_message_job.rb b/app/jobs/conversations/activity_message_job.rb index 6e8cf73d9881a..8950657ecf833 100644 --- a/app/jobs/conversations/activity_message_job.rb +++ b/app/jobs/conversations/activity_message_job.rb @@ -2,11 +2,9 @@ class Conversations::ActivityMessageJob < ApplicationJob queue_as :high def perform(conversation, message_params) - begin - conversation.messages.create!(message_params) - rescue StandardError => e - Rails.logger.error e.message - Rails.logger.error e.backtrace.first - end + conversation.messages.create!(message_params) + rescue StandardError => e + Rails.logger.error e.message + Rails.logger.error e.backtrace.first end end diff --git a/app/mailers/conversation_reply_mailer.rb b/app/mailers/conversation_reply_mailer.rb index 0fff039d8f93f..4b10d04915b01 100644 --- a/app/mailers/conversation_reply_mailer.rb +++ b/app/mailers/conversation_reply_mailer.rb @@ -159,9 +159,7 @@ def inbox_from_email_address end def custom_message_id - last_message = @message || @messages&.reject(&:customized)&.last - - return if last_message.blank? + return if (last_message = @message || @messages&.reject(&:customized)&.last).blank? return last_message.source_id if last_message&.source_id.present? "" diff --git a/app/mailers/conversation_reply_mailer_helper.rb b/app/mailers/conversation_reply_mailer_helper.rb index b9520223ce4ee..cf1137af40aa0 100644 --- a/app/mailers/conversation_reply_mailer_helper.rb +++ b/app/mailers/conversation_reply_mailer_helper.rb @@ -15,20 +15,23 @@ def prepare_mail(cc_bcc_enabled) end ms_smtp_settings set_delivery_method + set_attachments Rails.logger.info("Email sent from #{email_from} to #{to_emails} with subject #{mail_subject}") - if @attachments.present? - @attachments.each do |attachment| - attachments[attachment.file.filename.to_s] = attachment.file.download - end - end - mail(@options) end private + def set_attachments + return if @attachments.blank? + + @attachments.each do |attachment| + attachments[attachment.file.filename.to_s] = attachment.file.download + end + end + def ms_smtp_settings return unless @inbox.email? && @channel.imap_enabled && @inbox.channel.provider == 'microsoft' diff --git a/app/models/conversation.rb b/app/models/conversation.rb index 7c2271c01ee80..6e38cf52f4578 100644 --- a/app/models/conversation.rb +++ b/app/models/conversation.rb @@ -245,7 +245,9 @@ def auto_assign_to_latest_agent return if assignee_id.present? return if latest_agent.blank? + # rubocop:disable Rails/SkipsModelValidations update_column(:assignee_id, latest_agent.id) + # rubocop:enable Rails/SkipsModelValidations end def latest_agent diff --git a/app/services/message_templates/hook_execution_service.rb b/app/services/message_templates/hook_execution_service.rb index d2fb962e50238..b66d4c64c36d3 100644 --- a/app/services/message_templates/hook_execution_service.rb +++ b/app/services/message_templates/hook_execution_service.rb @@ -54,6 +54,7 @@ def contact_has_email? contact.email end + # rubocop:disable Metrics/CyclomaticComplexity def csat_enabled_conversation? return false unless conversation.resolved? || ((message.outgoing? || message.input_csat?) && inbox.send_csat_on_all_reply?) @@ -64,17 +65,13 @@ def csat_enabled_conversation? true end + # rubocop:enable Metrics/CyclomaticComplexity def should_send_csat_survey? return unless csat_enabled_conversation? if inbox.csat_template_enabled? - last_csat_reached = conversation.messages.csat.count >= csat_template.questions_count - if inbox.email? - return if last_csat_reached - elsif last_csat_reached || conversation.messages.unanswered_csat.exists? - return - end + return if last_csat_reached? || (!inbox.email? && conversation.messages.unanswered_csat.exists?) elsif conversation.messages.csat.present? return # only send CSAT once in a conversation @@ -82,5 +79,9 @@ def should_send_csat_survey? true end + + def last_csat_reached? + conversation.messages.csat.count >= csat_template.questions_count + end end MessageTemplates::HookExecutionService.prepend_mod_with('MessageTemplates::HookExecutionService') diff --git a/app/views/api/v1/accounts/conversations/search_by_email.json.jbuilder b/app/views/api/v1/accounts/conversations/search_by_email.json.jbuilder index 2af394b743617..3e73d8403e6db 100644 --- a/app/views/api/v1/accounts/conversations/search_by_email.json.jbuilder +++ b/app/views/api/v1/accounts/conversations/search_by_email.json.jbuilder @@ -1,3 +1,4 @@ +# rubocop:disable Metrics/BlockLength json.array! @conversations do |conversation| json.meta do json.sender do @@ -47,5 +48,6 @@ json.array! @conversations do |conversation| json.last_non_activity_message conversation.messages.where(account_id: conversation.account_id).non_activity_messages.first.try(:push_event_data) json.last_activity_at conversation.last_activity_at.to_i json.priority conversation.priority - json.waiting_since conversation.waiting_since.to_i.to_i + json.waiting_since conversation.waiting_since.to_i end +# rubocop:enable Metrics/BlockLength diff --git a/db/migrate/20231229092744_add_inbox_notification_enabled.rb b/db/migrate/20231229092744_add_inbox_notification_enabled.rb index 62e17c4f979ce..ff8db8c46cb02 100644 --- a/db/migrate/20231229092744_add_inbox_notification_enabled.rb +++ b/db/migrate/20231229092744_add_inbox_notification_enabled.rb @@ -1,5 +1,5 @@ class AddInboxNotificationEnabled < ActiveRecord::Migration[7.0] def change - add_column :inboxes, :push_notification_enabled, :boolean, default: true + add_column :inboxes, :push_notification_enabled, :boolean, default: true, null: false end end diff --git a/db/migrate/20240105005101_add_audio_notification_enable_to_inbox.rb b/db/migrate/20240105005101_add_audio_notification_enable_to_inbox.rb index 992536cea415f..dc98fbc52a072 100644 --- a/db/migrate/20240105005101_add_audio_notification_enable_to_inbox.rb +++ b/db/migrate/20240105005101_add_audio_notification_enable_to_inbox.rb @@ -1,5 +1,5 @@ class AddAudioNotificationEnableToInbox < ActiveRecord::Migration[7.0] def change - add_column :inboxes, :audio_notification_enabled, :boolean, default: true + add_column :inboxes, :audio_notification_enabled, :boolean, default: true, null: false end end diff --git a/db/migrate/20240116135628_transfer_csat_settings_to_inbox.rb b/db/migrate/20240116135628_transfer_csat_settings_to_inbox.rb index 4285498d2f30f..13c65ce6f2717 100644 --- a/db/migrate/20240116135628_transfer_csat_settings_to_inbox.rb +++ b/db/migrate/20240116135628_transfer_csat_settings_to_inbox.rb @@ -1,6 +1,6 @@ class TransferCsatSettingsToInbox < ActiveRecord::Migration[7.0] def change add_column :inboxes, :csat_trigger, :string - remove_column :accounts, :csat_trigger + remove_column :accounts, :csat_trigger, :string end end diff --git a/db/migrate/20240117130808_remove_csat_template_enabled_for_account.rb b/db/migrate/20240117130808_remove_csat_template_enabled_for_account.rb index f44859190ed9f..db5ef09e7e286 100644 --- a/db/migrate/20240117130808_remove_csat_template_enabled_for_account.rb +++ b/db/migrate/20240117130808_remove_csat_template_enabled_for_account.rb @@ -1,5 +1,5 @@ class RemoveCsatTemplateEnabledForAccount < ActiveRecord::Migration[7.0] def change - remove_column :accounts, :csat_template_enabled + remove_column :accounts, :csat_template_enabled, :boolean end end diff --git a/db/migrate/20240119112918_fix_old_dt_url.rb b/db/migrate/20240119112918_fix_old_dt_url.rb index f18bfe7e3c292..7d049b57da9b4 100644 --- a/db/migrate/20240119112918_fix_old_dt_url.rb +++ b/db/migrate/20240119112918_fix_old_dt_url.rb @@ -8,7 +8,9 @@ def change new_content = new_content.gsub(old_url, new_url) Rails.logger.debug new_content + # rubocop:disable Rails/SkipsModelValidations message.update_column(:content, new_content) + # rubocop:enable Rails/SkipsModelValidations end end end diff --git a/db/migrate/20240122104127_add_webhook_enabled.rb b/db/migrate/20240122104127_add_webhook_enabled.rb index e2d58d2925a6f..4fbb10bc75707 100644 --- a/db/migrate/20240122104127_add_webhook_enabled.rb +++ b/db/migrate/20240122104127_add_webhook_enabled.rb @@ -1,5 +1,5 @@ class AddWebhookEnabled < ActiveRecord::Migration[7.0] def change - add_column :webhooks, :enabled, :boolean, default: true + add_column :webhooks, :enabled, :boolean, default: true, null: false end end diff --git a/db/migrate/20240122135344_clear_chatwoot_labels.rb b/db/migrate/20240122135344_clear_chatwoot_labels.rb index 08414b304bf73..d81ec78b79847 100644 --- a/db/migrate/20240122135344_clear_chatwoot_labels.rb +++ b/db/migrate/20240122135344_clear_chatwoot_labels.rb @@ -1,4 +1,5 @@ class ClearChatwootLabels < ActiveRecord::Migration[7.0] + # rubocop:disable Metrics/MethodLength def change Label.destroy_all @@ -64,6 +65,9 @@ def change objects << { account_id: 1, title: label, show_on_sidebar: true, description: label, color: Faker::Color.hex_color } end + # rubocop:disable Rails/SkipsModelValidations Label.insert_all(objects) + # rubocop:enable Rails/SkipsModelValidations end + # rubocop:enable Metrics/MethodLength end diff --git a/db/migrate/20240128123047_inbox_required_label.rb b/db/migrate/20240128123047_inbox_required_label.rb index 2c31a6f985672..4754a6adf63d7 100644 --- a/db/migrate/20240128123047_inbox_required_label.rb +++ b/db/migrate/20240128123047_inbox_required_label.rb @@ -1,5 +1,5 @@ class InboxRequiredLabel < ActiveRecord::Migration[7.0] def change - add_column :inboxes, :label_required, :boolean, default: false + add_column :inboxes, :label_required, :boolean, default: false, null: false end end diff --git a/db/migrate/20240131060216_add_auto_reply_on_message.rb b/db/migrate/20240131060216_add_auto_reply_on_message.rb index 6138423158e59..5c701b712383e 100644 --- a/db/migrate/20240131060216_add_auto_reply_on_message.rb +++ b/db/migrate/20240131060216_add_auto_reply_on_message.rb @@ -1,5 +1,5 @@ class AddAutoReplyOnMessage < ActiveRecord::Migration[7.0] def change - add_column :messages, :auto_reply, :boolean, default: false + add_column :messages, :auto_reply, :boolean, default: false, null: false end end diff --git a/db/migrate/20240308131440_add_archived_on_conversations.rb b/db/migrate/20240308131440_add_archived_on_conversations.rb index b7acf00370385..cf865e8dce63b 100644 --- a/db/migrate/20240308131440_add_archived_on_conversations.rb +++ b/db/migrate/20240308131440_add_archived_on_conversations.rb @@ -1,5 +1,5 @@ class AddArchivedOnConversations < ActiveRecord::Migration[7.0] def change - add_column :conversations, :closed, :boolean, default: false + add_column :conversations, :closed, :boolean, default: false, null: false end end diff --git a/db/migrate/20240403124715_add_custom_message.rb b/db/migrate/20240403124715_add_custom_message.rb index 140fe5742e2a4..65b6857451b32 100644 --- a/db/migrate/20240403124715_add_custom_message.rb +++ b/db/migrate/20240403124715_add_custom_message.rb @@ -1,5 +1,5 @@ class AddCustomMessage < ActiveRecord::Migration[7.0] def change - add_column :messages, :customized, :boolean, default: false + add_column :messages, :customized, :boolean, default: false, null: false end end diff --git a/db/migrate/20240517140740_log_conversation.rb b/db/migrate/20240517140740_log_conversation.rb index e43476d54820e..14958cf265d1e 100644 --- a/db/migrate/20240517140740_log_conversation.rb +++ b/db/migrate/20240517140740_log_conversation.rb @@ -1,13 +1,13 @@ class LogConversation < ActiveRecord::Migration[7.0] def change - conversation = Conversation.find_by(display_id: 33053) + conversation = Conversation.find_by(display_id: 33_053) - if conversation.present? - puts 'logging conversation' - puts conversation.attributes - conversation.messages.each do |msg| - puts msg.attributes - end + return if conversation.blank? + + Rails.logger.warn 'logging conversation' + Rails.logger.warn conversation.attributes + conversation.messages.each do |msg| + Rails.logger.warn msg.attributes end end end diff --git a/lib/digitaltolk/add_conversation_service.rb b/lib/digitaltolk/add_conversation_service.rb index dcec457087f5f..e8e56c71e200e 100644 --- a/lib/digitaltolk/add_conversation_service.rb +++ b/lib/digitaltolk/add_conversation_service.rb @@ -19,7 +19,7 @@ def inbox end def find_or_create_contact - @contact = inbox.contacts.find_by(email: email_address) + @contact = inbox.contacts.from_email(email_address) if @contact.present? @contact_inbox = ContactInbox.find_by(inbox: @inbox, contact: @contact) diff --git a/lib/digitaltolk/auto_assign_conversation_service.rb b/lib/digitaltolk/auto_assign_conversation_service.rb index 990a02a798d16..008f4334571a7 100644 --- a/lib/digitaltolk/auto_assign_conversation_service.rb +++ b/lib/digitaltolk/auto_assign_conversation_service.rb @@ -18,7 +18,9 @@ def auto_assign! unassigned_conversations.limit(20).each(&:auto_assign_to_latest_agent) unassigned_csats.limit(20).each do |csat| + # rubocop:disable Rails/SkipsModelValidations csat.update_column(:assigned_agent_id, csat.conversation.assignee_id) + # rubocop:enable Rails/SkipsModelValidations end end diff --git a/lib/digitaltolk/change_contact_service.rb b/lib/digitaltolk/change_contact_service.rb index f6e41315c8624..8240edaf55878 100644 --- a/lib/digitaltolk/change_contact_service.rb +++ b/lib/digitaltolk/change_contact_service.rb @@ -28,22 +28,25 @@ def change_conversation_contact @conversation.update(contact: @contact, contact_inbox: @contact_inbox) end + def create_contact_inbox_with_contact_attrs + ::ContactInboxWithContactBuilder.new( + source_id: @email, + inbox: @inbox, + contact_attributes: { + name: identify_contact_name, + email: @email, + additional_attributes: { + source_id: "email:#{source_id}" + } + } + ).perform + end + def find_or_create_contact - @contact = @account.contacts.find_by(email: @email) + @contact = @account.contacts.from_email(@email) if @contact.blank? - @contact_inbox = ::ContactInboxWithContactBuilder.new( - source_id: @email, - inbox: @inbox, - contact_attributes: { - name: identify_contact_name, - email: @email, - additional_attributes: { - source_id: "email:#{source_id}" - } - } - ).perform - + @contact_inbox = create_contact_inbox_with_contact_attrs @contact = @contact_inbox.contact else @contact_inbox = @inbox.contact_inboxes.find_by(contact: @contact) diff --git a/lib/digitaltolk/find_conversation_by_email_service.rb b/lib/digitaltolk/find_conversation_by_email_service.rb index 2d308e48281a9..3c65d3519908e 100644 --- a/lib/digitaltolk/find_conversation_by_email_service.rb +++ b/lib/digitaltolk/find_conversation_by_email_service.rb @@ -19,7 +19,7 @@ def fetch_conversations end def find_contact - @contact = Contact.find_by(email: email) + @contact = Contact.from_email(email) end def email From c2b2b278de21e90e6b429e731c641dbbde4f0ed2 Mon Sep 17 00:00:00 2001 From: John Manuel Derecho Date: Fri, 31 May 2024 01:26:15 +0800 Subject: [PATCH 2/2] fixes --- .rubocop.yml | 1 + app/helpers/custom_report_helper.rb | 33 +++++++++++++++ app/helpers/report_helper.rb | 40 +++---------------- .../migration/clear_conversation_draft_job.rb | 1 - app/mailboxes/mailbox_helper.rb | 2 +- app/mailers/conversation_reply_mailer.rb | 9 +++-- 6 files changed, 47 insertions(+), 39 deletions(-) create mode 100644 app/helpers/custom_report_helper.rb diff --git a/.rubocop.yml b/.rubocop.yml index 3dcebb172d1c1..f060e769ab136 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -63,6 +63,7 @@ Metrics/ModuleLength: - lib/seeders/message_seeder.rb - spec/support/slack_stubs.rb - app/models/concerns/activity_message_handler.rb + - app/mailboxes/mailbox_helper.rb Rails/ApplicationController: Exclude: - 'app/controllers/api/v1/widget/messages_controller.rb' diff --git a/app/helpers/custom_report_helper.rb b/app/helpers/custom_report_helper.rb new file mode 100644 index 0000000000000..2bdc73579117e --- /dev/null +++ b/app/helpers/custom_report_helper.rb @@ -0,0 +1,33 @@ +module CustomReportHelper + private + + def custom_filter(collection) + collection.filter_by_label(selected_label) + .filter_by_team(selected_team) + .filter_by_inbox(selected_inbox) + .filter_by_rating(selected_rating) + end + + def get_filter(key) + filter = params.dig(:custom_filter, key) + return [] if filter.blank? + + filter.to_unsafe_h.values + end + + def selected_label + get_filter(:selected_label) + end + + def selected_team + get_filter(:selected_team) + end + + def selected_inbox + get_filter(:selected_inbox) + end + + def selected_rating + get_filter(:selected_rating) + end +end diff --git a/app/helpers/report_helper.rb b/app/helpers/report_helper.rb index c24fa929a0e53..3c88b34353ef4 100644 --- a/app/helpers/report_helper.rb +++ b/app/helpers/report_helper.rb @@ -1,4 +1,6 @@ module ReportHelper + include CustomReportHelper + private def scope @@ -16,36 +18,6 @@ def scope end end - def custom_filter(collection) - collection.filter_by_label(selected_label) - .filter_by_team(selected_team) - .filter_by_inbox(selected_inbox) - .filter_by_rating(selected_rating) - end - - def get_filter(key) - filter = params.dig(:custom_filter, key) - return [] if filter.blank? - - filter.to_unsafe_h.values - end - - def selected_label - get_filter(:selected_label) - end - - def selected_team - get_filter(:selected_team) - end - - def selected_inbox - get_filter(:selected_inbox) - end - - def selected_rating - get_filter(:selected_rating) - end - def conversations_count (get_grouped_values conversations).count end @@ -83,13 +55,13 @@ def outgoing_messages end def resolutions - custom_filter(scope.reporting_events).joins(:conversation).select(:conversation_id).where(account_id: account.id, name: :conversation_resolved, - conversations: { status: :resolved }, created_at: range).distinct + custom_filter(scope.reporting_events).joins(:conversation).select(:conversation_id).where(conversations: { status: :resolved }) + .where(account_id: account.id, name: :conversation_resolved, created_at: range).distinct end def bot_resolutions - custom_filter(scope.reporting_events).joins(:conversation).select(:conversation_id).where(account_id: account.id, name: :conversation_bot_resolved, - conversations: { status: :resolved }, created_at: range).distinct + custom_filter(scope.reporting_events).joins(:conversation).select(:conversation_id).where(conversations: { status: :resolved }) + .where(account_id: account.id, name: :conversation_bot_resolved, created_at: range).distinct end def bot_handoffs diff --git a/app/jobs/migration/clear_conversation_draft_job.rb b/app/jobs/migration/clear_conversation_draft_job.rb index 230889b51cda1..811eed96fc8c5 100644 --- a/app/jobs/migration/clear_conversation_draft_job.rb +++ b/app/jobs/migration/clear_conversation_draft_job.rb @@ -8,7 +8,6 @@ def perform counter = 0 if account.present? account.conversations.each do |convo| - key = format(Redis::Alfred::CONVERSATION_DRAFT_MESSAGE, conversation_id: convo.id, account_id: account.id) convo.clear_draft_message counter += 1 Rails.logger.debug '.' diff --git a/app/mailboxes/mailbox_helper.rb b/app/mailboxes/mailbox_helper.rb index 60809c93e2fcd..8fd743b5a6371 100644 --- a/app/mailboxes/mailbox_helper.rb +++ b/app/mailboxes/mailbox_helper.rb @@ -2,7 +2,7 @@ module MailboxHelper private def create_message - Rails.logger.info "[MailboxHelper] Creating message #{processed_mail.message_id}" + # Rails.logger.info "[MailboxHelper] Creating message #{processed_mail.message_id}" return if @conversation.messages.find_by(source_id: processed_mail.message_id).present? @message = @conversation.messages.create!( diff --git a/app/mailers/conversation_reply_mailer.rb b/app/mailers/conversation_reply_mailer.rb index 4b10d04915b01..702cda17af758 100644 --- a/app/mailers/conversation_reply_mailer.rb +++ b/app/mailers/conversation_reply_mailer.rb @@ -159,10 +159,13 @@ def inbox_from_email_address end def custom_message_id - return if (last_message = @message || @messages&.reject(&:customized)&.last).blank? - return last_message.source_id if last_message&.source_id.present? + return if last_message.blank? - "" + last_message.source_id.presence || "" + end + + def last_message + @message || @messages&.reject(&:customized)&.last end def in_reply_to_email