Scheduled Scripts
Scheduled Scripts (Scheduled Jobs) run Script Modules automatically on a recurring schedule. They are the primary tool for nightly batch processing, automated data maintenance, recurring report generation, and timed integration tasks.
How Scheduled Jobs Work
Scheduled Jobs run at 5:00 AM Eastern Time on their configured schedule. They execute a Script Module in the context of a specific User Account, giving the script the same permissions and account context as that user.
Creating a Scheduled Job
Scheduled Jobs are found on the Integration sidebar.
- Go to Integration > Scheduled Jobs.
- Click Create New Scheduled Job.
- Enter a Name and optional description.
- Select the Script Module to run.
- Select the User Account the script will run as.
- Set the Schedule (see below).
- Set the Start Recurrence Date — the first date the job will run.
- Ensure Active is checked.
- Save.
Schedule Options
| Schedule | Runs |
|---|---|
| Daily | Every day at 5AM Eastern |
| Semi-Weekly | Twice per week (Monday and Thursday) |
| Weekly | Once per week (Monday) |
| Bi-Weekly | Every two weeks |
| Monthly | First of each month |
The Next Recurrence Date field shows when the job will next run. This is updated automatically after each execution.
Variables Available in Scheduled Job Scripts
| Variable | Content |
|---|---|
user |
The configured User Account the job runs as |
account |
The account associated with that user |
log |
Logger for debug and error output |
elProcessor |
EL evaluation utilities |
messages |
Externalized text |
ReferenceData |
System-wide reference values |
Any CDI service can be imported: import "queryService"; import "contactService"; etc.
Common Patterns
Nightly Data Export
import "queryService";
import "commonHttpClient";
// Get all active transactions from the past day
var yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
var transactions = queryService.createQuery(
"select po from PurchaseOrder po where po.account = :account " +
"and po.status = 'ACTIVE' and po.orderReceived >= :since"
).setParameter('account', account)
.setParameter('since', yesterday)
.getResultList();
// Build export payload
var rows = [];
for each (var po in transactions) {
rows.push({
id: po.id,
amount: po.amount,
contact: po.contact != null ? po.contact.email : '',
campaign: po.campaign != null ? po.campaign.name : ''
});
}
// POST to external system
var response = commonHttpClient.post(
'https://api.example.com/import/transactions',
JSON.stringify({transactions: rows}),
'application/json'
);
log.info('Exported ' + rows.length + ' transactions. Response: ' + response);
Nightly Status Update
import "queryService";
import "purchaseOrderService";
// Find pledges past their due date with no payment
var overdue = queryService.createQuery(
"select po from PurchaseOrder po where po.account = :account " +
"and po.type = 'PLEDGE' and po.status = 'ACTIVE' " +
"and po.dueDate < CURRENT_DATE"
).setParameter('account', account).getResultList();
log.info('Found ' + overdue.length + ' overdue pledges');
for each (var po in overdue) {
var customStatus = po.get('ManualStatus');
if (customStatus == null || customStatus.value == '') {
purchaseOrderService.setCustomProperty(po, 'ManualStatus', 'OVERDUE');
log.info('Marked pledge ' + po.id + ' as OVERDUE');
}
}
Recurring Report Email
import "mailer";
import "queryService";
// Count this month's new donors
var firstOfMonth = new Date();
firstOfMonth.setDate(1);
var newDonors = queryService.createQuery(
"select count(distinct po.contact) from PurchaseOrder po " +
"where po.account = :account and po.status = 'ACTIVE' " +
"and po.type in ('RECEIVED', 'PLEDGE') and po.orderReceived >= :since"
).setParameter('account', account)
.setParameter('since', firstOfMonth)
.getSingleResult();
mailer.sendEmail(
user.email,
'Monthly New Donor Count',
'<p>New donors this month: <strong>' + newDonors + '</strong></p>'
);
Deactivating and Troubleshooting
- Uncheck Active to pause a Scheduled Job without deleting it.
- The Last Recurrence Date field shows when the job last ran.
- If a job fails, the error is logged server-side. Contact help@donorpoint.com to request a log review.
- Test your script logic manually using the Run button on the Script Module edit page before scheduling it.