-
Notifications
You must be signed in to change notification settings - Fork 7
/
message.go
102 lines (83 loc) · 2.42 KB
/
message.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package main
import (
"github.com/jhillyerd/enmime"
"io"
"net/mail"
"strings"
"time"
)
type Message struct {
From []*Address `multipart:"from"`
To []*Address `multipart:"to"`
Cc []*Address `multipart:"cc"`
Bcc []*Address `multipart:"bcc"`
ReplyTo []*Address `multipart:"reply_to"`
Subject string `multipart:"subject"`
Date *Time `multipart:"date"`
MessageID string `multipart:"message_id"`
InReplyTo string `multipart:"in_reply_to"`
References []string `multipart:"references"`
Text string `multipart:"text"`
HTML string `multipart:"html"`
Attachments []*Attachment `multipart:"attachments"`
}
type Address struct {
Name string `multipart:"name"`
Email string `multipart:"email"`
}
func NewMessage(r io.Reader) (*Message, error) {
env, err := enmime.ReadEnvelope(r)
if err != nil {
return nil, err
}
msg := &Message{
Subject: env.GetHeader("Subject"),
MessageID: env.GetHeader("Message-ID"),
InReplyTo: env.GetHeader("In-Reply-To"),
References: strings.Fields(env.GetHeader("References")),
Text: env.Text,
HTML: env.HTML,
Attachments: make([]*Attachment, len(env.Attachments)),
}
for i, attachment := range env.Attachments {
msg.Attachments[i] = &Attachment{attachment}
}
if msg.From, err = readAddressListHeader(env, "From"); err != nil {
return nil, err
}
if msg.To, err = readAddressListHeader(env, "To"); err != nil {
return nil, err
}
if msg.Cc, err = readAddressListHeader(env, "Cc"); err != nil {
return nil, err
}
if msg.Bcc, err = readAddressListHeader(env, "Bcc"); err != nil {
return nil, err
}
if msg.ReplyTo, err = readAddressListHeader(env, "Reply-To"); err != nil {
return nil, err
}
if msg.Date, err = readDateHeader(env); err != nil {
return nil, err
}
return msg, nil
}
func readAddressListHeader(env *enmime.Envelope, key string) ([]*Address, error) {
list, err := env.AddressList(key)
if err != nil && err != mail.ErrHeaderNotPresent {
return nil, err
}
emails := make([]*Address, len(list))
for i, addr := range list {
emails[i] = &Address{Name: addr.Name, Email: addr.Address}
}
return emails, nil
}
func readDateHeader(env *enmime.Envelope) (*Time, error) {
hdr := env.GetHeader("Date")
if hdr == "" {
return &Time{time.Now()}, nil
}
date, err := mail.ParseDate(hdr)
return &Time{date}, err
}