diff --git a/README.md b/README.md index 16114750..400cf9b9 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ that responds to: Each of those has some sensible defaults. -`.from`, `.raw_body`, `.raw_headers`, and `.subject` will contain the obvious +`.raw_body`, `.raw_headers`, and `.subject` will contain the obvious values found in the email, the raw values from those fields. `.body` will contain the full contents of the email body **unless** there is a @@ -103,6 +103,10 @@ information of each recipient: * `email`: The email address of the recipient. * `full`: The whole recipient field. E.g, `Some User ` + * `name`: The name of the recipient. E.g, `Some User` + +`.from` behaves similar to `.to` but returns a hash instead of an array +of hashes. `.attachments` will contain an array of attachments as multipart/form-data files which can be passed off to attachment libraries like Carrierwave or Paperclip. @@ -123,7 +127,8 @@ Griddler.configure do |config| # :raw => 'AppName ' # :email => 's13.6b2d13dc6a1d33db7644@mail.myapp.com' # :token => 's13.6b2d13dc6a1d33db7644' - # :hash => { raw: '', email: '', token: '', host: '' } + # :hash => { full: '', email: '', token: '', host: '', name: '' } + config.from = :hash # :token, :full, :email (default) config.reply_delimiter = '-- REPLY ABOVE THIS LINE --' config.email_service = :sendgrid end @@ -133,6 +138,8 @@ end * `config.reply_delimiter` is the string searched for that will split your body. * `config.to` is the format of the returned value for the `:to` key in the email object. `:hash` will return all options within a -- (surprise!) -- hash. +* `config.from` is the format of the returned value for the `:from` key in +the email object. It behaves identical to `config.to`. * `config.email_service` tells Griddler which email service you are using. The supported email service options are `:sendgrid` (the default), `:cloudmailin` (expects multipart format), `:postmark` and `:mandrill`. @@ -147,7 +154,7 @@ following sample factory. ```ruby factory :email, class: OpenStruct do # Assumes Griddler.configure.to is :hash (default) - to [{ raw: 'to_user@email.com', email: 'to_user@email.com', token: 'to_user', host: 'email.com' }] + to [{ full: 'to_user@email.com', email: 'to_user@email.com', token: 'to_user', host: 'email.com', name: nil }] from 'user@email.com' subject 'email subject' body 'Hello!' diff --git a/lib/griddler/adapters/postmark_adapter.rb b/lib/griddler/adapters/postmark_adapter.rb index 898bd304..8611e04a 100644 --- a/lib/griddler/adapters/postmark_adapter.rb +++ b/lib/griddler/adapters/postmark_adapter.rb @@ -13,7 +13,7 @@ def self.normalize_params(params) def normalize_params { to: extract_recipients, - from: params[:FromFull][:Email], + from: full_email(params[:FromFull]), subject: params[:Subject], text: params[:TextBody], html: params[:HtmlBody], diff --git a/lib/griddler/configuration.rb b/lib/griddler/configuration.rb index 1f98bc9b..e33c4afe 100644 --- a/lib/griddler/configuration.rb +++ b/lib/griddler/configuration.rb @@ -33,6 +33,14 @@ def to=(type) @to = type end + def from + @from ||= :email + end + + def from=(type) + @from = type + end + def processor_class @processor_class ||= EmailProcessor end diff --git a/lib/griddler/email.rb b/lib/griddler/email.rb index c9900cd0..15d83953 100644 --- a/lib/griddler/email.rb +++ b/lib/griddler/email.rb @@ -10,7 +10,7 @@ def initialize(params) @params = params @to = recipients - @from = extract_address(params[:from], :email) + @from = extract_address(params[:from], config.from) @subject = params[:subject] @body = extract_body diff --git a/lib/griddler/email_parser.rb b/lib/griddler/email_parser.rb index 4058b6a6..61c275e2 100644 --- a/lib/griddler/email_parser.rb +++ b/lib/griddler/email_parser.rb @@ -13,12 +13,14 @@ module Griddler::EmailParser def self.parse_address(full_address) email_address = extract_email_address(full_address) + name = extract_name(full_address) token, host = split_address(email_address) { token: token, host: host, email: email_address, full: full_address, + name: name, } end @@ -60,6 +62,14 @@ def self.extract_email_address(full_address) full_address.split('<').last.delete('>').strip end + def self.extract_name(full_address) + full_address = full_address.strip + name = full_address.split('<').first.strip + if name.present? && name != full_address + name + end + end + def self.split_address(email_address) email_address.try :split, '@' end diff --git a/spec/features/adapters_and_email_spec.rb b/spec/features/adapters_and_email_spec.rb index 046b31f6..81d5c11c 100644 --- a/spec/features/adapters_and_email_spec.rb +++ b/spec/features/adapters_and_email_spec.rb @@ -15,7 +15,8 @@ token: 'hi', host: 'example.com', full: 'Hello World ', - email: 'hi@example.com' + email: 'hi@example.com', + name: 'Hello World', }]) end diff --git a/spec/griddler/adapters/postmark_adapter_spec.rb b/spec/griddler/adapters/postmark_adapter_spec.rb index 8a11913c..16336426 100644 --- a/spec/griddler/adapters/postmark_adapter_spec.rb +++ b/spec/griddler/adapters/postmark_adapter_spec.rb @@ -4,7 +4,7 @@ it 'normalizes parameters' do Griddler::Adapters::PostmarkAdapter.normalize_params(default_params).should be_normalized_to({ to: ['Robert Paulson '], - from: 'tdurden@example.com', + from: 'Tyler Durden ', subject: 'Reminder: First and Second Rule', text: /Dear bob/, html: %r{

Dear bob

} diff --git a/spec/griddler/configuration_spec.rb b/spec/griddler/configuration_spec.rb index 96417b54..d266f402 100644 --- a/spec/griddler/configuration_spec.rb +++ b/spec/griddler/configuration_spec.rb @@ -9,6 +9,7 @@ it 'provides defaults' do Griddler.configuration.processor_class.should eq(EmailProcessor) Griddler.configuration.to.should eq(:hash) + Griddler.configuration.from.should eq(:email) Griddler.configuration.reply_delimiter.should eq('Reply ABOVE THIS LINE') Griddler.configuration.email_service.should eq(Griddler::Adapters::SendgridAdapter) end @@ -22,9 +23,11 @@ it 'stores config' do Griddler.configure do |config| config.to = :full + config.from = :hash end Griddler.configuration.to.should eq :full + Griddler.configuration.from.should eq :hash end it 'warns when setting token' do diff --git a/spec/griddler/email_spec.rb b/spec/griddler/email_spec.rb index caa208de..239c3bd7 100644 --- a/spec/griddler/email_spec.rb +++ b/spec/griddler/email_spec.rb @@ -317,45 +317,51 @@ def header_from_email(header) email: 'bob@example.com', token: 'bob', host: 'example.com', + name: 'Bob', } - @address = @hash[:email] + @address = @hash[:full] + end + + it 'extracts the name' do + email = Griddler::Email.new(to: [@address], from: @address).process + email.to.should eq [@hash.merge(name: 'Bob')] end it 'handles normal e-mail address' do - email = Griddler::Email.new(text: 'hi', to: [@address], from: @address).process - email.to.should eq [@hash.merge(full: @address)] - email.from.should eq @address + email = Griddler::Email.new(text: 'hi', to: [@hash[:email]], from: @address).process + email.to.should eq [@hash.merge(full: @hash[:email], name: nil)] + email.from.should eq @hash[:email] end it 'handles new lines' do email = Griddler::Email.new(text: 'hi', to: ["#{@address}\n"], from: "#{@address}\n").process email.to.should eq [@hash.merge(full: "#{@address}\n")] - email.from.should eq @address + email.from.should eq @hash[:email] end it 'handles angle brackets around address' do - email = Griddler::Email.new(text: 'hi', to: ["<#{@address}>"], - from: "<#{@address}>").process - email.to.should eq [@hash.merge(full: "<#{@address}>")] - email.from.should eq @address + email = Griddler::Email.new(text: 'hi', to: ["<#{@hash[:email]}>"], + from: "<#{@hash[:email]}>").process + email.to.should eq [@hash.merge(full: "<#{@hash[:email]}>", name: nil)] + email.from.should eq @hash[:email] end it 'handles name and angle brackets around address' do - email = Griddler::Email.new(text: 'hi', to: ["Bob <#{@address}>"], - from: "Bob <#{@address}>").process + email = Griddler::Email.new(text: 'hi', to: [@address], + from: @address).process email.to.should eq [@hash] - email.from.should eq @address + email.from.should eq @hash[:email] end it 'handles multiple e-mails, with priority to the bracketed' do email = Griddler::Email.new( text: 'hi', - to: ["fake@example.com <#{@address}>"], - from: "fake@example.com <#{@address}>" + to: ["fake@example.com <#{@hash[:email]}>"], + from: "fake@example.com <#{@hash[:email]}>" ).process - email.to.should eq [@hash.merge(full: "fake@example.com <#{@address}>")] - email.from.should eq @address + email.to.should eq [@hash.merge(full: "fake@example.com <#{@hash[:email]}>", name: 'fake@example.com')] + email.from.should eq @hash[:email] end end @@ -443,6 +449,7 @@ def header_from_email(header) host: 'example.com', email: 'some-identifier@example.com', full: 'Some Identifier ', + name: 'Some Identifier', } email.to.first.should be_an_instance_of(Hash) @@ -477,6 +484,50 @@ def header_from_email(header) end end + describe 'from = :hash' do + it 'returns a hash for email.from' do + Griddler.configuration.stub(from: :hash) + email = Griddler::Email.new(params).process + expected_hash = { + token: 'joeuser', + host: 'example.com', + email: 'joeuser@example.com', + full: 'Joe User ', + name: 'Joe User', + } + + email.from.should be_an_instance_of(Hash) + email.from.should eq expected_hash + end + end + + describe 'from = :full' do + it 'returns the full from for email.from' do + Griddler.configuration.stub(from: :full) + email = Griddler::Email.new(params).process + + email.from.should eq params[:from] + end + end + + describe 'from = :email' do + it 'returns just the email address for email.from' do + Griddler.configuration.stub(from: :email) + email = Griddler::Email.new(params).process + + email.from.should eq 'joeuser@example.com' + end + end + + describe 'from = :token' do + it 'returns the local portion of the email for email.from' do + Griddler.configuration.stub(from: :token) + email = Griddler::Email.new(params).process + + email.from.should eq 'joeuser' + end + end + describe 'processor_class' do it 'calls process on the custom processor class' do my_handler = double