Scripting Guide
DonorPoint scripts are written in JavaScript and run on the server using the Mozilla Rhino engine. Scripts can access DonorPoint data, call services to read and write records, send emails, make HTTP calls, and interact with external systems.
The Script Execution Environment
Always Available
The following variables are available in every script context:
| Variable | Type | Description |
|---|---|---|
log |
Logger | Server-side logging: log.info(msg), log.debug(msg), log.error(msg) |
elProcessor |
ELProcessor | Execute EL expressions: elProcessor.eval('#{expression}') |
ReferenceData |
Map | System-wide configuration values |
messages |
ResourceBundle | Externalized text for the current context |
Importing CDI Services
Use the import statement to bring any DonorPoint service or component into scope:
import "mailer"; // email sending
import "purchaseOrderService"; // transaction operations
import "contactService"; // contact operations
import "organizationService"; // organization operations
import "queryService"; // database queries
import "commonRenderer"; // formatting and rendering utilities
Importing the current user: The logged-in user requires special handling because it is created via a CDI producer. Use:
import "user"; var currentUser = user; // UserAccount object
Return Values
If your script contains a return statement, it is automatically wrapped in a function and called. Use return to pass values back to the caller:
// This script returns a value to a Webhook caller:
import "queryService";
var total = queryService.createQuery(
"select sum(po.amount) from PurchaseOrder po where po.contact = #{contact} and po.status = 'ACTIVE'"
).getSingleResult();
return total != null ? total.toString() : '0';
Calling EL from JavaScript
You can evaluate EL expressions from within JavaScript:
// Evaluate an EL expression:
var name = elProcessor.eval('#{contact.firstName}', 'contact', theContact);
// Evaluate and get an object back (not a string):
var org = elProcessor.evalObject('#{contact.getEmployer()}', 'contact', theContact);
Database Queries
Use queryService to run JPQL queries:
import "queryService";
// Simple query returning a list:
var results = queryService.createQuery(
"select c from Contact c where c.account = :account and c.archived = false"
).setParameter('account', account).getResultList();
// EL expressions in queries are automatically evaluated:
var gifts = queryService.createQuery(
"select po from PurchaseOrder po where po.contact = #{contact} and po.status = 'ACTIVE'"
).getResultList();
// Count query:
var count = queryService.createQuery(
"select count(po) from PurchaseOrder po where po.campaign = :campaign"
).setParameter('campaign', campaign).getSingleResult();
Common Patterns
Sending Email
import "mailer";
mailer.sendEmail(
'recipient@example.com', // to
'Subject line', // subject
'<p>HTML email body</p>' // body (HTML)
);
// Send from a template:
mailer.sendEmailFromTemplate(
contact.email,
emailTemplateId,
'context_var', contextValue // named context variables
);
Working with Custom Fields
// Read a custom field value:
var deptField = contact.get('Department');
var dept = (deptField != null && deptField.value != '') ? deptField.value : 'Unknown';
// For text areas (CLOB), use .text:
var notes = contact.get('Notes');
var notesText = (notes != null) ? notes.text : '';
// For files and images, use .value for URL, .fileName, etc.:
var logo = organization.get('Logo');
var logoUrl = (logo != null) ? logo.value : '';
Making HTTP Calls
import "commonHttpClient";
// POST JSON to an external API:
var response = commonHttpClient.post(
'https://api.example.com/endpoint',
JSON.stringify({ key: 'value' }),
'application/json'
);
// GET from an external API:
var response = commonHttpClient.get('https://api.example.com/data');
var data = JSON.parse(response);
Logging for Debugging
log.info('Processing contact: ' + contact.id);
log.debug('Custom field value: ' + JSON.stringify(contact.get('FieldName')));
log.error('Error in script: ' + errorMessage);
Script Modules
Script Modules store reusable scripts that can be referenced by Event Handlers, Workflows, Entity Actions, Scheduled Jobs, Webhooks, and Campaign Templates.
To create a Script Module:
- Go to Integration in the sidebar and select Script Modules.
- Click Create New Script Module.
- Enter a Name (used to identify the script in Event Handlers, Workflows, etc.).
- Enter the Script content.
- Save.
Script Modules can also be run directly from the Script Module edit page using the Run button. This executes the script immediately in the context of your account and the currently logged-in user — useful for testing and one-off data operations.
Script Contexts by Usage
| Usage | Key Variables Available |
|---|---|
| Event Handler | this (entity), {entityName}Home, user, account |
| Workflow action | this (transaction or order item), user, account |
| Entity Action | this (the current entity on the edit page) |
| Scheduled Job | user (configured user for the job), account |
| Webhook | requestBody (POST body), account (no user defined) |
| Campaign Template createEL | campaignHome, newly created campaign context |
| Form Init Script | this (the form/campaign), user |
| Item Init Script | this (the order item), user, campaign |
| Email Creation Script | contact (recipient), campaign, purchaseOrder |
Security Notes
- Scripts run with the permissions of the user account configured for the job (for Scheduled Jobs) or the currently logged-in user (for interactive contexts).
- Webhook scripts have access to your account but no user context. Retrieve a user via:
import "queryService"; var adminUser = queryService.createQuery("select u from UserAccount u where u.account = :account and u.admin = true").setParameter('account', account).setMaxResults(1).getSingleResult(); - Script access is permission-controlled. Contact help@donorpoint.com to enable scripting permissions for your account.