204 lines
5.2 KiB
Go
204 lines
5.2 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
)
|
|
|
|
// The response from a get reqeuest to the postmark tempalte API.
|
|
type PostmarkTemplate struct {
|
|
TemplateId int
|
|
Name string
|
|
Subject string
|
|
HtmlBody string
|
|
TextBody string
|
|
AssociatedServerId int
|
|
Active bool
|
|
Alias string
|
|
TemplateType string
|
|
LayoutTemplate string
|
|
}
|
|
|
|
// The model that we're using for the template that abner made
|
|
type PostmarkTemplateModel struct {
|
|
Name string `json:"name"`
|
|
Email string `json:"email"`
|
|
Body string `json:"body"`
|
|
Subject string `json:"subject"`
|
|
}
|
|
|
|
// The request body for the postmark validate endpoint which renders a provided tempalte if its valid
|
|
type ValidateTemplateBody struct {
|
|
Subject string
|
|
HTMLBody string
|
|
TextBody string
|
|
|
|
TestRenderModel PostmarkTemplateModel
|
|
// There are other body options but i think this is all we care about
|
|
// InlineCssForHtmlTestRender bool
|
|
// TemplateType string
|
|
}
|
|
|
|
// The validation error types returned from the postmark template validation api
|
|
type ValidationError struct {
|
|
Message string
|
|
Line int
|
|
CharacterPosition int
|
|
}
|
|
|
|
type ContentBodyValidationResponse struct {
|
|
ContentIsValid bool
|
|
ValidationErrors []ValidationError
|
|
RenderedContent string
|
|
}
|
|
|
|
// The response from the postmark tempalte validation endpoint
|
|
type ValidationResponse struct {
|
|
AllContentIsValid bool
|
|
Subject ContentBodyValidationResponse
|
|
HtmlBody ContentBodyValidationResponse
|
|
TextBody ContentBodyValidationResponse
|
|
SuggestedTemplateModel interface{}
|
|
}
|
|
|
|
type Email struct {
|
|
Html string
|
|
Subject string
|
|
}
|
|
|
|
// Gets the tempalte in the postmark config section of the app.ini file from teh postmark server so we can render it
|
|
func getPostmarkTemplate(cfg ApiConfig) PostmarkTemplate {
|
|
// Get Template
|
|
getTemplateURL := fmt.Sprintf("https://api.postmarkapp.com/templates/%v", cfg.Postmark.TemplateId)
|
|
getReq, err := http.NewRequest(http.MethodGet, getTemplateURL, bytes.NewBuffer([]byte("")))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
getReq.Header.Add("Accept", "application/json")
|
|
getReq.Header.Add("X-Postmark-Server-Token", cfg.Postmark.ServerToken)
|
|
|
|
client := &http.Client{}
|
|
getResp, err := client.Do(getReq)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer getReq.Body.Close()
|
|
|
|
template := PostmarkTemplate{}
|
|
decode_error := json.NewDecoder(getResp.Body).Decode(&template)
|
|
|
|
if decode_error != nil {
|
|
panic(decode_error)
|
|
}
|
|
return template
|
|
}
|
|
|
|
// Given a tempalte and model use the postmark tempalte validation api to render the template
|
|
func renderPostmarkTemplate(cfg ApiConfig, template PostmarkTemplate, model PostmarkTemplateModel) Email {
|
|
bodyObj := ValidateTemplateBody{
|
|
Subject: template.Subject,
|
|
HTMLBody: template.HtmlBody,
|
|
TextBody: template.TextBody,
|
|
TestRenderModel: model,
|
|
}
|
|
|
|
body, err := json.Marshal(bodyObj)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
req, err := http.NewRequest("POST", "https://api.postmarkapp.com/templates/validate", bytes.NewBuffer(body))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
req.Header.Add("Content-Type", "application/json")
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("X-Postmark-Server-Token", cfg.Postmark.ServerToken)
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
response := &ValidationResponse{}
|
|
rawBodyContent, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
decode_error := json.NewDecoder(bytes.NewBuffer(rawBodyContent)).Decode(response)
|
|
if decode_error != nil {
|
|
panic(decode_error)
|
|
}
|
|
|
|
return Email{
|
|
Html: response.HtmlBody.RenderedContent,
|
|
Subject: response.Subject.RenderedContent,
|
|
}
|
|
}
|
|
|
|
type PostmarkBatchArguments struct {
|
|
From string
|
|
To string
|
|
TemplateId int
|
|
TemplateModel PostmarkTemplateModel
|
|
MessageStream string
|
|
}
|
|
|
|
func sendBatchWithTemplate(cfg ApiConfig, email, subject string, recipients []string) {
|
|
type BatchAPIArgs struct {
|
|
Messages []PostmarkBatchArguments
|
|
}
|
|
bodyObj := &BatchAPIArgs{}
|
|
|
|
for _, recipient := range recipients {
|
|
args := PostmarkBatchArguments{
|
|
From: cfg.Postmark.SenderEmail,
|
|
To: recipient,
|
|
TemplateId: cfg.Postmark.TemplateId,
|
|
TemplateModel: PostmarkTemplateModel{
|
|
Name: cfg.Postmark.SenderName,
|
|
Email: cfg.Postmark.SenderEmail,
|
|
Body: email,
|
|
Subject: subject,
|
|
},
|
|
MessageStream: cfg.Postmark.MessageStream,
|
|
}
|
|
bodyObj.Messages = append(bodyObj.Messages, args)
|
|
}
|
|
|
|
body, err := json.Marshal(bodyObj)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
req, err := http.NewRequest("POST", "https://api.postmarkapp.com/email/batchWithTemplates", bytes.NewBuffer(body))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Content-Type", "application/json")
|
|
req.Header.Add("X-Postmark-Server-Token", cfg.Postmark.ServerToken)
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
rawBodyContent, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
log.Printf("batchWithTemplates responded with: %s\n", string(rawBodyContent))
|
|
}
|