Files
kjol/go/snailmail/cloudflare.go

90 lines
2.2 KiB
Go

package snailmail
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
)
type cloudflareSender struct{}
type cfEmailRequest struct {
To string `json:"to"`
From string `json:"from"`
Subject string `json:"subject"`
HTML string `json:"html,omitempty"`
Text string `json:"text,omitempty"`
}
type cfEmailResponse struct {
Success bool `json:"success"`
Errors []struct {
Code int `json:"code"`
Message string `json:"message"`
} `json:"errors"`
}
func (c *cloudflareSender) Send(message Email, mailtype int) error {
if len(message.Recipients) == 0 {
return fmt.Errorf("cloudflare email: no recipients")
}
req := cfEmailRequest{
To: message.Recipients[0],
From: settings.Cloudflare.FromAddress,
Subject: message.Subject,
}
if mailtype == TYPE_HTML {
req.HTML = message.Body.String()
} else {
req.Text = message.Body.String()
}
body, err := json.Marshal(req)
if err != nil {
return fmt.Errorf("cloudflare email: failed to marshal request: %w", err)
}
url := fmt.Sprintf("https://api.cloudflare.com/client/v4/accounts/%s/email/sending/send", settings.Cloudflare.AccountID)
httpReq, err := http.NewRequest("POST", url, bytes.NewReader(body))
if err != nil {
return fmt.Errorf("cloudflare email: failed to create request: %w", err)
}
httpReq.Header.Set("Authorization", "Bearer "+settings.Cloudflare.APIToken)
httpReq.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(httpReq)
if err != nil {
log.Println("cloudflare email: request failed:", err)
return fmt.Errorf("cloudflare email: request failed: %w", err)
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("cloudflare email: failed to read response: %w", err)
}
var cfResp cfEmailResponse
if err := json.Unmarshal(respBody, &cfResp); err != nil {
return fmt.Errorf("cloudflare email: failed to parse response: %w", err)
}
if !cfResp.Success {
errMsg := "unknown error"
if len(cfResp.Errors) > 0 {
errMsg = cfResp.Errors[0].Message
}
log.Printf("cloudflare email: send failed: %s (HTTP %d)", errMsg, resp.StatusCode)
return fmt.Errorf("cloudflare email: %s", errMsg)
}
return nil
}