Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@

An email rendering and sending package that can be configured to use either SendGrid or SMTP.

* GitHub: <https://github.com/rotationalio/commo>
* Go Docs: <https://go.rtnl.ai/commo>

## 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)
Expand All @@ -30,4 +37,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 <https://en.wikipedia.org/wiki/Communications_officer> for information on why this library is named "COMMO".
31 changes: 31 additions & 0 deletions commo/commo.go → commo.go
Original file line number Diff line number Diff line change
@@ -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 <test@example.com>", "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 (
Expand Down
2 changes: 1 addition & 1 deletion commo/commo_test.go → commo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
File renamed without changes.
38 changes: 27 additions & 11 deletions commo/config_test.go → config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,24 @@ import (

"github.com/rotationalio/confire"
"github.com/stretchr/testify/require"
"go.rtnl.ai/commo/commo"
"go.rtnl.ai/commo"
)

var testEnv = map[string]string{
"EMAIL_SENDER": "Jane Szack <jane@example.com>",
"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 <jane@example.com>",
"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) {
Expand All @@ -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) {
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion commo/email_test.go → email_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion commo/render_test.go → render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion commo/sendgrid_test.go → sendgrid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
File renamed without changes.
Loading