From 467f3b9191f4eccb129489211ada347bfd3a31cb Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Tue, 22 Mar 2022 12:14:17 +0530 Subject: [PATCH] chore: Disable fetching new emails after mailbox error (#4176) - Disabled email fetch job if credentials for the channel isn't working - notify customers when the email channel isn't working fixes: https://github.com/chatwoot/chatwoot/issues/4174 --- .../api/v1/accounts/inboxes_controller.rb | 5 +++- app/jobs/inboxes/fetch_imap_emails_job.rb | 23 +++++++++++++++++-- app/mailboxes/mailbox_helper.rb | 2 +- .../channel_notifications_mailer.rb | 8 +++++++ app/models/channel/email.rb | 1 + app/models/concerns/reauthorizable.rb | 7 +++--- .../email_disconnect.liquid | 8 +++++++ .../facebook_disconnect.liquid | 2 +- 8 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 app/views/mailers/administrator_notifications/channel_notifications_mailer/email_disconnect.liquid diff --git a/app/controllers/api/v1/accounts/inboxes_controller.rb b/app/controllers/api/v1/accounts/inboxes_controller.rb index 2bda5c07a..bcea2d9d7 100644 --- a/app/controllers/api/v1/accounts/inboxes_controller.rb +++ b/app/controllers/api/v1/accounts/inboxes_controller.rb @@ -48,7 +48,10 @@ class Api::V1::Accounts::InboxesController < Api::V1::Accounts::BaseController # Inbox update doesn't necessarily need channel attributes return if permitted_params(channel_attributes)[:channel].blank? - validate_email_channel(channel_attributes) if @inbox.inbox_type == 'Email' + if @inbox.inbox_type == 'Email' + validate_email_channel(channel_attributes) + @inbox.channel.reauthorized! + end @inbox.channel.update!(permitted_params(channel_attributes)[:channel]) update_channel_feature_flags diff --git a/app/jobs/inboxes/fetch_imap_emails_job.rb b/app/jobs/inboxes/fetch_imap_emails_job.rb index 3c15ed005..94dd101c8 100644 --- a/app/jobs/inboxes/fetch_imap_emails_job.rb +++ b/app/jobs/inboxes/fetch_imap_emails_job.rb @@ -1,9 +1,28 @@ +require 'net/imap' + class Inboxes::FetchImapEmailsJob < ApplicationJob queue_as :low def perform(channel) - return unless channel.imap_enabled? + return unless should_fetch_email?(channel) + process_mail_for_channel(channel) + rescue Errno::ECONNREFUSED, Net::OpenTimeout, Net::IMAP::NoResponseError + channel.authorization_error! + rescue StandardError => e + channel.authorization_error! + Sentry.capture_exception(e) + end + + private + + def should_fetch_email?(channel) + channel.imap_enabled? && !channel.reauthorization_required? + end + + def process_mail_for_channel(channel) + # TODO: rather than setting this as default method for all mail objects, lets if can do new mail object + # using Mail.retriever_method.new(params) Mail.defaults do retriever_method :imap, address: channel.imap_address, port: channel.imap_port, @@ -21,6 +40,6 @@ class Inboxes::FetchImapEmailsJob < ApplicationJob end end - Channel::Email.update(channel.id, imap_inbox_synced_at: Time.now.utc) if new_mails + channel.update(imap_inbox_synced_at: Time.now.utc) if new_mails end end diff --git a/app/mailboxes/mailbox_helper.rb b/app/mailboxes/mailbox_helper.rb index 06fa8c0ee..831baa91a 100644 --- a/app/mailboxes/mailbox_helper.rb +++ b/app/mailboxes/mailbox_helper.rb @@ -5,7 +5,7 @@ module MailboxHelper @message = @conversation.messages.create( account_id: @conversation.account_id, sender: @conversation.contact, - content: mail_content, + content: mail_content&.truncate(150_000), inbox_id: @conversation.inbox_id, message_type: 'incoming', content_type: 'incoming_email', diff --git a/app/mailers/administrator_notifications/channel_notifications_mailer.rb b/app/mailers/administrator_notifications/channel_notifications_mailer.rb index 4408a9a94..e8cd450b6 100644 --- a/app/mailers/administrator_notifications/channel_notifications_mailer.rb +++ b/app/mailers/administrator_notifications/channel_notifications_mailer.rb @@ -15,6 +15,14 @@ class AdministratorNotifications::ChannelNotificationsMailer < ApplicationMailer send_mail_with_liquid(to: admin_emails, subject: subject) and return end + def email_disconnect(inbox) + return unless smtp_config_set_or_development? + + subject = 'Your email inbox has been disconnected. Please update the credentials for SMTP/IMAP' + @action_url = "#{ENV['FRONTEND_URL']}/app/accounts/#{Current.account.id}/settings/inboxes/#{inbox.id}" + send_mail_with_liquid(to: admin_emails, subject: subject) and return + end + private def admin_emails diff --git a/app/models/channel/email.rb b/app/models/channel/email.rb index 3a25c3798..c101bc8c1 100644 --- a/app/models/channel/email.rb +++ b/app/models/channel/email.rb @@ -34,6 +34,7 @@ class Channel::Email < ApplicationRecord include Channelable + include Reauthorizable self.table_name = 'channel_email' EDITABLE_ATTRS = [:email, :imap_enabled, :imap_email, :imap_password, :imap_address, :imap_port, :imap_enable_ssl, :imap_inbox_synced_at, diff --git a/app/models/concerns/reauthorizable.rb b/app/models/concerns/reauthorizable.rb index 5af92124a..dc55d9b2e 100644 --- a/app/models/concerns/reauthorizable.rb +++ b/app/models/concerns/reauthorizable.rb @@ -39,10 +39,11 @@ module Reauthorizable if (is_a? Integrations::Hook) && slack? AdministratorNotifications::ChannelNotificationsMailer.with(account: account).slack_disconnect.deliver_later + elsif is_a? Channel::FacebookPage + AdministratorNotifications::ChannelNotificationsMailer.with(account: account).facebook_disconnect(inbox).deliver_later + elsif is_a? Channel::Email + AdministratorNotifications::ChannelNotificationsMailer.with(account: account).email_disconnect(inbox).deliver_later end - return unless is_a? Channel::FacebookPage - - AdministratorNotifications::ChannelNotificationsMailer.with(account: account).facebook_disconnect(inbox).deliver_later end # call this after you successfully Reauthorized the object in UI diff --git a/app/views/mailers/administrator_notifications/channel_notifications_mailer/email_disconnect.liquid b/app/views/mailers/administrator_notifications/channel_notifications_mailer/email_disconnect.liquid new file mode 100644 index 000000000..279c34f2b --- /dev/null +++ b/app/views/mailers/administrator_notifications/channel_notifications_mailer/email_disconnect.liquid @@ -0,0 +1,8 @@ +

Hello,

+ +

Your email inbox has been disconnected due to configuration errors.

+

Please update it to continue receiving messages.

+ +

+Click here to re-connect. +

diff --git a/app/views/mailers/administrator_notifications/channel_notifications_mailer/facebook_disconnect.liquid b/app/views/mailers/administrator_notifications/channel_notifications_mailer/facebook_disconnect.liquid index c20f57da5..528c71543 100644 --- a/app/views/mailers/administrator_notifications/channel_notifications_mailer/facebook_disconnect.liquid +++ b/app/views/mailers/administrator_notifications/channel_notifications_mailer/facebook_disconnect.liquid @@ -1,7 +1,7 @@

Hello,

Your Facebook Inbox Access has expired.

-

Please reconnect Facebook Page to continue receiving messages in Chatwoot

+

Please reconnect Facebook Page to continue receiving messages.

Click here to re-connect.