You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.4 KiB
75 lines
2.4 KiB
require "net/imap"
|
|
class FetchEmails
|
|
include Interactor
|
|
|
|
OUTLOOK_IMAP_HOST = 'outlook.office365.com'
|
|
OUTLOOK_IMAP_PORT = 993
|
|
SENT_FOLDER_NAME = 'Sent Items'
|
|
INBOX_FOLDER_NAME = 'INBOX'
|
|
DRAFTS_FOLDER_NAME = 'Drafts'
|
|
|
|
def call
|
|
establish_imap_connection(
|
|
host: OUTLOOK_IMAP_HOST,
|
|
port: OUTLOOK_IMAP_PORT,
|
|
username: context.email,
|
|
password: context.password
|
|
) do |imap|
|
|
context.messages=get_messages(
|
|
imap: imap,
|
|
folder: INBOX_FOLDER_NAME,
|
|
after_datetime: context.query_from
|
|
)
|
|
end
|
|
end
|
|
|
|
def establish_imap_connection(host:, port:, username:, password:)
|
|
connection = Net::IMAP.new(OUTLOOK_IMAP_HOST, OUTLOOK_IMAP_PORT, ssl: true)
|
|
connection.login(username, password)
|
|
return connection unless block_given?
|
|
begin
|
|
yield connection
|
|
ensure
|
|
connection&.disconnect
|
|
end
|
|
end
|
|
|
|
# imap_query: is an array following IMAP query format such as ["SINCE", "11-Jan-2021"]
|
|
def get_messages(imap:, folder: INBOX_FOLDER_NAME, after_datetime: nil, imap_query: nil)
|
|
raise ::NotImplementedError, 'Still to be implemented fetching of all messages' unless imap_query || after_datetime
|
|
|
|
query = if imap_query
|
|
imap_query
|
|
elsif after_datetime
|
|
# The IMAP SINCE filter does not accept a time component to be able to skip
|
|
# the fetching will iterate over the emails but will not include the ones that
|
|
# have a date on the envelope that is in the past respect to after_datetime
|
|
# therefore ignoring these.
|
|
['SINCE', after_datetime.strftime('%d-%b-%Y')]
|
|
end
|
|
|
|
messages = []
|
|
|
|
imap.examine(folder)
|
|
imap.search(query).each do |message_id|
|
|
res = imap.fetch(message_id, %w(RFC822 ENVELOPE UID))[0]
|
|
envelope = res.attr['ENVELOPE']
|
|
next if after_datetime && envelope.date.to_time.to_i < after_datetime.to_i
|
|
|
|
rfc = res.attr['RFC822']
|
|
uid = res.attr['UID']
|
|
mail = Mail::Message.new(rfc)
|
|
message = OpenStruct.new(
|
|
date: envelope.date.to_time.utc.iso8601,
|
|
thread: mail.references,
|
|
from: "#{envelope.from&.dig(0)&.name} <#{envelope.from&.dig(0)&.mailbox}@#{envelope.from&.dig(0)&.host}>",
|
|
subject: envelope.subject,
|
|
mail_object: mail,
|
|
uid: uid,
|
|
)
|
|
messages << message
|
|
end
|
|
|
|
messages
|
|
end
|
|
end
|
|
|