diff --git a/helpers/inbound/README.md b/helpers/inbound/README.md index b7c06e86..a18bfa78 100644 --- a/helpers/inbound/README.md +++ b/helpers/inbound/README.md @@ -27,10 +27,10 @@ func inboundHandler(response http.ResponseWriter, request *http.Request) { fmt.Print(parsedEmail.Headers["From"]) - for filename, contents := range parsedEmail.Attachments { - // Do something with an attachment - handleAttachment(filename, contents) - } + for _, file := range parsedEmail.Attachments { + // Do something with an attachment + handleAttachment(file.Filename, file.Content) + } for section, body := range parsedEmail.Body { // Do something with the email body diff --git a/helpers/inbound/inbound.go b/helpers/inbound/inbound.go index cd95e242..4dfa7613 100644 --- a/helpers/inbound/inbound.go +++ b/helpers/inbound/inbound.go @@ -6,13 +6,21 @@ import ( "mime" "mime/multipart" "net/http" + "net/textproto" "strings" ) +type ParsedAttachment struct { + Headers textproto.MIMEHeader + ContentType string + Filename string + Content []byte +} + type ParsedEmail struct { Headers map[string]string Body map[string]string - Attachments map[string][]byte + Attachments []ParsedAttachment rawRequest *http.Request } @@ -20,7 +28,7 @@ func Parse(request *http.Request) (*ParsedEmail, error) { result := ParsedEmail{ Headers: make(map[string]string), Body: make(map[string]string), - Attachments: make(map[string][]byte), + Attachments: []ParsedAttachment{}, rawRequest: request, } err := result.parse() @@ -76,11 +84,16 @@ func (email *ParsedEmail) parseRawEmail(rawEmail string) error { } } else if emailPart.FileName() != "" { - b, err := ioutil.ReadAll(emailPart) - if err != nil { - return err + content := readBody(emailPart) + + attachment := ParsedAttachment{ + Filename: emailPart.FileName(), + ContentType: strings.Split(emailPart.Header.Get("Content-Type"), ";")[0], + Content: content, + Headers: emailPart.Header, } - email.Attachments[emailPart.FileName()] = b + + email.Attachments = append(email.Attachments, attachment) } else { header := emailPart.Header.Get("Content-Type") b, err := ioutil.ReadAll(emailPart) diff --git a/helpers/inbound/inbound_test.go b/helpers/inbound/inbound_test.go index b8b0019e..d1fcce63 100644 --- a/helpers/inbound/inbound_test.go +++ b/helpers/inbound/inbound_test.go @@ -70,6 +70,14 @@ func TestParse(t *testing.T) { } } +func TestAttachments(t *testing.T) { + req := createRequest("./sample_data/raw_data_with_attachments.txt") + email := Parse(req) + contentType := "image/jpeg" + + assert.Equalf(t, contentType, email.Attachments[0].ContentType,"Expected From: %s, Got: %s", contentType, email.Attachments[0].ContentType) +} + func ExampleParsedEmail_parseHeaders() { headers := ` Foo: foo @@ -78,7 +86,7 @@ Bar: baz email := ParsedEmail{ Headers: make(map[string]string), Body: make(map[string]string), - Attachments: make(map[string][]byte), + Attachments: []ParsedAttachment{}, rawRequest: nil, } email.parseHeaders(headers) @@ -110,7 +118,7 @@ Content-Transfer-Encoding: quoted-printable email := ParsedEmail{ Headers: make(map[string]string), Body: make(map[string]string), - Attachments: make(map[string][]byte), + Attachments: []ParsedAttachment{}, rawRequest: nil, } @@ -128,4 +136,4 @@ Content-Transfer-Encoding: quoted-printable // Subject Test Email // Content-Type multipart/mixed; boundary=TwiLIo // Hello Twilio SendGrid! -} +} \ No newline at end of file