emails

package
v0.3.2 Latest Latest
Warning

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

Go to latest
Published: Feb 21, 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"
)

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 added in v0.2.6

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 EmailData) (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 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
	SendGridAPIKey string `split_words:"true" required:"false"`
	// FromEmail is the default email we'll send from and is safe to configure by default as our emails and domain are signed
	FromEmail string `split_words:"true" default:"no-reply@datum.net"`
	// Testing is a bool flag to indicate we shouldn't be sending live emails and defaults to true so needs to be specifically changed to send live emails
	Testing bool `split_words:"true" default:"true"`
	// Archive is only supported in testing mode and is what is tied through the mock to write out fixtures
	Archive string `split_words:"true" default:""`
	// DatumListID is the UUID sendgrid spits out when you create marketing lists
	DatumListID string `split_words:"true" required:"false" default:"f5459563-8a46-44ef-9066-e96124d30e52"`
	// AdminEmail is an internal group email configured within datum for email testing and visibility
	AdminEmail string `split_words:"true" default:"admins@datum.net"`
}

Config is a struct for sending emails via SendGrid and managing marketing contacts

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 {
	URLConfig
	// 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 added in v0.2.6

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

AdminContact parses the AdminEmail and returns a sendgrid contact

func (*EmailManager) Enabled added in v0.2.6

func (m *EmailManager) Enabled() bool

Enabled returns true if there is a SendGrid API key available

func (*EmailManager) FromContact added in v0.2.6

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

FromContact parses the FromEmail and returns a sendgrid contact

func (*EmailManager) GetAdminEmail added in v0.2.6

func (m *EmailManager) GetAdminEmail() string

GetAdminEmail from the email manager config

func (*EmailManager) GetArchive added in v0.2.6

func (m *EmailManager) GetArchive() string

GetArchive from the email manager config

func (*EmailManager) GetDatumListID added in v0.2.6

func (m *EmailManager) GetDatumListID() string

GetDatumListID from the email manager config

func (*EmailManager) GetFromEmail added in v0.2.6

func (m *EmailManager) GetFromEmail() string

GetFromEmail from the email manager config

func (*EmailManager) GetSendGridAPIKey added in v0.2.6

func (m *EmailManager) GetSendGridAPIKey() string

GetSendGridAPIKey from the email manager config

func (*EmailManager) GetTesting added in v0.2.6

func (m *EmailManager) GetTesting() bool

GetTesting from the email manager config

func (*EmailManager) MustAdminContact added in v0.2.6

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 added in v0.2.6

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) Send

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

func (*EmailManager) SendAddedtoOrgEmail added in v0.2.6

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

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

func (*EmailManager) SendOrgInvitationEmail added in v0.2.6

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

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

func (*EmailManager) SetAdminEmail added in v0.2.6

func (m *EmailManager) SetAdminEmail(email string)

SetAdminEmail to provided email

func (*EmailManager) SetArchive added in v0.2.6

func (m *EmailManager) SetArchive(archive string)

SetArchive location of email fixtures

func (*EmailManager) SetDatumListID added in v0.2.6

func (m *EmailManager) SetDatumListID(id string)

SetDatumListID to provided uuid

func (*EmailManager) SetFromEmail added in v0.2.6

func (m *EmailManager) SetFromEmail(email string)

SetFromEmail to provided email

func (*EmailManager) SetSendGridAPIKey added in v0.2.6

func (m *EmailManager) SetSendGridAPIKey(key string)

SetSendGridAPIKey to provided key

func (*EmailManager) SetTesting added in v0.2.6

func (m *EmailManager) SetTesting(testing bool)

SetTesting to true/false to enable testing settings

func (*EmailManager) Validate added in v0.2.6

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

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

type InvalidEmailConfigError added in v0.2.6

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

InvalidEmailConfigError is returned when an invalid url configuration was provided

func (*InvalidEmailConfigError) Error added in v0.2.6

func (e *InvalidEmailConfigError) Error() string

Error returns the InvalidEmailConfigError in string format

type Invite added in v0.2.6

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 MissingRequiredFieldError added in v0.2.6

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 added in v0.2.6

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 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 URLConfig added in v0.2.6

type URLConfig struct {
	Base   string `split_words:"true" default:"https://api.datum.net"`
	Verify string `split_words:"true" default:"/v1/verify"`
	Invite string `split_words:"true" default:"/v1/invite"`
	Reset  string `split_words:"true" default:"/v1/password-reset"`
}

URLConfig for the datum registration

func (URLConfig) InviteURL added in v0.2.6

func (c URLConfig) InviteURL(token string) (string, error)

InviteURL Construct an invite URL from the token.

func (URLConfig) ResetURL added in v0.2.6

func (c URLConfig) ResetURL(token string) (string, error)

ResetURL constructs a reset URL from the token.

func (URLConfig) Validate added in v0.2.6

func (c URLConfig) Validate() error

func (URLConfig) VerifyURL added in v0.2.6

func (c URLConfig) VerifyURL(token string) (string, error)

VerifyURL constructs a verify URL from the token.

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