Documentation ¶
Overview ¶
Package emails contains all of the logic and templating for sending emails 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
- Variables
- func AttachCSV(message *mail.SGMailV3, data []byte, filename string) (err error)
- func AttachData(message *mail.SGMailV3, data []byte, filename, mimetype string) error
- func AttachJSON(message *mail.SGMailV3, data []byte, filename string) (err error)
- func InviteAccepted(data InviteData) (message *mail.SGMailV3, err error)
- func InviteEmail(data InviteData) (message *mail.SGMailV3, err error)
- func LoadAttachment(message *mail.SGMailV3, attachmentPath string) (err error)
- func PasswordResetRequestEmail(data ResetRequestData) (message *mail.SGMailV3, err error)
- func PasswordResetSuccessEmail(data ResetSuccessData) (message *mail.SGMailV3, err error)
- func Render(name string, data interface{}) (text, html string, err error)
- func SubscribeEmail(data SubscriberEmailData) (message *mail.SGMailV3, err error)
- func VerifyEmail(data VerifyEmailData) (message *mail.SGMailV3, err error)
- func WelcomeEmail(data WelcomeData) (message *mail.SGMailV3, err error)
- type Config
- type ConsoleURLConfig
- type EmailData
- type EmailManager
- func (m *EmailManager) AddContact(contact *sendgrid.Contact, listIDs ...string) (err error)
- func (m *EmailManager) AdminContact() (sendgrid.Contact, error)
- func (m *EmailManager) Enabled() bool
- func (m *EmailManager) FromContact() (sendgrid.Contact, error)
- func (m *EmailManager) GetAdminEmail() string
- func (m *EmailManager) GetArchive() string
- func (m *EmailManager) GetFromEmail() string
- func (m *EmailManager) GetListID() string
- func (m *EmailManager) GetSendGridAPIKey() string
- func (m *EmailManager) GetTesting() bool
- func (m *EmailManager) InviteURL(token string) (string, error)
- func (m *EmailManager) MustAdminContact() sendgrid.Contact
- func (m *EmailManager) MustFromContact() sendgrid.Contact
- func (m *EmailManager) ResetURL(token string) (string, error)
- func (m *EmailManager) Send(message *sgmail.SGMailV3) (err error)
- func (m *EmailManager) SendAddedToOrgEmail(i *Invite) error
- func (m *EmailManager) SendOrgInvitationEmail(i *Invite) error
- func (m *EmailManager) SetAdminEmail(email string)
- func (m *EmailManager) SetArchive(archive string)
- func (m *EmailManager) SetFromEmail(email string)
- func (m *EmailManager) SetListID(id string)
- func (m *EmailManager) SetSendGridAPIKey(key string)
- func (m *EmailManager) SetTesting(testing bool)
- func (m *EmailManager) SubscriberVerifyURL(token string) (string, error)
- func (m *EmailManager) Validate() (err error)
- func (m *EmailManager) VerifyURL(token string) (string, error)
- type InvalidEmailConfigError
- type Invite
- type InviteData
- type MarketingURLConfig
- type MissingRequiredFieldError
- type ResetRequestData
- type ResetSuccessData
- type SendGridClient
- type SubscriberEmailData
- type VerifyEmailData
- type WelcomeData
Constants ¶
const ( UnknownDate = "unknown date" DateFormat = "Monday, January 27, 1987" )
const ( WelcomeRE = "Welcome to openlane!" VerifyEmailRE = "Please verify your email address to login to openlane" InviteRE = "Join Your Teammate %s on openlane!" PasswordResetRequestRE = "Openlane Password Reset - Action Required" PasswordResetSuccessRE = "Openlane Password Reset Confirmation" InviteBeenAccepted = "You've been added to an Organization on openlane" Subscribed = "You've been subscribed to %s" )
Email subject lines
Variables ¶
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") // ErrEmailUnparsable is returned when an email address could not be parsed ErrEmailUnparsable = 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") // ErrEmailNotParsable ErrEmailNotParsable = errors.New("invalid configuration: from email is unparsable") // ErrAdminEmailNotParsable ErrAdminEmailNotParsable = 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 ¶
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 ¶
AttachData onto an email as a file with the specified mimetype
func AttachJSON ¶
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 ¶
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 ¶
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 the account wherever possible so these files are rendered exports of templates created within that system and can be customized to suite purpose
func SubscribeEmail ¶
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@theopenlane.io"` // 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" ` // ListID is the UUID SendGrid spits out when you create marketing lists ListID string `json:"listId" koanf:"listId"` // AdminEmail is an internal group email configured for email testing and visibility AdminEmail string `json:"adminEmail" koanf:"adminEmail" default:"admins@theopenlane.io"` // 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 ¶
type ConsoleURLConfig struct { // ConsoleBase is the base URL used for URL links in emails ConsoleBase string `json:"consoleBase" koanf:"consoleBase" default:"https://console.theopenlane.io"` // 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 registration
func (ConsoleURLConfig) Validate ¶
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
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 *sendgrid.Contact, listIDs ...string) (err error)
AddContact adds a contact to SendGrid, adding them to the sign-up 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 sign-ups 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) GetFromEmail ¶
func (m *EmailManager) GetFromEmail() string
GetFromEmail from the email manager config
func (*EmailManager) GetListID ¶
func (m *EmailManager) GetListID() string
GetListID 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 ¶
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 ¶
func (m *EmailManager) ResetURL(token string) (string, error)
ResetURL constructs a reset URL from the token.
func (*EmailManager) SendAddedToOrgEmail ¶
func (m *EmailManager) SendAddedToOrgEmail(i *Invite) error
SendAddedToOrgEmail sends an email notifying the user they've been added to an organization
func (*EmailManager) SendOrgInvitationEmail ¶
func (m *EmailManager) SendOrgInvitationEmail(i *Invite) error
SendOrgInvitationEmail sends an email inviting a user to join 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) SetFromEmail ¶
func (m *EmailManager) SetFromEmail(email string)
SetFromEmail to provided email
func (*EmailManager) SetListID ¶
func (m *EmailManager) SetListID(id string)
SetListID to provided uuid
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 ¶
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
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 ¶
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 ¶
type MarketingURLConfig struct { // MarketingBase is the base URL used for marketing links in emails MarketingBase string `json:"marketingBase" koanf:"marketingBase" default:"https://www.theopenlane.io"` // SubscriberVerify is the path to the subscriber verify endpoint used in verification emails SubscriberVerify string `json:"subscriberVerify" koanf:"subscriberVerify" default:"/verify"` }
MarketingURLConfig for the marketing emails
func (MarketingURLConfig) Validate ¶
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 ¶
ResetRequestData is used to complete the password reset request email template
type ResetSuccessData ¶
type ResetSuccessData struct {
EmailData
}
ResetSuccessData is used to complete the password success request email template
type SendGridClient ¶
SendGridClient is an interface that can be implemented by live email clients to send real emails or by mock clients for testing
type SubscriberEmailData ¶
SubscriberEmailData is used to complete the subscriber email template
type VerifyEmailData ¶
VerifyEmailData is used to complete the verify email template
Source Files ¶
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 |