fake-smtp/internal/command/store_email.go

101 lines
2.1 KiB
Go

package command
import (
"context"
"time"
"github.com/pkg/errors"
"forge.cadoles.com/wpetit/fake-smtp/internal/model"
"forge.cadoles.com/wpetit/fake-smtp/internal/storm"
"github.com/jhillyerd/enmime"
"gitlab.com/wpetit/goweb/cqrs"
"gitlab.com/wpetit/goweb/middleware/container"
)
type StoreEmailRequest struct {
Envelope *enmime.Envelope
}
func HandleStoreEmail(ctx context.Context, cmd cqrs.Command) error {
req, ok := cmd.Request().(*StoreEmailRequest)
if !ok {
return cqrs.ErrUnexpectedRequest
}
ctn, err := container.From(ctx)
if err != nil {
return errors.Wrap(err, "could not retrieve service container")
}
db, err := storm.From(ctn)
if err != nil {
return errors.Wrap(err, "could not retrieve storm service")
}
email := &model.Email{
Headers: make(map[string][]string),
SentAt: time.Now(),
}
email.HTML = req.Envelope.HTML
email.Text = req.Envelope.Text
for _, k := range req.Envelope.GetHeaderKeys() {
switch k {
case "From":
from, err := req.Envelope.AddressList(k)
if err != nil {
return errors.Wrapf(err, "could not retrieve '%s' adresses", k)
}
email.From = from
case "To":
to, err := req.Envelope.AddressList(k)
if err != nil {
return errors.Wrapf(err, "could not retrieve '%s' adresses", k)
}
email.To = to
case "Cc":
cc, err := req.Envelope.AddressList(k)
if err != nil {
return errors.Wrapf(err, "could not retrieve '%s' adresses", k)
}
email.Cc = cc
case "Cci":
cci, err := req.Envelope.AddressList(k)
if err != nil {
return errors.Wrapf(err, "could not retrieve '%s' adresses", k)
}
email.Cci = cci
case "Subject":
email.Subject = req.Envelope.GetHeader(k)
default:
email.Headers[k] = req.Envelope.GetHeaderValues(k)
}
}
email.Attachments = make([]*model.Attachment, 0, len(req.Envelope.Attachments))
for _, a := range req.Envelope.Attachments {
email.Attachments = append(email.Attachments, &model.Attachment{
ContentType: a.ContentType,
Name: a.FileName,
Data: a.Content,
})
}
if err := db.Save(email); err != nil {
return errors.Wrap(err, "could not save email")
}
return nil
}