emails

package
v0.2.4 Latest Latest
Warning

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

Go to latest
Published: Jan 9, 2024 License: Apache-2.0 Imports: 19 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"
)

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 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:"false"`
	// 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:"fixtures/emails"`
	// 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

func (Config) AdminContact

func (c Config) AdminContact() (sendgrid.Contact, error)

AdminContact parses the AdminEmail and returns a sendgrid contact

func (*Config) Enabled

func (c *Config) Enabled() bool

Enabled returns true if there is a SendGrid API key available

func (*Config) FromContact

func (c *Config) FromContact() (sendgrid.Contact, error)

FromContact parses the FromEmail and returns a sendgrid contact

func (*Config) MustAdminContact

func (c *Config) 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 (*Config) MustFromContact

func (c *Config) MustFromContact() sendgrid.Contact

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

func (*Config) Validate

func (c *Config) Validate() (err error)

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

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

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

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