Script Tasks with Triggers
Table of Contents
- Script Variables and Examples
- Variables Shared Across Trigger Types
- Approvals
- Maintenance
- Requests
- Resource
- Reservations
- Status Events
- Templates
- Working With Optional Data
Script Variables and Examples
Script tasks use QReserve's sneq scripting language. QReserve injects global variables into each script so it can access the event, its associated objects, and results from earlier tasks.
These variables are dictionaries. For example, reservation["reservation_id"] reads a reservation's ID.
Variables Shared Across Trigger Types
| Variable | Description |
|---|---|
workflow |
Information about the workflow run and the configured trigger condition. |
outputs |
A list of outputs from tasks already executed in the current run. It is empty when no earlier tasks have run. |
input_task |
Input supplied through the script task's Input Script Task ID setting. Only injected when input is supplied. |
audit_log |
The audit entry associated with the triggering event. Available during automatic event runs; it may be absent during manual tests. |
The workflow dictionary contains:
workflow["manual_run"]: Whether the workflow was started manually.workflow["trigger"]["event_object"]: The configured trigger category, using its internal name.workflow["trigger"]["event_type"]: The configured event type:create,modify, ordelete.workflow["trigger"]["subevent_type"]: The configured sub-event filter, orNonewhen no specific filter is selected.
The trigger information describes the configured condition. For example, an approval trigger configured for All Events has a subevent_type of None, even when the particular approval event is an approval or denial.
When a workflow has an assigned user, workflow["user"] contains user_id, display_name, email, and bot. This is the workflow's assigned user; it should not be assumed to be the person who made the booking or caused the event.
workflow["for_date"] is provided for scheduled subscription runs with a run date. Event Hook scripts should not assume it is available.
Example: return the trigger configuration for inspection.
return {
"category": workflow["trigger"]["event_object"],
"event": workflow["trigger"]["event_type"],
"filter": workflow["trigger"]["subevent_type"],
"manual_run": workflow["manual_run"]
}
Approvals
Injected variables: approval and reservation, plus the shared variables above.
approvalcontains the individual approval record, includingapproval_id,status,note, approver information, and its linkedreservation.reservationcontains the associated booking. For an approval attached to a component of a multi-resource booking, this top-level variable refers to the overall parent booking.
approval["approver"] can be None, such as when an approval is assigned to a group. Group information is available through approval["approver_site_user_group_name"].
Example: return the approval decision and associated booking ID.
return {
"approval_id": approval["approval_id"],
"approval_status": approval["status"],
"approval_note": approval["note"],
"reservation_id": reservation["reservation_id"]
}
The approval's current status can differ from its status when the event occurred. During an automatic approval modification run, the recorded transition is available through:
return {
"previous_status": audit_log["meta_data"]["approval_status"]["old"],
"new_status": audit_log["meta_data"]["approval_status"]["new"]
}
This second example applies to approval modifications, rather than approval creation or manual tests.
Maintenance
Injected variable: reservation, plus the shared variables above.
Maintenance bookings use the reservation variable. There is no separate maintenance global.
Useful fields include reservation_id, maintenance, start, end, purpose, and status. The maintenance field identifies the booking as maintenance.
Example: return the maintenance booking's purpose and scheduled times.
return {
"reservation_id": reservation["reservation_id"],
"maintenance": reservation["maintenance"],
"purpose": reservation["purpose"],
"start": reservation["start"],
"end": reservation["end"]
}
Requests
Injected variable: reservation, plus the shared variables above.
Requests also use the reservation variable. There is no separate request global.
Useful fields include reservation_id, reservation_type, purpose, and status. When the request has an associated user, their details are available through reservation["reserved_for"].
Example: prepare a summary of the request for a later task.
return {
"request_id": reservation["reservation_id"],
"purpose": reservation["purpose"],
"status": reservation["status"]
}
Resource
Injected variable: reservable, plus the shared variables above.
reservable contains the resource's current properties, including:
reservable_idnamestatusstatus_detailactive
Resource modification triggers also provide two additional values:
workflow["trigger"]["previous_value"]: The resource's status before the recorded change.workflow["trigger"]["value"]: The resource's status after the recorded change.
These describe the triggering event. reservable["status"] describes the resource's current status when the script runs, which may have changed again.
Example: return the resource name and status transition.
return {
"resource_id": reservable["reservable_id"],
"resource_name": reservable["name"],
"previous_status": workflow["trigger"]["previous_value"],
"new_status": workflow["trigger"]["value"],
"current_status": reservable["status"]
}
During a manual test without an actual event, previous_value and value are None.
If several resource status changes occur before processing, intermediate changes may be combined. The previous and new values describe the latest retained event, rather than the entire sequence of changes.
Reservations
Injected variable: reservation, plus the shared variables above.
Useful fields include reservation_id, start, end, purpose, status, cancelled, and is_loan.
For a booking associated directly with one resource, resource details are nested under reservation["reservable"]. For bookings containing multiple resources, component bookings are available through reservation["reservation_children"].
Example: prepare content for a follow-up email.
return {
"subject": "How was your reservation?",
"body": "Thank you for using our facilities. Please share any feedback about your booking.",
"reservation_id": reservation["reservation_id"]
}
To use this content, assign the script a Task ID and select that ID as the input to a later email task. Configure the recipient in the email task. Returning this dictionary does not send an email by itself.
Status Events
Injected variable: reservation, plus the shared variables above.
reservation contains the booking or request associated with the status event. For multi-resource bookings, this may be an individual component or the overall parent, depending on which status changed.
Use reservation["status"] to read the status of the injected booking object.
During an automatic run, the recorded status transition is available through audit_log["meta_data"]["reservation_status"].
Example: return the status transition that caused the workflow to run.
return {
"reservation_id": reservation["reservation_id"],
"previous_status": audit_log["meta_data"]["reservation_status"]["old"],
"new_status": audit_log["meta_data"]["reservation_status"]["new"]
}
For an Initial Status event, the previous status is unset. This example requires an actual event audit entry and should not be used unchanged in a manual test without one.
Templates
Injected variables: reservation, and conditionally template or sub_reservation, plus the shared variables above.
The available objects depend on the template event:
reservationis the primary booking object associated with the event. It can represent the template itself or a reservation created from a template.templateis injected when the event includes a related reservation template, such as Template is Used. It contains the template's reservation data.sub_reservationis injected when the event includes a related booking that is not itself a template, such as the reservation that consumed a template.
The template global is a dictionary. The similarly named reservation["template"] field is a boolean indicating whether the primary booking object is itself a template.
Example for Templates > Reservation > Template is Used: return the new reservation ID and the template it used.
return {
"reservation_id": reservation["reservation_id"],
"template_id": template["reservation_id"],
"purpose": reservation["purpose"]
}
This example specifically requires a template-use event. Other template events may not inject the template global.
Working With Optional Data
Some variables and dictionary fields are only present when the corresponding data exists. For example:
input_taskrequires configured input from another task.audit_logmay be absent during manual tests.templateandsub_reservationdepend on the template event.reservation["reserved_for"]requires an associated user.reservation["reservable"]is not present on every multi-resource parent booking.
Use examples appropriate to the selected trigger and account for optional fields when extending them.
Injected objects provide data for the script to read. Returning a dictionary makes data available as the script's result; it does not automatically update the booking or resource. Configure subsequent workflow tasks to perform the required actions.