Custom Scheduled Events
Custom Scheduled Events are user-defined scripts that run on a recurring schedule. You write the script and ScriptForge executes it automatically during each scheduled cycle.
Creating a Custom Event
- Navigate to Workspace → Scheduled Events
- Click Create Event
- Configure:
- Name: A clear name (e.g., "Weekly stale issue cleanup")
- Description: What it does and why
- Schedule: Set the interval (hourly minimum)
- Script: Your JavaScript code
- Enabled: Toggle on
- Click Save
Writing Event Scripts
Event scripts have the same Canarys HAPI access as the Execution Console. They run as the app (service account) with full access to all projects.
Key differences from console scripts:
- No interactive output - use
console.logfor logging (captured in activity log) - Must complete within ~22 seconds
- Should be idempotent - if the same event runs twice, the result should be consistent
Examples
Auto-archive completed sprints' issues
// Move all "Done" issues older than 14 days to "Archived" status
const done = WorkItems.search(
'status = Done AND updated < -14d AND resolution is not EMPTY'
);
let count = 0;
await done.forEach(async (issue) => {
try {
await issue.transition('Archived');
count++;
} catch (e) {
console.warn(`Could not archive ${issue.key}: ${e.message}`);
}
});
return `Archived ${count} issues`;
Sync entity properties for reporting
// Update a "lastProcessed" timestamp on all active project issues
const active = WorkItems.search('status != Done AND status != Closed');
const now = new Date().toISOString();
await active.forEach(async (issue) => {
const props = issue.getEntityProperties();
await props.setString('lastProcessed', now);
});
Unassign inactive assignees
// If an issue has been "In Progress" for 14+ days with no updates, unassign it
const stuck = WorkItems.search(
'status = "In Progress" AND updated < -14d AND assignee is not EMPTY'
);
await stuck.forEach(async (issue) => {
await issue.update(b => b.setAssignee(null));
await issue.addComment('Unassigned due to 14 days of inactivity. Please re-assign if still active.');
});
Monitoring
Check the Activity Log filtered to "Scheduled Event" to see:
- When each event last ran
- Whether it succeeded or failed
- Console output and errors
- How long it took
Tips
- Keep events focused - one event per task. Don't combine unrelated operations.
- Use
try/catchinside loops so one failing issue doesn't abort the entire batch. - Log meaningful output (
console.log) so you can debug issues from the activity log. - Test your script in the Execution Console first before setting it as a scheduled event.