Browse Source

Included the interactor gem and the initial email email fetching interactor

master
rodley82 4 years ago
parent
commit
d8492f03f4
  1. 2
      Gemfile
  2. 5
      Gemfile.lock
  3. 75
      app/interactors/fetch_emails.rb
  4. 7
      spec/interactors/fetch_action_emails_spec.rb

2
Gemfile

@ -48,6 +48,8 @@ gem "bootsnap", require: false
# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
# gem "image_processing", "~> 1.2"
gem "interactor-rails", "~> 2.0"
group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
gem "debug", platforms: %i[ mri mingw x64_mingw ]

5
Gemfile.lock

@ -96,6 +96,10 @@ GEM
importmap-rails (1.0.3)
actionpack (>= 6.0.0)
railties (>= 6.0.0)
interactor (3.1.2)
interactor-rails (2.2.1)
interactor (~> 3.0)
rails (>= 4.2)
io-console (0.5.11)
io-wait (0.2.1)
irb (1.4.1)
@ -217,6 +221,7 @@ DEPENDENCIES
capybara
debug
importmap-rails
interactor-rails (~> 2.0)
jbuilder
puma (~> 5.0)
rails (~> 7.0.2, >= 7.0.2.2)

75
app/interactors/fetch_emails.rb

@ -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

7
spec/interactors/fetch_action_emails_spec.rb

@ -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…
Cancel
Save