Skip to content

Instantly share code, notes, and snippets.

@zigzag
Created December 3, 2009 12:37
Show Gist options
  • Save zigzag/248127 to your computer and use it in GitHub Desktop.
Save zigzag/248127 to your computer and use it in GitHub Desktop.
A MailFetcher fecthing mails via IMAP and parsing it with Tmail. A enhanced module is included to fitler the mail by some condition and also dump the mail content and attachment to the file system.
require 'net/imap'
require 'tmail_mail_extension'
class MailFetcher
cattr_accessor :email_download_path
self.email_download_path = File.join(RAILS_ROOT, 'public','emails_download')
def initialize(setting)
@setting = setting
end
def fetch
imap = Net::IMAP.new(@setting[:IMAP_HOST], @setting[:IMAP_PORT], true)
imap.login(@setting[:LOGIN_EMAIL_USER_NAME], @setting[:LOGIN_EMAIL_PASSWORD])
imap.select('inbox')
imap.search(["UNSEEN"]).each do |id|
source = imap.fetch(id, ['RFC822']).first.attr['RFC822']
email = TMail::Mail.parse(source).extend ParsedEmail
if email.should_fetch?(@setting[:EMAIL_FILTER_DATE_FROM], @setting[:EMAIL_FILTER_DATE_TO], @setting[:EMAIL_SUBJECT_KEY_WORDS])
email.save_content(MailFetcher.email_download_path)
EmailHistory.record_incoming email
imap.store(id, "+FLAGS", [:Seen])
end
end
imap.logout
end
end
# An exhanced Email module to TMail Parse Result.
module ParsedEmail
attr_reader :content_path
def should_fetch?(form_date,to_date,key_words)
return false if date < Date.parse(form_date)
return false if date > Date.parse(to_date) + 1
key_words.split(',').any? { |key_word| subject.include?(key_word) }
end
def should_reply_to
email_pattern = /([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA -Z]\.)+[a-zA-Z]{2,9})/
should_reply_to = reply_to
should_reply_to = from if reply_to.blank?
(body_plain||body_html||'').gsub(email_pattern){ |email_in_body| should_reply_to = email_in_body}
should_reply_to
end
def save_content(base_path)
@content_path = File.join(base_path, should_reply_to, date.to_s(:db))
FileUtils.makedirs(@content_path)
File.open(File.join(@content_path,"email_text.html"),'w+') { |f| f << body_html } unless body_html.blank?
File.open(File.join(@content_path,"email_text.txt"),'w+') { |f| f << body_plain } unless body_plain.blank?
unless attachments.blank?
File.open(File.join(@content_path,attachments.first.original_filename),'w+') do |f|
f << attachments.first.gets(nil)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment