#21: Add possbility to set dedicated envelope from address

- Added `EnvelopeFrom()` and `EnvelopeFromFormat()` methods analogous to the `From()` `FromFormat()` methods
- Changed MsgWriter logic for envelope from addresses
- Adjusted `Msg.GetSender()` to return the envelope from first and only mail body from if the envelope is not set
This commit is contained in:
Winni Neessen 2022-06-13 10:18:35 +02:00
parent afa847d5df
commit a50910b943
Signed by: wneessen
GPG key ID: 385AC9889632126E
3 changed files with 41 additions and 6 deletions

View file

@ -81,7 +81,7 @@ const (
HeaderXPriority Header = "X-Priority" HeaderXPriority Header = "X-Priority"
) )
// List of common generic header field names // List of common address header field names
const ( const (
// HeaderBcc is the "Blind Carbon Copy" header field // HeaderBcc is the "Blind Carbon Copy" header field
HeaderBcc AddrHeader = "Bcc" HeaderBcc AddrHeader = "Bcc"
@ -89,6 +89,10 @@ const (
// HeaderCc is the "Carbon Copy" header field // HeaderCc is the "Carbon Copy" header field
HeaderCc AddrHeader = "Cc" HeaderCc AddrHeader = "Cc"
// HeaderEnvelopeFrom is the envelope FROM header field
// It's not included in the mail body but only used by the Client for the envelope
HeaderEnvelopeFrom AddrHeader = "EnvelopeFrom"
// HeaderFrom is the "From" header field // HeaderFrom is the "From" header field
HeaderFrom AddrHeader = "From" HeaderFrom AddrHeader = "From"

22
msg.go
View file

@ -197,6 +197,18 @@ func (m *Msg) SetAddrHeaderIgnoreInvalid(h AddrHeader, v ...string) {
m.addrHeader[h] = al m.addrHeader[h] = al
} }
// EnvelopeFrom takes and validates a given mail address and sets it as envelope "FROM"
// addrHeader of the Msg
func (m *Msg) EnvelopeFrom(f string) error {
return m.SetAddrHeader(HeaderEnvelopeFrom, f)
}
// EnvelopeFromFormat takes a name and address, formats them RFC5322 compliant and stores them as
// the envelope FROM address header field
func (m *Msg) EnvelopeFromFormat(n, a string) error {
return m.SetAddrHeader(HeaderEnvelopeFrom, fmt.Sprintf(`"%s" <%s>`, n, a))
}
// From takes and validates a given mail address and sets it as "From" genHeader of the Msg // From takes and validates a given mail address and sets it as "From" genHeader of the Msg
func (m *Msg) From(f string) error { func (m *Msg) From(f string) error {
return m.SetAddrHeader(HeaderFrom, f) return m.SetAddrHeader(HeaderFrom, f)
@ -365,13 +377,17 @@ func (m *Msg) SetUserAgent(a string) {
m.SetHeader(HeaderXMailer, a) m.SetHeader(HeaderXMailer, a)
} }
// GetSender returns the currently set FROM address. If f is true, it will return the full // GetSender returns the currently set envelope FROM address. If no envelope FROM is set it will use
// address string including the address name, if set // the first mail body FROM address. If ff is true, it will return the full address string including
// the address name, if set
func (m *Msg) GetSender(ff bool) (string, error) { func (m *Msg) GetSender(ff bool) (string, error) {
f, ok := m.addrHeader[HeaderFrom] f, ok := m.addrHeader[HeaderEnvelopeFrom]
if !ok || len(f) == 0 {
f, ok = m.addrHeader[HeaderFrom]
if !ok || len(f) == 0 { if !ok || len(f) == 0 {
return "", ErrNoFromAddress return "", ErrNoFromAddress
} }
}
if ff { if ff {
return f[0].String(), nil return f[0].String(), nil
} }

View file

@ -54,7 +54,22 @@ func (mw *msgWriter) writeMsg(m *Msg) {
m.addDefaultHeader() m.addDefaultHeader()
m.checkUserAgent() m.checkUserAgent()
mw.writeGenHeader(m) mw.writeGenHeader(m)
for _, t := range []AddrHeader{HeaderFrom, HeaderTo, HeaderCc} {
// Set the FROM header (or envelope FROM if FROM is empty)
hf := true
f, ok := m.addrHeader[HeaderFrom]
if !ok || len(f) == 0 {
f, ok = m.addrHeader[HeaderEnvelopeFrom]
if !ok || len(f) == 0 {
hf = false
}
}
if hf {
mw.writeHeader(Header(HeaderFrom), f[0].String())
}
// Set the rest of the address headers
for _, t := range []AddrHeader{HeaderTo, HeaderCc} {
if al, ok := m.addrHeader[t]; ok { if al, ok := m.addrHeader[t]; ok {
var v []string var v []string
for _, a := range al { for _, a := range al {