Overdue Notifications
Feature Development Plan
The core of this new feature is:If a user hasn't checked out by their expectedCheckOutTimestamp
, the system should automatically send an SMS and an email to their selected emergency contact. These notifications should include details about the trip and any notes from the check-in.
This is a critical safety feature and will primarily involve backend logic. Here's how we can break down its development:
This plan outlines the steps to implement automated notifications to emergency contacts for overdue check-ins.
Phase 1: Backend Foundation - Data Model & Lambda Function Setup
This phase focuses on preparing your AWS Amplify backend.
- Update
CheckInLog
GraphQL Schema:- To prevent sending duplicate notifications for the same overdue event, we need to add a flag to the
CheckInLog
model. - After saving the schema file, run
amplify codegen models
in your terminal to update your local Dart model files inlib/models/
.
- To prevent sending duplicate notifications for the same overdue event, we need to add a flag to the
- Create an AWS Lambda Function for Notifications:
- This serverless function will contain the core logic to identify overdue check-ins and dispatch notifications.
- Action: In your project root directory, run the command
amplify add function
.- Function type: Choose "Lambda function (serverless function)".
- Name: Give it a descriptive name, for example,
overdueCheckinNotifier
. - Runtime: Select Node.js (as it has robust AWS SDK support and many examples are available) or Python if you prefer.
- Template: You can start with a basic "Hello World" template and modify it.
- Advanced settings / Resource access:
- When prompted if you want to configure advanced settings, choose yes.
- When asked if you want to access other Amplify resources, choose yes.
- Select the API (GraphQL) category.
- Choose your existing GraphQL API.
- Grant permissions for the Lambda function to perform the following operations on these models:
CheckInLog
: Query (to find overdue check-ins) and Update (to set theisOverdueNotified
flag).Trip
: Query (to get trip details like name and destination).EmergencyContact
: Query (to get the contact's phone number and email).Profile
: Query (to get the name of the user who is on the trip).
- You can skip Lambda layers for now unless you have specific shared code.
- Environment variables can be configured later if needed (e.g., for a default sender email address for SES).
- This setup will create a new directory structure for your Lambda function, typically under
amplify/backend/function/overdueCheckinNotifier/
.
Action: In your amplify/backend/api/<YOUR_API_NAME>/schema.graphql
file, add a new field isOverdueNotified: Boolean
to the CheckInLog
type.GraphQL
type CheckInLog @model @auth(rules: [{ allow: owner }]) {
# ... all your existing fields like id, tripID, expectedCheckOutTimestamp, notes, selectedEmergencyContactID ...
isOverdueNotified: Boolean # New field to track if notification has been sent
# ... createdAt, updatedAt ...
}
Phase 2: Lambda Function Logic - Identifying Overdue Check-ins & Fetching Necessary Data
This involves writing the code for the overdueCheckinNotifier
Lambda function.
- Location: The main code file will be something like
amplify/backend/function/overdueCheckinNotifier/src/index.js
(for Node.js) orapp.py
(for Python). - Core Logic:
- The Lambda function will be triggered periodically by a scheduler (detailed in Phase 4).
- Query for Overdue
CheckInLog
s:- The function will make a GraphQL query to your AppSync API.
- It needs to find
CheckInLog
records that meet these criteria:checkOutTimestamp
isnull
(meaning the user hasn't checked out).expectedCheckOutTimestamp
is in the past (i.e., less than the current time).isOverdueNotified
isfalse
ornull
(to ensure notifications are sent only once per overdue event).
- Iterate and Gather Details: For each overdue
CheckInLog
identified:- Use the
tripID
from theCheckInLog
to query theTrip
model and retrieve details liketripName
anddestination
. - Use the
selectedEmergencyContactID
from theCheckInLog
to query theEmergencyContact
model for the contact'sname
,phone
, andemail
. - Use the
owner
field (or a similar user identifier on theCheckInLog
orTrip
model, which usually corresponds to the user's Cognitosub
) to query theProfile
model and get the user'sfirstName
andlastName
.
- Use the
Phase 3: Lambda Function Logic - Sending SMS & Email Notifications
This continues within the same Lambda function, processing each overdue check-in.
- AWS SDK: You'll use the AWS SDK (for JavaScript or Python, depending on your Lambda runtime) to interact with SNS and SES.
- Send SMS via AWS SNS (Simple Notification Service):
- Permissions: The Lambda function's IAM execution role needs permission to publish to SNS (e.g.,
sns:Publish
). If Amplify didn't add this automatically when you granted API access, you'll need to add a custom policy to the Lambda's IAM role. This can often be done by modifying the function's CloudFormation template (e.g.,overdueCheckinNotifier-cloudformation-template.json
) or using acustom-policies.json
file if supported by your Amplify CLI version. - Logic:
- Check if the fetched emergency contact has a phone number.
- Construct the SMS message. It should be concise and include key information: user's name, that they are overdue, trip name, expected checkout time, and any notes from the check-in.
- Use the AWS SDK's SNS client to publish the SMS to the emergency contact's phone number. Ensure phone numbers are stored and used in the E.164 format (e.g.,
+12223334444
).
- Permissions: The Lambda function's IAM execution role needs permission to publish to SNS (e.g.,
- Send Email via AWS SES (Simple Email Service):
- Permissions: The Lambda's IAM role needs permission to send emails via SES (e.g.,
ses:SendEmail
orses:SendRawEmail
). Add this similarly to the SNS permission. - SES Setup (Important - Manual AWS Console Steps):
- Verify Sender Identity: In the AWS SES console (for the AWS region you're using for SES), you must verify an email address (e.g.,
alerts@your-app-domain.com
) or an entire domain. Emails can only originate from verified identities. - SES Sandbox: By default, SES accounts are in a "sandbox" environment, meaning you can only send emails to other email addresses that are also verified in your SES account. To send emails to any address (like your users' emergency contacts), you must request AWS to move your SES account out of the sandbox.
- Verify Sender Identity: In the AWS SES console (for the AWS region you're using for SES), you must verify an email address (e.g.,
- Logic:
- Check if the fetched emergency contact has an email address.
- Construct the email (subject and body). The body can be HTML or plain text and should include the user's name, trip name, destination, expected checkout time, check-in notes, and a clear message for the emergency contact.
- Use the AWS SDK's SES client to send the email from your verified sender identity.
- Permissions: The Lambda's IAM role needs permission to send emails via SES (e.g.,
- Update
CheckInLog
Record:- After successfully attempting to send both SMS and email (or whichever is applicable based on available contact info):
- The Lambda function must make a GraphQL mutation call back to your AppSync API to update the specific
CheckInLog
record. - Set the
isOverdueNotified
field totrue
. This is crucial to prevent sending repeated notifications for the same overdue check-in.
Example policy statement:JSON
{
"Effect": "Allow",
"Action": ["ses:SendEmail", "ses:SendRawEmail"],
"Resource": "*" // Scope this to specific verified identities if possible
}
Example policy statement:JSON
{
"Effect": "Allow",
"Action": ["sns:Publish"],
"Resource": "*" // It's better to scope this down if possible
}
Phase 4: Scheduling the Lambda Function
To automate the checking process, the Lambda function needs to be invoked periodically.
- Method: The recommended way is to use Amazon EventBridge Scheduler.
- Action:
- After you successfully deploy your Lambda function (via
amplify push
), log in to the AWS Management Console. - Navigate to Amazon EventBridge.
- In the EventBridge console, go to Schedules.
- Create a new schedule:
- Provide a Name (e.g.,
OverdueCheckinNotificationScheduler
). - Define the Schedule pattern. You can use a rate-based expression (e.g.,
rate(10 minutes)
,rate(30 minutes)
) or a cron expression for more specific timing. Consider the balance between responsiveness and cost/load. - For the Target, select "AWS Lambda".
- Choose your
overdueCheckinNotifier
Lambda function from the list. - The Input to the Lambda can usually be left as default for this use case.
- EventBridge will typically handle or guide you on setting up the necessary Permissions for it to invoke your Lambda function.
- Provide a Name (e.g.,
- After you successfully deploy your Lambda function (via
Phase 5: Implementation Details, Configuration & Deployment
This involves fleshing out the Lambda code, configuring services, and thorough testing.
- Lambda Code Implementation:
- Write the actual Node.js or Python code for the
overdueCheckinNotifier
Lambda.- Properly set up the AWS SDK clients for AppSync (to make GraphQL calls), SNS, and SES.
- Implement robust error handling and logging (e.g.,
console.log
statements in Node.js will appear in Amazon CloudWatch Logs, which is essential for debugging). - Carefully construct your GraphQL queries and mutations. For querying AppSync from a Lambda with IAM auth (which Amplify typically sets up), you'll need to sign your HTTP requests to the GraphQL endpoint.
- Write the actual Node.js or Python code for the
- Environment Variables for Lambda (Recommended):
- Consider setting environment variables for your Lambda function for values like:
SES_SENDER_EMAIL
: The verified email address you'll send notifications from.SES_REGION
: The AWS region where your SES identity is verified.
- These can be configured in the Lambda's settings in the AWS console or by modifying its CloudFormation template provided by Amplify.
- Consider setting environment variables for your Lambda function for values like:
- Local Mocking & Testing (Limited):
- While
amplify mock function <functionName>
can help with basic Lambda logic testing, fully testing SNS/SES integration and scheduled triggers usually requires deployment to a dev environment.
- While
- Deploy Backend Changes:
- Once the Lambda code is written and permissions are set up in the Amplify project, run
amplify push
. This will deploy the schema changes, the new Lambda function, its IAM role, and any related configurations.
- Once the Lambda code is written and permissions are set up in the Amplify project, run
- Post-Deployment Configuration & Rigorous Testing:
- Double-check that the EventBridge Scheduler is enabled and configured correctly.
- Monitor CloudWatch Logs for your
overdueCheckinNotifier
Lambda to see its execution logs, confirm it's being triggered, and debug any issues. - End-to-End Testing is Critical:
- Create a new trip in the app.
- Perform a check-in, setting an
expectedCheckOutTimestamp
that will occur soon (e.g., 15-20 minutes in the future). Select an emergency contact for which you can monitor SMS/email. - Do not check out of the trip.
- Wait for the EventBridge schedule to trigger your Lambda function (past the expected checkout time).
- Verify that the designated emergency contact receives both the SMS and email notifications.
- Check the
CheckInLog
record in your database (e.g., via AppSync query or DynamoDB console) to ensureisOverdueNotified
is set totrue
. - Confirm that on subsequent runs of the Lambda, notifications are not sent again for this same overdue event.
This is a fairly complex feature involving multiple interconnected services. Breaking it down into these phases should help manage the implementation. The Lambda function's code, particularly the interactions with AppSync, SNS, and SES, along with proper error handling and idempotency (ensuring isOverdueNotified
is reliably set), will be the most detailed part.