Notifications and reminders

Reminders

Surveys will have a reminders property which will be null when they have no reminders set. When a reminder is set the reminders property of the survey will have the following properties:

type string

  • fixed: the reminders interval is relative to the date that the survey is downloaded
  • rolling: the reminders interval is relative to the timeline of the universe

recurrence string

The intervals, both in the fixed and rolling type of reminders, are represented by crontab-like expressions:

# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday;
# │ │ │ │ │                                   7 is also Sunday on some systems)
# │ │ │ │ │
# │ │ │ │ │
# * * * * *

The following expressions will have different behaviors whether the reminder is fixed or rolling:

  • 0 10 * * 1
    • fixed: on Monday at 10am
    • rolling: every Monday at 10am
  • 0 10 * * 1,3,5
    • fixed: on days 1, 3 and 5 at 10am since the survey is downloaded
    • rolling: every Mon-Wed-Fri at 10am

https://crontab.guru/ is a quick and simple crontab-like expressions editor that can be helpful to understand these rules.

ends Union(integer, null)

This property only applies in the case of a rolling reminder

  • null: never
  • 15: after 15 intervals

notification: Map(string, string)

This property is an object with the following attributes

  • subject: the notification subject, e.g. "Time to complete a form"
  • body: the notification body, e.g. "Don't forget to log your data"

Limitations

  • For rolling reminders we'll only support:
    • The interval can be every day OR some days of the week, e.g. Mon-Wed-Fri. We won't support day of the month NOR month. Intervals will specify a single time per day, e.g. 10am.
    • Ending can be either number of days OR null. We won't support other time unit.
    • Delay can be either number of days OR null. We won't support other time unit.
  • For fixed reminders we'll only support:
    • The interval is a set of days, e.g. 1-14,21, and a single time per day, e.g. 10am. We won't support other time unit.
    • No ending or delay attributes are supported

Mobile devices interaction with the API

Mobile devices will require to register themselves with the backend through the POST /user/:userIdentifier/device endpoint. They will need to send their platform name, secret token and local time zone.

If any of the local time zone, device identifier or secret token changes, they would need to update the device's value by using the PATCH /device/:identifier endpoint.

If a device should be deleted the DELETE /device/:identifier endpoint must be invoked.

API data model

A new class of entities tsDevices will be created. It will have attributes such as a unique identifier, a reference to the user it belongs to, the platform name and its secret token. It will also store the Amazon Resource Name (ARN) of the device's platform endpoint generated by Amazon SNS and used to send push notifications to that specific device.

Users will have a new attribute named devices which will be a set with the devices' identifiers associated to each user. Another new attribute named customRemindersTime will be created to store the custom reminders time that users can set on their devices.

Another class of entities tsNotifications will also need to be created. It will have attributes such as a unique identifier, a reference to the user that the notification needs to be sent to, a reference to the survey that the notification is related to, a dueAt datetime, a sentAt datetime and a counter to handle fixed interval reminders. This entity will represent a scheduled notification for a user.

Worker task

The worker task will have to periodically, e.g every minute, scan the tsNotifications table for scheduled notifications that are due to be sent but haven't still been sent. If it does, the worker will trigger them and will mark them as sent.

Notifications scheduling and invalidation

One key aspect of this design is to accurately create, and invalidate, tsNotifications instances. If any of the following events occur, we will need to invalidate existing tsNotifications and compute newer ones.

  • User sign up: on user sign up we don't need to invalidate existing tsNotifications given that there won't be any for the new user. We will need to compute the next scheduled notification which is appropriate for the user based on the surveys reminders settings of the studies they belong to
  • Updating a survey reminders setting: we will need to invalidate existing tsNotifications for users that belong to this survey study. For each if these users, we will need to compute the next scheduled notification for them based on the surveys reminders settings of the studies they belong to
  • Updating a user's custom reminders time

As soon as a scheduled notification in tsNotification is marked as sent, the next notification to be sent is computed and it is stored in tsNotification.

Amazon Simple Notification Service (SNS) and Firebase Cloud Messaging (FCM)

We will use Amazon SNS as a layer of abstraction on top of Firebase Cloud Messaging. We will need to create an SNS Platform Application using FCM as the provider.

For each device that is registered we will need to create its appropriate platform endpoint with an Amazon Resource Name (ARN) attached to it. Whenever a notification is needed to be sent to a device, a message must be sent to its platform endpoint so the platform, e.g. FCM, sends them the notification.