Email Service

Email Service

BizTech uses Amazon SES for all transactional email — registration confirmations, QR codes, calendar invites, and admin-managed templates.


Two Email Systems

BizTech has two distinct email paths:

1. Transactional Emails (Registration Flow)

Sent automatically during event registration. These are not managed through the email templates service — they are hardcoded in the registration pipeline.

Sent by: services/registrations/handler.jsupdateHelper()SESEmailService

Email typeSent whenContents
QR code emailRegistration status is registered, waitlist, or acceptedCompleteInline QR code image + event details
Calendar inviteSame as above.ics file attachment for the event

Not sent for: incomplete, rejected, accepted, checkedIn, or partner registrations (isPartner: true).

The SESEmailService class in services/registrations/helpers/SESEmailService.js has two methods:

  • sendDynamicQR(registrationData) — generates a QR code containing the attendee's email and event ID, embeds it as an inline image
  • sendCalendarInvite(registrationData) — builds an .ics calendar file with the event's start/end times, attaches it to the email

2. Email Templates (Admin CRUD)

A separate service for managing reusable SES email templates. Admins can create, edit, and list templates for ad-hoc email campaigns.

Handler: services/emails/handler.js Auth: All endpoints require Cognito (admin-only — @ubcbiztech.com email check)

MethodPathHandlerDescription
GET/email/getEmailTemplateGet a single template by name
GET/email/listlistEmailTemplatesList all SES templates (paginated)
POST/email/createEmailTemplateCreate a new SES template
PATCH/email/{templateName}updateEmailTemplateUpdate an existing template
DELETE/email/{templateName}deleteEmailTemplateDelete a template

These endpoints are thin wrappers around the AWS SES API:

  • createEmailTemplateses.createTemplate()
  • updateEmailTemplateses.updateTemplate()
  • deleteEmailTemplateses.deleteTemplate()
  • getEmailTemplateses.getTemplate()
  • listEmailTemplatesses.listTemplates() with optional NextToken for pagination

No DynamoDB tables are involved — templates are stored entirely in SES.


Partnerships Mass Email

The partnerships CRM has its own email system for sending bulk emails to sponsor contacts. This is separate from both the registration emails and the email template service.

Handler: services/partnerships/handler.js Endpoints:

MethodPathDescription
GET/partnerships/email/configGet email configuration
GET/partnerships/email/templatesList partnership email templates
POST/partnerships/email/templatesCreate partnership email template
PATCH/partnerships/email/templates/{templateId}Update template
DELETE/partnerships/email/templates/{templateId}Delete template
POST/partnerships/email/sendSend bulk emails (120s timeout)

Partnership email templates support variable substitution (e.g., {{companyName}}, {{contactName}}).


SNS Notifications

Besides email, the registration flow also publishes notifications to SNS, which are delivered to Slack:

// services/registrations/handler.js → updateHelper()
await snsHelper.publish(message, topicArn)

This sends a Slack notification to organizers whenever someone registers or gets waitlisted.


SES Configuration

SES email sending is configured in the service's serverless.yml IAM permissions:

iamRoleStatements:
  - Effect: Allow
    Action:
      - ses:SendEmail
      - ses:SendRawEmail
    Resource: 'arn:aws:ses:us-west-2:*:identity/*'

The ses:SendRawEmail permission is needed for the calendar invite attachment (raw MIME email).


Key Files

FilePurpose
services/emails/handler.jsEmail template CRUD endpoints
services/registrations/helpers/SESEmailService.jsQR code + calendar invite email sending
lib/sesHelper.jsSES client wrapper
lib/sesV2Client.jsSES v2 client initialization
lib/snsHelper.jsSNS notification publishing
services/partnerships/handler.jsPartnership mass email endpoints

Previous
Overview