From 845a57ad0c4d7aa5267e3858438ad410dd67c8c4 Mon Sep 17 00:00:00 2001 From: Chris Okuda Date: Fri, 24 Oct 2025 06:51:38 -1000 Subject: [PATCH 1/3] moved everything to the top level so that the module imports without `.../commo/commo` and updated the docs a bit --- README.md | 14 ++++++++- commo/commo.go => commo.go | 31 +++++++++++++++++++ commo/commo_test.go => commo_test.go | 2 +- commo/config.go => config.go | 0 commo/config_test.go => config_test.go | 2 +- commo/email.go => email.go | 0 commo/email_test.go => email_test.go | 2 +- commo/errors.go => errors.go | 0 commo/render.go => render.go | 0 commo/render_test.go => render_test.go | 2 +- commo/sendgrid.go => sendgrid.go | 0 commo/sendgrid_test.go => sendgrid_test.go | 2 +- {commo/testdata => testdata}/.env.template | 0 .../templates/partials/base.html | 0 .../templates/partials/style.html | 0 .../templates/test_email.html | 0 .../templates/test_email.txt | 0 17 files changed, 49 insertions(+), 6 deletions(-) rename commo/commo.go => commo.go (78%) rename commo/commo_test.go => commo_test.go (99%) rename commo/config.go => config.go (100%) rename commo/config_test.go => config_test.go (99%) rename commo/email.go => email.go (100%) rename commo/email_test.go => email_test.go (98%) rename commo/errors.go => errors.go (100%) rename commo/render.go => render.go (100%) rename commo/render_test.go => render_test.go (97%) rename commo/sendgrid.go => sendgrid.go (100%) rename commo/sendgrid_test.go => sendgrid_test.go (99%) rename {commo/testdata => testdata}/.env.template (100%) rename {commo/testdata => testdata}/templates/partials/base.html (100%) rename {commo/testdata => testdata}/templates/partials/style.html (100%) rename {commo/testdata => testdata}/templates/test_email.html (100%) rename {commo/testdata => testdata}/templates/test_email.txt (100%) diff --git a/README.md b/README.md index 2eb5ede..40ef88b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,11 @@ An email rendering and sending package that can be configured to use either Send ## Usage +First, add it to your module with `go get go.rtnl.ai/commo`. + ```go +import "go.rtnl.ai/commo" + // Load configuration from a .env file conf := commo.Config{} err := confire.Process("commo_email", &conf) @@ -30,4 +34,12 @@ err = email.Send() checkErr(err) ``` -See the test(s) in [commo/commo_test.go](./commo/commo_test.go) for a full working example. +See the test `TestLiveEmails` in [`commo_test.go`](./commo_test.go) for a full working example. + +## License + +See [LICENSE](./LICENSE) + +## Naming + +See for information on why this library is named "COMMO". diff --git a/commo/commo.go b/commo.go similarity index 78% rename from commo/commo.go rename to commo.go index 330aaa9..19f9554 100644 --- a/commo/commo.go +++ b/commo.go @@ -1,3 +1,34 @@ +/* +An email rendering and sending package that can be configured to use either SendGrid or SMTP. + +Usage Example: + + // Load configuration from a .env file + conf := commo.Config{} + err := confire.Process("commo_email", &conf) + checkErr(err) + + // Load templates + var templates map[string]*template.Template + templates = ... // not shown here; see `commo/commo_test.go` for full example + + // Initialize commo + err = commo.Initialize(conf, templates) + checkErr(err) + + // Data is a struct that has all of the required fields for the template being used + data := struct{ ContactName string }{ContactName: "User Name"} + + // Create the email + email, err := commo.New("Test User ", "Email Subject", "template_name_no_ext", data) + checkErr(err) + + // Send the email + err = email.Send() + checkErr(err) + +See the test TestLiveEmails() in commo_test.go for a full working example. +*/ package commo import ( diff --git a/commo/commo_test.go b/commo_test.go similarity index 99% rename from commo/commo_test.go rename to commo_test.go index 880a992..53772e5 100644 --- a/commo/commo_test.go +++ b/commo_test.go @@ -12,7 +12,7 @@ import ( "github.com/joho/godotenv" "github.com/rotationalio/confire" "github.com/stretchr/testify/require" - "go.rtnl.ai/commo/commo" + "go.rtnl.ai/commo" ) func TestLiveEmails(t *testing.T) { diff --git a/commo/config.go b/config.go similarity index 100% rename from commo/config.go rename to config.go diff --git a/commo/config_test.go b/config_test.go similarity index 99% rename from commo/config_test.go rename to config_test.go index b366280..42d3aad 100644 --- a/commo/config_test.go +++ b/config_test.go @@ -7,7 +7,7 @@ import ( "github.com/rotationalio/confire" "github.com/stretchr/testify/require" - "go.rtnl.ai/commo/commo" + "go.rtnl.ai/commo" ) var testEnv = map[string]string{ diff --git a/commo/email.go b/email.go similarity index 100% rename from commo/email.go rename to email.go diff --git a/commo/email_test.go b/email_test.go similarity index 98% rename from commo/email_test.go rename to email_test.go index 7ccfdab..6d1b1e5 100644 --- a/commo/email_test.go +++ b/email_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "go.rtnl.ai/commo/commo" + "go.rtnl.ai/commo" ) func TestEmailValidate(t *testing.T) { diff --git a/commo/errors.go b/errors.go similarity index 100% rename from commo/errors.go rename to errors.go diff --git a/commo/render.go b/render.go similarity index 100% rename from commo/render.go rename to render.go diff --git a/commo/render_test.go b/render_test.go similarity index 97% rename from commo/render_test.go rename to render_test.go index ffdd097..7d83b1b 100644 --- a/commo/render_test.go +++ b/render_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/stretchr/testify/require" - "go.rtnl.ai/commo/commo" + "go.rtnl.ai/commo" ) func TestRender(t *testing.T) { diff --git a/commo/sendgrid.go b/sendgrid.go similarity index 100% rename from commo/sendgrid.go rename to sendgrid.go diff --git a/commo/sendgrid_test.go b/sendgrid_test.go similarity index 99% rename from commo/sendgrid_test.go rename to sendgrid_test.go index 94c2de1..acec51f 100644 --- a/commo/sendgrid_test.go +++ b/sendgrid_test.go @@ -5,7 +5,7 @@ import ( sgmail "github.com/sendgrid/sendgrid-go/helpers/mail" "github.com/stretchr/testify/require" - "go.rtnl.ai/commo/commo" + "go.rtnl.ai/commo" ) func TestNewSGEmail(t *testing.T) { diff --git a/commo/testdata/.env.template b/testdata/.env.template similarity index 100% rename from commo/testdata/.env.template rename to testdata/.env.template diff --git a/commo/testdata/templates/partials/base.html b/testdata/templates/partials/base.html similarity index 100% rename from commo/testdata/templates/partials/base.html rename to testdata/templates/partials/base.html diff --git a/commo/testdata/templates/partials/style.html b/testdata/templates/partials/style.html similarity index 100% rename from commo/testdata/templates/partials/style.html rename to testdata/templates/partials/style.html diff --git a/commo/testdata/templates/test_email.html b/testdata/templates/test_email.html similarity index 100% rename from commo/testdata/templates/test_email.html rename to testdata/templates/test_email.html diff --git a/commo/testdata/templates/test_email.txt b/testdata/templates/test_email.txt similarity index 100% rename from commo/testdata/templates/test_email.txt rename to testdata/templates/test_email.txt From 024f04a4de2555a09de650d59f17eb63450e24a5 Mon Sep 17 00:00:00 2001 From: Chris Okuda Date: Fri, 24 Oct 2025 06:54:24 -1000 Subject: [PATCH 2/3] add links --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 40ef88b..703b9ec 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ An email rendering and sending package that can be configured to use either SendGrid or SMTP. +* GitHub: +* Go Docs: + ## Usage First, add it to your module with `go get go.rtnl.ai/commo`. From 1d3bf7869d2da47f3e81ca4d533572bb4cf9d791 Mon Sep 17 00:00:00 2001 From: Chris Okuda Date: Fri, 24 Oct 2025 07:03:12 -1000 Subject: [PATCH 3/3] test the backoff configs --- config_test.go | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/config_test.go b/config_test.go index 42d3aad..8af3440 100644 --- a/config_test.go +++ b/config_test.go @@ -11,16 +11,20 @@ import ( ) var testEnv = map[string]string{ - "EMAIL_SENDER": "Jane Szack ", - "EMAIL_SENDER_NAME": "Jane Szack", - "EMAIL_TESTING": "true", - "EMAIL_SMTP_HOST": "smtp.example.com", - "EMAIL_SMTP_PORT": "25", - "EMAIL_SMTP_USERNAME": "jszack", - "EMAIL_SMTP_PASSWORD": "supersecret", - "EMAIL_SMTP_USE_CRAM_MD5": "true", - "EMAIL_SMTP_POOL_SIZE": "16", - "EMAIL_SENDGRID_API_KEY": "sg:fakeapikey", + "EMAIL_SENDER": "Jane Szack ", + "EMAIL_SENDER_NAME": "Jane Szack", + "EMAIL_TESTING": "true", + "EMAIL_SMTP_HOST": "smtp.example.com", + "EMAIL_SMTP_PORT": "25", + "EMAIL_SMTP_USERNAME": "jszack", + "EMAIL_SMTP_PASSWORD": "supersecret", + "EMAIL_SMTP_USE_CRAM_MD5": "true", + "EMAIL_SMTP_POOL_SIZE": "16", + "EMAIL_SENDGRID_API_KEY": "sg:fakeapikey", + "EMAIL_BACKOFF_TIMEOUT": "1s", + "EMAIL_BACKOFF_INITIAL_INTERVAL": "1s", + "EMAIL_BACKOFF_MAX_INTERVAL": "1s", + "EMAIL_BACKOFF_MAX_ELAPSED_TIME": "1s", } func TestConfig(t *testing.T) { @@ -41,6 +45,18 @@ func TestConfig(t *testing.T) { require.Equal(t, 16, conf.SMTP.PoolSize) require.Equal(t, testEnv["EMAIL_SENDGRID_API_KEY"], conf.SendGrid.APIKey) require.NoError(t, err, "could not process configuration from the environment") + dur, err := time.ParseDuration(testEnv["EMAIL_BACKOFF_TIMEOUT"]) + require.NoError(t, err) + require.Equal(t, dur, conf.Backoff.Timeout) + dur, err = time.ParseDuration(testEnv["EMAIL_BACKOFF_INITIAL_INTERVAL"]) + require.NoError(t, err) + require.Equal(t, dur, conf.Backoff.InitialInterval) + dur, err = time.ParseDuration(testEnv["EMAIL_BACKOFF_MAX_INTERVAL"]) + require.NoError(t, err) + require.Equal(t, dur, conf.Backoff.MaxInterval) + dur, err = time.ParseDuration(testEnv["EMAIL_BACKOFF_MAX_ELAPSED_TIME"]) + require.NoError(t, err) + require.Equal(t, dur, conf.Backoff.MaxElapsedTime) } func TestConfigAvailable(t *testing.T) {