git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/email/postmark/postmark.go (about)

     1  package postmark
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  	"strings"
     7  
     8  	"git.sr.ht/~pingoo/stdx/email"
     9  	"git.sr.ht/~pingoo/stdx/postmark"
    10  )
    11  
    12  // Mailer implements the `email.Mailer` interface to send emails using postmarkapp.com's API
    13  // https://postmarkapp.com/developer/api/overview
    14  type Mailer struct {
    15  	accountApiToken             string
    16  	serverApiToken              string
    17  	postmarkClient              *postmark.Client
    18  	messageStreamBroadcast      string
    19  	messageStreamTransactionnal string
    20  }
    21  
    22  type Config struct {
    23  	AccountApiToken string
    24  	ServerApiToken  string
    25  	HttpClient      *http.Client
    26  }
    27  
    28  // NewMailer returns a new smtp Mailer
    29  func NewMailer(config Config) *Mailer {
    30  	postmarkClient := postmark.NewClient(config.AccountApiToken, config.HttpClient)
    31  
    32  	return &Mailer{
    33  		accountApiToken:             config.AccountApiToken,
    34  		serverApiToken:              config.ServerApiToken,
    35  		postmarkClient:              postmarkClient,
    36  		messageStreamBroadcast:      "broadcast",
    37  		messageStreamTransactionnal: "outbound",
    38  	}
    39  }
    40  
    41  func (mailer *Mailer) SendTransactionnal(ctx context.Context, email email.Email) error {
    42  	replyTo := ""
    43  
    44  	if len(email.ReplyTo) == 1 {
    45  		replyTo = email.ReplyTo[0].String()
    46  	}
    47  
    48  	postmarkEmail := postmark.Email{
    49  		From:          email.From.String(),
    50  		To:            email.To[0].String(),
    51  		ReplyTo:       replyTo,
    52  		Subject:       email.Subject,
    53  		HtmlBody:      string(email.HTML),
    54  		TextBody:      string(email.Text),
    55  		MessageStream: mailer.messageStreamTransactionnal,
    56  	}
    57  
    58  	_, err := mailer.postmarkClient.SendEmail(ctx, mailer.serverApiToken, postmarkEmail)
    59  
    60  	return err
    61  }
    62  
    63  func (mailer *Mailer) SendBroadcast(ctx context.Context, email email.Email) error {
    64  	replyTo := ""
    65  
    66  	if len(email.ReplyTo) == 1 {
    67  		replyTo = email.ReplyTo[0].String()
    68  	}
    69  
    70  	headers := make([]postmark.Header, 0, len(email.Headers))
    71  	for key, values := range email.Headers {
    72  		headers = append(headers, postmark.Header{
    73  			Name:  key,
    74  			Value: strings.Join(values, ","),
    75  		})
    76  	}
    77  
    78  	postmarkEmail := postmark.Email{
    79  		From:          email.From.String(),
    80  		To:            email.To[0].String(),
    81  		ReplyTo:       replyTo,
    82  		Subject:       email.Subject,
    83  		HtmlBody:      string(email.HTML),
    84  		TextBody:      string(email.Text),
    85  		MessageStream: mailer.messageStreamBroadcast,
    86  		Headers:       headers,
    87  	}
    88  
    89  	_, err := mailer.postmarkClient.SendEmail(ctx, mailer.serverApiToken, postmarkEmail)
    90  
    91  	return err
    92  }