Mail gem. Extract recipient display name and address as separate values
Asked Answered
F

2

13

Using the Mail gem (i.e. Rails + ActionMailer), is there a clean way to get the display name of the recipient?

I can get the address with:

mail.to.first

And I can get the formatted display name + address with:

mail.header_fields.select{ |f| f.name == "To" }.first.to_s

But how can I get just the display name part (i.e. before the < and >). I know somebody is going to suggest a Regex, but that's not what I'm looking for, since I'd then have to parse out any encoding, which is something the Mail gem probably already does. I'm the author of a popular Mailer library in PHP and am aware of the pitfalls of just assuming the bit before < and > is human-readable, in the headers, when 8-bit characters come into play.

I can do this:

mail.header_fields.select{ |f| f.name == "To" }.first.parse.individual_recipients.first.display_name.text_value

But there must be a better way? :)

Fullscale answered 27/8, 2011 at 7:44 Comment(0)
F
25

Figured it out, sorry. For anyone else who hits this thread looking for the solution:

mail[:to].display_names.first
Fullscale answered 27/8, 2011 at 8:11 Comment(5)
Your answer helped me find a way to create email address with display name containing angle brackets and quotesSolita
Also: mail[:to].addrs.first.display_name (could be handy if you want to keep the name-address relation).Mayan
I would like to mention that message[:to] is not at all the same thing as message.to - that is embarassing!!! Took me 2 hours of digging in the source code to find out.Monition
I could not replicate this with the mail gem packaged in rails 6Cherlynchernow
Make sure you use the bracket notation. The gotcha is that the gem uses the bracket notation and dotted notation for two different things. Doc for To field class is at rubydoc.info/github/mikel/mail/Mail/ToFieldLondrina
L
6

The gotcha is that bracket access and dotted access are different for this gem.

From the doc:

mail = Mail.new
mail.to = 'Mikel Lindsaar <[email protected]>, [email protected]'
mail.to    #=> ['[email protected]', '[email protected]']
mail[:to]  #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ToField:0x180e1c4
mail['to'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ToField:0x180e1c4
mail['To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::ToField:0x180e1c4

mail[:to].encoded   #=> 'To: Mikel Lindsaar <[email protected]>, [email protected]\r\n'
mail[:to].decoded   #=> 'Mikel Lindsaar <[email protected]>, [email protected]'
mail[:to].addresses #=> ['[email protected]', '[email protected]']
mail[:to].formatted #=> ['Mikel Lindsaar <[email protected]>', '[email protected]']

So to get the display name, you can use #display_name

mail[:to].addrs.first.display_name #=> Mikel Lindsaar

Use #address to get the email address

mail[:from].addrs.first.address #=> [email protected]
Londrina answered 17/3, 2021 at 16:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.