4 changed files with 89 additions and 0 deletions
@ -0,0 +1,75 @@ |
|||||
|
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 |
||||
@ -0,0 +1,7 @@ |
|||||
|
require 'spec_helper' |
||||
|
|
||||
|
RSpec.describe FetchActionEmails, type: :interactor do |
||||
|
describe '.call' do |
||||
|
pending "add some examples to (or delete) #{__FILE__}" |
||||
|
end |
||||
|
end |
||||
Loading…
Reference in new issue