Cron Pusher

Syntax

The schema of CronPusher are as follows:

type Date = {
	minute?: 0-60;
	hour?: 0-24;
	date?: 1-31;
	month?: 1-12;
	year?: number;
	timezone?: Timezone | 'client';
}

type Interval = {
	minute?: number;
	hour?: number;
	day?: number;
} | number;

type Timer = {
	// if using `last interaction` then start time will be calculated from user's last interaction(chat with bot) time
	start?: Required<Date> | 'last interaction';
	delay?: Interval;
	interval?: Interval;
}

Timer

The timer is the core structure, which includes how to define a timer. A timer refers to our timed push action; start, delay, and interval are all timing conditions of the timer. When the timing conditions are met (with minute-level precision), a push action will be triggered. The push action can execute a certain state and perform its logic inside, then render the corresponding message to be pushed to the user.

start

The start indicates the time when the push action begins. You can use a regular time or choose the user's last interaction time.

If start='last interaction', then the push time will be calculated from a user's last interaction.

If start is in Date format, it can be understood as a cron expression, and the trigger time of this expression will be calculated.

It should be noted that you can select the corresponding timezone for start. If no timezone is selected, this time will be calculated based on UTC. If a timezone is selected, it will be calculated based on that specific timezone's time.

You can refer to https://en.wikipedia.org/wiki/List_of_tz_database_time_zones for the list of timezones.

delay

delay indicates how long to delay sending. An Interval can be used to represent its delay time. It is not required, if delay is empty it means that delay will not be count on calculating cron.

interval

Interval indicates the interval between push times. If interval is empty, it means this push is a one-time action.

Push Time Calculation

Ignoring the impact of time zones, let's assume our writing is

"morning": {
            "start": {
                "hour": 10,
                "minute": 5
            },
            "delay": {
	        "minute": 1
            },
            "interval": {
                 "minute": 3
            }
        }

Then the time of the first push is: 10:05 + 1 minute (from delay) = 10:06, and it will be pushed again every 3 minutes, that is, after the first push, the next push time will be 10:09.

How to write a cron push task

Taking an actual proconfig as an example, here we want to implement a scheduled task that starts at 8:30 AM in the UTC+8 time zone and pushes every 10 minutes.

{
  "type": "automata",
  "id": "language_partner",
  "initial": "home_page_state",
  "inputs": {},
  "outputs": {},
  "properties": {
    "timers": {
      "morning": {
        "start": { "timezone": "Asia/Shanghai", "hour": 08, "minute": 30 },
        "interval":{"minute":10},
        "event": "run_cron_job"
      }
    },
    "skip_idle_state": true,
    "cache": false
  },
  "transitions": { "run_cron_job": "cron_page" },
  "states": {
    "home_page_state": { "render": { "text": "Home message for display" } },
    "cron_page": {
      "render": {
        "text": "Go morning sir."
      }
    }
  }
}

Here, the syntax of a scheduled task is divided into three parts:

  1. Timer settings in properties

  2. Event settings in global transitions

  3. Cron state settings in states

properties.timer

This is consistent with the timer definition given in the first section. In properties.timer, we will define a timer named morning. The internal time settings are similar to those listed in the first section. The only difference is that in an actual timer, an event needs to be added to indicate the event triggered when the timer goes off. This event needs to be defined in global transitions.

global transitions

In the top-level transitions structure (which we call global transitions), a "run_cron_job": "cron_page" is defined. It means that upon receiving the run_cron_job event, it will jump to cron_page and execute its logic.

cron state

After jumping to cron_page, it will execute its internal logic. As shown in the proconfig code above, it will render a text and send a message to the user.

What should be noticed when using CronPusher.

  • cron state should not have input

Since the cron state does not directly involve user input, it should not have input. However, context variables can be used in output and render.

  • Consumption of tasks in cron state

If there are tasks running in the cron state, they will consume the user's (not the creator's) battery power. Additionally, if context is included in the task parameters, each user may receive different outputs. Note that if a user's battery is insufficient, this message will not be rendered.

  • Push mechanism of cron state

If a user has logged into a device on iOS or web (this happens automatically) and is online, they will receive corresponding push notifications.

Last updated