emails

package
v0.4.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 25, 2024 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package emails contains all of the logic and templating for sending emails within the datum services - it is built to allow for other email providers other than sendgrid if required but is mostly specific to sendgrid as that's our email provider of choice.

Index

Constants

View Source
const (
	UnknownDate = "unknown date"
	DateFormat  = "Monday, January 27, 1987"
)
View Source
const (
	WelcomeRE              = "Welcome to Datum!"
	VerifyEmailRE          = "Please verify your email address to login to Datum"
	InviteRE               = "Join Your Teammate %s on Datum!"
	PasswordResetRequestRE = "Datum Password Reset - Action Required"
	PasswordResetSuccessRE = "Datum Password Reset Confirmation"
	InviteBeenAccepted     = "You've been added to an Organization on Datum"
	Subscribed             = "You've been subscribed to %s"
)

Email subject lines

Variables

View Source
var (
	// ErrMissingSubject is returned when the email is missing a subject
	ErrMissingSubject = errors.New("missing email subject")

	// ErrMissingSender is returned when the email sender field is missing
	ErrMissingSender = errors.New("missing email sender")

	// ErrMissingRecipient is returned when the email recipient is missing
	ErrMissingRecipient = errors.New("missing email recipient")

	// ErrEmailUnparseable is returned when an email address could not be parsed
	ErrEmailUnparseable = errors.New("could not parse email address")

	// ErrSendgridNotEnabled is returned when no sendgrid API key is present
	ErrSendgridNotEnabled = errors.New("sendgrid is not enabled, cannot add contact")

	// ErrFailedToCreateEmailClient is returned when the client cannot instantiate due to a missing API key
	ErrFailedToCreateEmailClient = errors.New("cannot create email client without API key")

	// ErrEmailArchiveOnlyInTestMode is returned when Archive is enabled but Testing mode is not enabled
	ErrEmailArchiveOnlyInTestMode = errors.New("invalid configuration: email archiving is only supported in testing mode")

	// ErrEmailNotParseable
	ErrEmailNotParseable = errors.New("invalid configuration: from email is unparsable")

	// ErrAdminEmailNotParseable
	ErrAdminEmailNotParseable = errors.New("invalid configuration: admin email is unparsable")

	// ErrBothAdminAndFromRequired
	ErrBothAdminAndFromRequired = errors.New("invalid configuration: admin and from emails are required if sendgrid is enabled")
)

Functions

func AttachCSV

func AttachCSV(message *mail.SGMailV3, data []byte, filename string) (err error)

AttachCSV by encoding the csv data and attaching it to the email as a file - we don't have any CSV usecases today but likely will be generating reports and emailing them at some point in the future so adding it now

func AttachData

func AttachData(message *mail.SGMailV3, data []byte, filename, mimetype string) error

AttachData onto an email as a file with the specified mimetype

func AttachJSON

func AttachJSON(message *mail.SGMailV3, data []byte, filename string) (err error)

AttachJSON by marshaling the specified data into human-readable data and encode and attach it to the email as a file

func InviteAccepted

func InviteAccepted(data InviteData) (message *mail.SGMailV3, err error)

InviteAccepted creates an email to invite a user to join an organization

func InviteEmail

func InviteEmail(data InviteData) (message *mail.SGMailV3, err error)

InviteEmail creates an email to invite a user to join an organization

func LoadAttachment

func LoadAttachment(message *mail.SGMailV3, attachmentPath string) (err error)

LoadAttachment onto email from a file on disk - the intent here was the most "common types" we could envision sending out of the system rather than support every file type under the sun

func PasswordResetRequestEmail

func PasswordResetRequestEmail(data ResetRequestData) (message *mail.SGMailV3, err error)

PasswordResetRequestEmail creates a password reset email

func PasswordResetSuccessEmail

func PasswordResetSuccessEmail(data ResetSuccessData) (message *mail.SGMailV3, err error)

PasswordResetSuccessEmail creates an email to send to users once their password has been reset

func Render

func Render(name string, data interface{}) (text, html string, err error)

Render returns the text and html executed templates for the specified name and data - while Sendgrid does have "rich" templates that could have been used instead, it seemed better not to explicitly reference SG ID's specific to Datum's account wherever possible so these files are rendered exports of templates created within that system and can be customized to suite purpose

func SubscribeEmail added in v0.3.6

func SubscribeEmail(data SubscriberEmailData) (message *mail.SGMailV3, err error)

SubscribeEmail creates a subscribe email for a new subscriber

func VerifyEmail

func VerifyEmail(data VerifyEmailData) (message *mail.SGMailV3, err error)

VerifyEmail creates an email to verify a user's email address

func WelcomeEmail

func WelcomeEmail(data WelcomeData) (message *mail.SGMailV3, err error)

WelcomeEmail creates a welcome email for a new user

Types

type Config

type Config struct {
	// SendGridAPIKey is the SendGrid API key to authenticate with the service
	SendGridAPIKey string `json:"sendGridApiKey" koanf:"sendGridApiKey"`
	// FromEmail is the default email to send from
	FromEmail string `json:"fromEmail" koanf:"fromEmail" default:"no-reply@datum.net"`
	// Testing is a bool flag to indicate we shouldn't be sending live emails, and instead should be writing out fixtures
	Testing bool `json:"testing" koanf:"testing" default:"true"`
	// Archive is only supported in testing mode and is what is tied through the mock to write out fixtures
	Archive string `json:"archive" koanf:"archive" `
	// DatumListID is the UUID SendGrid spits out when you create marketing lists
	DatumListID string `json:"datumListId" koanf:"datumListId"`
	// AdminEmail is an internal group email configured within datum for email testing and visibility
	AdminEmail string `json:"adminEmail" koanf:"adminEmail" default:"admins@datum.net"`
	// ConsoleURLConfig is the configuration for the URLs used in emails
	ConsoleURLConfig ConsoleURLConfig `json:"consoleUrl" koanf:"consoleUrl"`
	// MarketingURLConfig is the configuration for the URLs used in marketing emails
	MarketingURLConfig MarketingURLConfig `json:"marketingUrl" koanf:"marketingUrl"`
}

Config for sending emails via SendGrid and managing marketing contacts

type ConsoleURLConfig added in v0.4.0

type ConsoleURLConfig struct {
	// ConsoleBase is the base URL used for URL links in emails
	ConsoleBase string `json:"consoleBase" koanf:"consoleBase" default:"https://console.datum.net"`
	// Verify is the path to the verify endpoint used in verification emails
	Verify string `json:"verify" koanf:"verify" default:"/verify"`
	// Invite is the path to the invite endpoint used in invite emails
	Invite string `json:"invite" koanf:"invite" default:"/invite"`
	// Reset is the path to the reset endpoint used in password reset emails
	Reset string `json:"reset" koanf:"reset" default:"/password-reset"`
}

ConsoleURLConfig for the datum registration

func (ConsoleURLConfig) Validate added in v0.4.0

func (c ConsoleURLConfig) Validate() error

type EmailData

type EmailData struct {
	Subject   string           `json:"-"`
	Sender    sendgrid.Contact `json:"-"`
	Recipient sendgrid.Contact `json:"-"`
}

EmailData includes data fields that are common to all the email builders

func (EmailData) Build

func (e EmailData) Build(text, html string) (msg *mail.SGMailV3, err error)

Build creates a new email from pre-rendered templates

func (EmailData) Validate

func (e EmailData) Validate() error

Validate that all required data is present to assemble a sendable email

type EmailManager

type EmailManager struct {
	ConsoleURLConfig
	MarketingURLConfig
	// contains filtered or unexported fields
}

EmailManager allows a server to send rich emails using the SendGrid service

func New

func New(conf Config) (m *EmailManager, err error)

New email manager with the specified configuration

func (*EmailManager) AddContact

func (m *EmailManager) AddContact(contact *sg.Contact, listIDs ...string) (err error)

AddContact adds a contact to SendGrid, adding them to the Datum signup marketing list if it is configured. This is an upsert operation so existing contacts will be updated. The caller can optionally specify additional lists that the contact should be added to. If no lists are configured or specified, then the contact is added or updated in SendGrid but is not added to any marketing lists - the intent of this is to track within Sendgrid the signups and track PLG-related stuff

func (*EmailManager) AdminContact

func (m *EmailManager) AdminContact() (sendgrid.Contact, error)

AdminContact parses the AdminEmail and returns a sendgrid contact

func (*EmailManager) Enabled

func (m *EmailManager) Enabled() bool

Enabled returns true if there is a SendGrid API key available

func (*EmailManager) FromContact

func (m *EmailManager) FromContact() (sendgrid.Contact, error)

FromContact parses the FromEmail and returns a sendgrid contact

func (*EmailManager) GetAdminEmail

func (m *EmailManager) GetAdminEmail() string

GetAdminEmail from the email manager config

func (*EmailManager) GetArchive

func (m *EmailManager) GetArchive() string

GetArchive from the email manager config

func (*EmailManager) GetDatumListID

func (m *EmailManager) GetDatumListID() string

GetDatumListID from the email manager config

func (*EmailManager) GetFromEmail

func (m *EmailManager) GetFromEmail() string

GetFromEmail from the email manager config

func (*EmailManager) GetSendGridAPIKey

func (m *EmailManager) GetSendGridAPIKey() string

GetSendGridAPIKey from the email manager config

func (*EmailManager) GetTesting

func (m *EmailManager) GetTesting() bool

GetTesting from the email manager config

func (*EmailManager) InviteURL added in v0.4.0

func (m *EmailManager) InviteURL(token string) (string, error)

InviteURL Construct an invite URL from the token.

func (*EmailManager) MustAdminContact

func (m *EmailManager) MustAdminContact() sendgrid.Contact

MustAdminContact is a helper function that returns the `sendgrid.Contact` for the `AdminEmail` field in the `Config` struct. It first calls the `AdminContact` function to parse the `AdminEmail` and return a `sendgrid.Contact`. If there is an error parsing the email, it will panic and throw an error. Otherwise, it will return the parsed `sendgrid.Contact`

func (*EmailManager) MustFromContact

func (m *EmailManager) MustFromContact() sendgrid.Contact

MustFromContact function is a helper function that returns the `sendgrid.Contact` for the `FromEmail` field in the `Config` struct

func (*EmailManager) ResetURL added in v0.4.0

func (m *EmailManager) ResetURL(token string) (string, error)

ResetURL constructs a reset URL from the token.

func (*EmailManager) Send

func (m *EmailManager) Send(message *sgmail.SGMailV3) (err error)

func (*EmailManager) SendAddedtoOrgEmail

func (m *EmailManager) SendAddedtoOrgEmail(i *Invite) error

SendAddedtoOrgEmail sends an email notifying the user they've been added to an org

func (*EmailManager) SendOrgInvitationEmail

func (m *EmailManager) SendOrgInvitationEmail(i *Invite) error

SendOrgInvitationEmail sends an email inviting a user to join Datum and an existing organization

func (*EmailManager) SetAdminEmail

func (m *EmailManager) SetAdminEmail(email string)

SetAdminEmail to provided email

func (*EmailManager) SetArchive

func (m *EmailManager) SetArchive(archive string)

SetArchive location of email fixtures

func (*EmailManager) SetDatumListID

func (m *EmailManager) SetDatumListID(id string)

SetDatumListID to provided uuid

func (*EmailManager) SetFromEmail

func (m *EmailManager) SetFromEmail(email string)

SetFromEmail to provided email

func (*EmailManager) SetSendGridAPIKey

func (m *EmailManager) SetSendGridAPIKey(key string)

SetSendGridAPIKey to provided key

func (*EmailManager) SetTesting

func (m *EmailManager) SetTesting(testing bool)

SetTesting to true/false to enable testing settings

func (*EmailManager) SubscriberVerifyURL added in v0.4.0

func (m *EmailManager) SubscriberVerifyURL(token string) (string, error)

SubscriberVerifyURL constructs a verify URL from the token.

func (*EmailManager) Validate

func (m *EmailManager) Validate() (err error)

Validate the from and admin emails are present if the SendGrid API is enabled

func (*EmailManager) VerifyURL added in v0.4.0

func (m *EmailManager) VerifyURL(token string) (string, error)

VerifyURL constructs a verify URL from the token.

type InvalidEmailConfigError

type InvalidEmailConfigError struct {
	// RequiredField that is missing
	RequiredField string
}

InvalidEmailConfigError is returned when an invalid url configuration was provided

func (*InvalidEmailConfigError) Error

func (e *InvalidEmailConfigError) Error() string

Error returns the InvalidEmailConfigError in string format

type Invite

type Invite struct {
	Token     string
	OrgName   string
	Recipient string
	Requestor string
	Role      string
}

Invite data is used to hold temporary constructor information to compose the invite email

type InviteData

type InviteData struct {
	EmailData
	Email       string
	InviterName string
	OrgName     string
	Role        string
	InviteURL   string
}

InviteData is used to complete the invite email template

type MarketingURLConfig added in v0.4.0

type MarketingURLConfig struct {
	// MarketingBase is the base URL used for marketing links in emails
	MarketingBase string `json:"marketingBase" koanf:"marketingBase" default:"https://www.datum.net"`
	// SubscriberVerify is the path to the subscriber verify endpoint used in verification emails
	SubscriberVerify string `json:"subscriberVerify" koanf:"subscriberVerify" default:"/verify"`
	// DefaultSubscriptionOrg is the default organization name to subscribe to
	DefaultSubscriptionOrg string `json:"defaultSubscriptionOrg" koanf:"defaultSubscriptionOrg" default:"Datum"`
}

MarketingURLConfig for the datum marketing emails

func (MarketingURLConfig) Validate added in v0.4.0

func (c MarketingURLConfig) Validate() error

type MissingRequiredFieldError

type MissingRequiredFieldError struct {
	// RequiredField that is missing
	RequiredField string
}

MissingRequiredFieldError is returned when a required field was not provided in a request

func (*MissingRequiredFieldError) Error

func (e *MissingRequiredFieldError) Error() string

Error returns the InvalidEmailConfigError in string format

type ResetRequestData

type ResetRequestData struct {
	EmailData
	ResetURL string
}

ResetRequestData is used to complete the password reset request email template

type ResetSuccessData added in v0.4.0

type ResetSuccessData struct {
	EmailData
}

ResetSuccessData is used to complete the password success request email template

type SendGridClient

type SendGridClient interface {
	Send(email *sgmail.SGMailV3) (*rest.Response, error)
}

SendGridClient is an interface that can be implemented by live email clients to send real emails or by mock clients for testing

type SubscriberEmailData added in v0.3.6

type SubscriberEmailData struct {
	EmailData
	VerifySubscriberURL string
	OrgName             string
}

SubscriberEmailData is used to complete the subscriber email template

type VerifyEmailData

type VerifyEmailData struct {
	EmailData
	FullName  string
	VerifyURL string
}

VerifyEmailData is used to complete the verify email template

type WelcomeData

type WelcomeData struct {
	EmailData
	FirstName    string
	LastName     string
	Email        string
	Organization string
	Domain       string
}

WelcomeData is used to complete the welcome email template

Directories

Path Synopsis
Package mock provides intermediary data structures to assist in testing and debugging sending an email without actually sending the email - testing the creation and sending of email typically requires some kind of tracking of what was sent or not and metadata about the message which is what is setup here
Package mock provides intermediary data structures to assist in testing and debugging sending an email without actually sending the email - testing the creation and sending of email typically requires some kind of tracking of what was sent or not and metadata about the message which is what is setup here

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL