Migrate to the new toml file for config from the go email sender

main
Jack Punter 2024-04-23 23:38:44 +01:00
parent ed872ddfa3
commit cb425edd8b
5 changed files with 62 additions and 73 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
tmp/ tmp/
app.ini app.toml

2
go.mod
View File

@ -2,4 +2,4 @@ module send_email_site
go 1.21.6 go 1.21.6
require gopkg.in/ini.v1 v1.67.0 // indirect require github.com/pelletier/go-toml/v2 v2.2.1

22
go.sum
View File

@ -1,2 +1,20 @@
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pelletier/go-toml/v2 v2.2.1 h1:9TA9+T8+8CUCO2+WYnDLCgrYi9+omqKXyjDtosvtEhg=
github.com/pelletier/go-toml/v2 v2.2.1/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

97
main.go
View File

@ -15,73 +15,44 @@ import (
"strings" "strings"
"time" "time"
"gopkg.in/ini.v1" "github.com/pelletier/go-toml/v2"
) )
// ------------- Api configs ------------- // ------------- Api configs -------------
type DefaultSectionConfig struct {
Live bool
TestEmail string
SenderName string
}
type HMCConfig struct {
ApiSecret string
ApiUrl string
City string
}
type PostmarkConfig struct {
ServerToken string
ApiUrl string
TemplateId int
SenderEmail string
MessageStream string
}
type ApiConfig struct { type ApiConfig struct {
Default DefaultSectionConfig BatchSize int `toml:"batch_size"`
Hmc HMCConfig TestEmail string `toml:"test_email"`
Postmark PostmarkConfig HMC struct {
ApiUrl string `toml:"api_url"`
SharedSecret string `toml:"shared_secret"`
City string `toml:"city"`
} `toml:"hmc"`
Postmark struct {
ServerToken string `toml:"server_token"`
ApiUrl string `toml:"api_url"`
TemplateId int `toml:"template_id"`
SenderName string `toml:"sender_name"`
SenderEmail string `toml:"sender_email"`
MessageStream string `toml:"message_stream"`
} `toml:"postmark"`
} }
// Load the HMCsend-email app.ini and store the values in a structure, some of the keys in here // Load the HMCsend-email app.ini and store the values in a structure, some of the keys in here
// we probably don't actualy care about for this usage. // we probably don't actualy care about for this usage.
func loadConfig() ApiConfig { func loadConfig() ApiConfig {
// Read the config file and get the HMC api settings configFile := "app.toml"
config, err := ini.Load("app.ini") data, err := os.ReadFile(configFile)
if err != nil { if err != nil {
panic(err) fmt.Println("Error reading TOML file:", err)
os.Exit(1)
} }
defSection := config.Section("DEFAULT") config := ApiConfig{}
def := DefaultSectionConfig{ if err := toml.Unmarshal(data, &config); err != nil {
Live: defSection.Key("LIVE").MustBool(), fmt.Println("Error unmarshaling TOML:", err)
TestEmail: defSection.Key("TEST_EMAIL").String(), os.Exit(1)
SenderName: defSection.Key("SENDER_NAME").String(),
}
hmcSection := config.Section("hmc")
hmc := HMCConfig{
ApiSecret: hmcSection.Key("SHARED_SECRET").String(),
ApiUrl: hmcSection.Key("API_URL").String(),
City: hmcSection.Key("CITY").String(),
}
postmarkSection := config.Section("postmark")
postmark := PostmarkConfig{
ServerToken: postmarkSection.Key("SERVER_TOKEN").String(),
ApiUrl: postmarkSection.Key("API_URL").String(),
TemplateId: postmarkSection.Key("TEMPLATE_ID").MustInt(),
SenderEmail: postmarkSection.Key("SENDER_EMAIL").String(),
MessageStream: postmarkSection.Key("MESSAGE_STREAM").String(),
}
return ApiConfig{
Default: def,
Hmc: hmc,
Postmark: postmark,
} }
return config
} }
func ParseArguments(rawArgs string) map[string]string { func ParseArguments(rawArgs string) map[string]string {
@ -101,14 +72,14 @@ func GetMailingList(cfg ApiConfig) []string {
type EmailsResonse struct { type EmailsResonse struct {
Emails []string `json:"emails"` Emails []string `json:"emails"`
} }
body := []byte(fmt.Sprintf("{\"city\": \"%s\"}", cfg.Hmc.City)) body := []byte(fmt.Sprintf("{\"city\": \"%s\"}", cfg.HMC.City))
req, err := http.NewRequest("POST", cfg.Hmc.ApiUrl, bytes.NewBuffer(body)) req, err := http.NewRequest("POST", cfg.HMC.ApiUrl, bytes.NewBuffer(body))
if err != nil { if err != nil {
panic(err) panic(err)
} }
req.Header.Add("Content-Type", "application/json") req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", cfg.Hmc.ApiSecret) req.Header.Add("Authorization", cfg.HMC.SharedSecret)
client := &http.Client{} client := &http.Client{}
res, err := client.Do(req) res, err := client.Do(req)
@ -127,7 +98,7 @@ func GetMailingList(cfg ApiConfig) []string {
func main() { func main() {
apiConfig := loadConfig() apiConfig := loadConfig()
postmarkTemplate := getPostmarkTemplate(apiConfig.Postmark) postmarkTemplate := getPostmarkTemplate(apiConfig)
// Prepare the go html templates and static file server // Prepare the go html templates and static file server
templates := template.Must(template.ParseGlob("templates/*.html")) templates := template.Must(template.ParseGlob("templates/*.html"))
@ -160,13 +131,13 @@ func main() {
// Return a response to HTMX // Return a response to HTMX
model := PostmarkTemplateModel{ model := PostmarkTemplateModel{
Name: apiConfig.Default.SenderName, Name: apiConfig.Postmark.SenderName,
Email: apiConfig.Postmark.SenderEmail, Email: apiConfig.Postmark.SenderEmail,
Body: email_content, Body: email_content,
Subject: "This is a test subject", // TODO(jack): Get from user input on page Subject: "This is a test subject", // TODO(jack): Get from user input on page
} }
renderedEmail := renderPostmarkTemplate(apiConfig.Postmark, postmarkTemplate, model) renderedEmail := renderPostmarkTemplate(apiConfig, postmarkTemplate, model)
w.Write([]byte(renderedEmail.Html)) w.Write([]byte(renderedEmail.Html))
}) })
@ -186,12 +157,12 @@ func main() {
} }
model := PostmarkTemplateModel{ model := PostmarkTemplateModel{
Name: apiConfig.Default.SenderName, Name: apiConfig.Postmark.SenderName,
Email: apiConfig.Postmark.SenderEmail, Email: apiConfig.Postmark.SenderEmail,
Body: "", Body: "",
Subject: decoded_subject, // TODO(jack): Get from user input on page Subject: decoded_subject, // TODO(jack): Get from user input on page
} }
renderedEmail := renderPostmarkTemplate(apiConfig.Postmark, postmarkTemplate, model) renderedEmail := renderPostmarkTemplate(apiConfig, postmarkTemplate, model)
w.Write([]byte(renderedEmail.Subject)) w.Write([]byte(renderedEmail.Subject))
}) })
@ -217,7 +188,7 @@ func main() {
fmt.Printf("%v\n", arguments) fmt.Printf("%v\n", arguments)
var recipients []string var recipients []string
if arguments["destination"] == "test" { if arguments["destination"] == "test" {
recipients = []string{apiConfig.Default.TestEmail} recipients = []string{apiConfig.TestEmail}
} else if arguments["destination"] == "mailing_list" { } else if arguments["destination"] == "mailing_list" {
recipients = GetMailingList(apiConfig) recipients = GetMailingList(apiConfig)
} else { } else {

View File

@ -71,15 +71,15 @@ type Email struct {
} }
// Gets the tempalte in the postmark config section of the app.ini file from teh postmark server so we can render it // 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 PostmarkConfig) PostmarkTemplate { func getPostmarkTemplate(cfg ApiConfig) PostmarkTemplate {
// Get Template // Get Template
getTemplateURL := fmt.Sprintf("https://api.postmarkapp.com/templates/%v", cfg.TemplateId) getTemplateURL := fmt.Sprintf("https://api.postmarkapp.com/templates/%v", cfg.Postmark.TemplateId)
getReq, err := http.NewRequest(http.MethodGet, getTemplateURL, bytes.NewBuffer([]byte(""))) getReq, err := http.NewRequest(http.MethodGet, getTemplateURL, bytes.NewBuffer([]byte("")))
if err != nil { if err != nil {
panic(err) panic(err)
} }
getReq.Header.Add("Accept", "application/json") getReq.Header.Add("Accept", "application/json")
getReq.Header.Add("X-Postmark-Server-Token", cfg.ServerToken) getReq.Header.Add("X-Postmark-Server-Token", cfg.Postmark.ServerToken)
client := &http.Client{} client := &http.Client{}
getResp, err := client.Do(getReq) getResp, err := client.Do(getReq)
@ -98,7 +98,7 @@ func getPostmarkTemplate(cfg PostmarkConfig) PostmarkTemplate {
} }
// Given a tempalte and model use the postmark tempalte validation api to render the template // Given a tempalte and model use the postmark tempalte validation api to render the template
func renderPostmarkTemplate(cfg PostmarkConfig, template PostmarkTemplate, model PostmarkTemplateModel) Email { func renderPostmarkTemplate(cfg ApiConfig, template PostmarkTemplate, model PostmarkTemplateModel) Email {
bodyObj := ValidateTemplateBody{ bodyObj := ValidateTemplateBody{
Subject: template.Subject, Subject: template.Subject,
HTMLBody: template.HtmlBody, HTMLBody: template.HtmlBody,
@ -118,7 +118,7 @@ func renderPostmarkTemplate(cfg PostmarkConfig, template PostmarkTemplate, model
req.Header.Add("Content-Type", "application/json") req.Header.Add("Content-Type", "application/json")
req.Header.Add("Accept", "application/json") req.Header.Add("Accept", "application/json")
req.Header.Add("X-Postmark-Server-Token", cfg.ServerToken) req.Header.Add("X-Postmark-Server-Token", cfg.Postmark.ServerToken)
client := &http.Client{} client := &http.Client{}
resp, err := client.Do(req) resp, err := client.Do(req)
@ -163,7 +163,7 @@ func sendBatchWithTemplate(cfg ApiConfig, email, subject string, recipients []st
To: recipient, To: recipient,
TemplateId: cfg.Postmark.TemplateId, TemplateId: cfg.Postmark.TemplateId,
TemplateModel: PostmarkTemplateModel{ TemplateModel: PostmarkTemplateModel{
Name: cfg.Default.SenderName, Name: cfg.Postmark.SenderName,
Email: cfg.Postmark.SenderEmail, Email: cfg.Postmark.SenderEmail,
Body: email, Body: email,
Subject: subject, Subject: subject,