Feat: Support for Microsoft Oauth in Email Channel (#6227)
- Adds the backend APIs required for Microsoft Email Channels Co-authored-by: Pranav Raj S <pranav@chatwoot.com> Co-authored-by: Sojan <sojan@pepalo.com>
This commit is contained in:
@@ -6,9 +6,7 @@ class Inboxes::FetchImapEmailsJob < ApplicationJob
|
||||
def perform(channel)
|
||||
return unless should_fetch_email?(channel)
|
||||
|
||||
fetch_mail_for_channel(channel)
|
||||
# clearing old failures like timeouts since the mail is now successfully processed
|
||||
channel.reauthorized!
|
||||
process_email_for_channel(channel)
|
||||
rescue *ExceptionList::IMAP_EXCEPTIONS
|
||||
channel.authorization_error!
|
||||
rescue EOFError => e
|
||||
@@ -23,6 +21,17 @@ class Inboxes::FetchImapEmailsJob < ApplicationJob
|
||||
channel.imap_enabled? && !channel.reauthorization_required?
|
||||
end
|
||||
|
||||
def process_email_for_channel(channel)
|
||||
# fetching email for microsoft provider
|
||||
if channel.microsoft?
|
||||
fetch_mail_for_ms_provider(channel)
|
||||
else
|
||||
fetch_mail_for_channel(channel)
|
||||
end
|
||||
# clearing old failures like timeouts since the mail is now successfully processed
|
||||
channel.reauthorized!
|
||||
end
|
||||
|
||||
def fetch_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)
|
||||
@@ -41,9 +50,51 @@ class Inboxes::FetchImapEmailsJob < ApplicationJob
|
||||
end
|
||||
end
|
||||
|
||||
def fetch_mail_for_ms_provider(channel)
|
||||
return if channel.provider_config['access_token'].blank?
|
||||
|
||||
access_token = valid_access_token channel
|
||||
|
||||
return unless access_token
|
||||
|
||||
imap = imap_authenticate(channel, access_token)
|
||||
|
||||
process_mails(imap, channel)
|
||||
end
|
||||
|
||||
def process_mails(imap, channel)
|
||||
imap.search(['BEFORE', tomorrow, 'SINCE', yesterday]).each do |message_id|
|
||||
inbound_mail = Mail.read_from_string imap.fetch(message_id, 'RFC822')[0].attr['RFC822']
|
||||
|
||||
next if channel.inbox.messages.find_by(source_id: inbound_mail.message_id).present?
|
||||
|
||||
process_mail(inbound_mail, channel)
|
||||
end
|
||||
end
|
||||
|
||||
def imap_authenticate(channel, access_token)
|
||||
imap = Net::IMAP.new(channel.imap_address, channel.imap_port, true)
|
||||
imap.authenticate('XOAUTH2', channel.imap_login, access_token)
|
||||
imap.select('INBOX')
|
||||
imap
|
||||
end
|
||||
|
||||
def yesterday
|
||||
(Time.zone.today - 1).strftime('%d-%b-%Y')
|
||||
end
|
||||
|
||||
def tomorrow
|
||||
(Time.zone.today + 1).strftime('%d-%b-%Y')
|
||||
end
|
||||
|
||||
def process_mail(inbound_mail, channel)
|
||||
Imap::ImapMailbox.new.process(inbound_mail, channel)
|
||||
rescue StandardError => e
|
||||
ChatwootExceptionTracker.new(e, account: channel.account).capture_exception
|
||||
end
|
||||
|
||||
# Making sure the access token is valid for microsoft provider
|
||||
def valid_access_token(channel)
|
||||
Microsoft::RefreshOauthTokenService.new(channel: channel).access_token
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user