Aplicacion que monitorea una inbox de outlook/hotmail a traves de IMAP y cuando detecta un email con cierto subject y viniendo de una coleccion de direcciones de email conocidas, ejecuta una accion, por ejemplo: encender el server
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

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