HMC_Host_Dashboard/postmark.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))
}