Cron Module
Scheduled triggers — run your automations every minute, every morning, or on any cron expression.
The Cron module fires events on a schedule. Define as many named crons as you like, each with its own expression and timezone, and use them as triggers: a daily recap, a reminder every hour of stream, a cleanup at midnight.
Getting started
- Open the Cron module site and sign in with your Rawtoh account — same session as the dashboard
- Pick your organization and click Install with Rawtoh. The module creates a module instance in your organization, enrolls its key pair and connects. You need the owner role
- Add your crons: a name, a schedule in cron syntax and a timezone
One instance per organization is enough: every cron it holds emits the same event, told apart by its name.
Schedules
Standard five-field cron expressions, evaluated in the cron's timezone (an IANA name such as Europe/Paris), so daylight saving is handled for you.
| Expression | Fires |
|---|---|
* * * * * | Every minute |
*/15 * * * * | Every 15 minutes |
0 9 * * * | Every day at 09:00 |
0 20 * * 5 | Fridays at 20:00 |
0 0 1 * * | First day of the month at midnight |
Events
| Event | Description |
|---|---|
cron.tick | A cron fired. The payload carries its name, schedule, timezone and the timestamp (epoch, milliseconds) |
There is one event for every cron of the instance. A trigger on cron.tick therefore filters on the name:
import { event } from "rawtoh"
// Several crons can fire at the same minute: pick yours by name.
export default event.payload.name === "daily-recap"What you can do
cron.list— the crons of the instance with their next run, handy to show "next recap at…" somewhere
import { module } from "rawtoh"
const crons = await module("cron").request("cron.list")
// [{ name: "daily-recap", schedule: "0 9 * * *", timezone: "Europe/Paris", next_run: 1760000000000 }]Crons are created and edited on the module site, not from scripts, so a schedule can't change itself by accident.
Example: a daily recap in Discord
A cron named daily-recap on 0 9 * * *, the trigger above, and this action:
import { event, module, storage } from "rawtoh"
const subs = (await storage.get("subs-today")) ?? 0
await module("discord").request("message.send", {
channel_id: "123456789012345678",
content: `Recap for ${new Date(event.payload.timestamp).toLocaleDateString()}: ${subs} new subs`,
})
await storage.set("subs-today", 0)Example automations
- Every hour while live → remind chat about the schedule, rotate a sponsor message
- Every morning → post yesterday's stats in Discord, reset the daily counters in storage
- Five minutes before stream → switch OBS to the starting-soon scene, update the Twitch title
- Every night → clean up expired entries in storage