PlaybookDefinition
Creates a ServiceNow Playbook: a guided multi-step process that operates on a record (sys_pd_process_definition). Composed of lanes, activities, triggers, inputs, and outputs with inline startRule ordering.
Signature
PlaybookDefinition(
config: PlaybookConfig,
triggers: PlaybookTriggerDeclaration,
body: PlaybookBody
)
API Structure
The Playbook DSL follows a 3-argument pattern:
PlaybookDefinition(
config, // PlaybookConfig - top-level playbook properties, inputs, outputs
triggers, // PlaybookTriggerDeclaration - { triggers: [...] }
body // PlaybookBody - lanes and activities with inline startRule ordering
)
This pattern mirrors the Flow API while accommodating playbooks' need for multiple triggers. Declarative state (inputs, outputs) lives on the 1st-arg config alongside other top-level properties; the 2nd arg carries the playbook's triggers.
Parameters
-
config:
PlaybookConfigTop-level playbook properties, plus declarativeinputsandoutputs. See PlaybookConfig below. -
triggers:
PlaybookTriggerDeclarationObject containing atriggersarray ofwfa.playbook.trigger(...)instances. See PlaybookTriggerDeclaration below and wfa.playbook.trigger() for trigger construction. -
body:
PlaybookBodyObject defining lanes and activities with inline startRule ordering. See PlaybookBody and PlaybookBodyParams below.
Imports
import {
// Main definition function
PlaybookDefinition,
// wfa namespace contains playbook helpers under wfa.playbook.*
// (lane, activity, trigger, run, dataPill, currentActivity)
wfa,
// Trigger types (used as first argument to wfa.playbook.trigger())
PlaybookTriggerTypes,
// OOTB activity definitions
ActivityDefinitions,
} from '@servicenow/sdk/automation'
import {
// Column types for inputs/outputs
StringColumn,
ReferenceColumn,
IntegerColumn,
BooleanColumn,
DateTimeColumn,
// ... other column types
} from '@servicenow/sdk/core'
PlaybookConfig
PlaybookConfig
Top-level playbook properties (maps to sys_pd_process_definition).
Properties:
-
$id (required):
Now.Internal.ExplicitKey | string | numberUnique identifier. -
label (required):
stringDisplay name (max 240 chars). -
name (optional):
stringInternal name. Must be unique across playbooks. If not provided, auto-generated fromlabelby converting to lowercase and replacing non-alphanumeric characters with underscores. Acts as the record's stable identity — once a playbook is deployed, avoid changingnameon subsequent edits, as a changednameis treated as a new record rather than an update to the existing one. -
description (optional):
stringDescription (max 1000 chars). -
restartable (optional):
'RESTARTABLE_TRUE' | 'RESTARTABLE_FALSE'Whether playbook can be restarted. Default:'RESTARTABLE_FALSE'. -
allowAsNested (optional):
booleanCan be used as a nested playbook. Default:false. -
access (optional):
'package_private' | 'public'Visibility scope. Default:'public'. -
runStrategy (optional):
'run_once' | 'run_if_not_running' | 'run_always'Execution strategy. Default:'run_once'. -
executionType (optional):
'record_driven'Execution type. Default:'record_driven'. -
processType (optional):
stringPlaybook type name. Must exist in the SDK process type mapping. Currently supported value is'Standard playbook'. Default:'Standard playbook'. -
parentTable (optional):
TableNameTable whose records this playbook operates on. When set, auto-generates aparent_recordprocess input typed as a Reference to this table. The triggering record is then accessible in the lanes callback viaparams.parentRecord, dot-walkable to all fields. Required for record-driven playbooks that need to read fields from the triggering record. -
inputs (optional):
Record<string, Column>Playbook input schema declared on the config object. Maps tosys_pd_process_input. See Inputs and Outputs below. -
outputs (optional):
Record<string, Column>Playbook output schema declared on the config object. Maps tosys_pd_process_output. See Inputs and Outputs below. -
dataRetentionPeriodOverride (optional):
'2_week' | '6_week' | '6_month' | '1_year'Data retention period override.
Note: When a playbook is deployed, changes are not applied to running instances automatically. To make new changes take effect at runtime, open Playbook Designer and activate the playbook again. The build/deploy output logs this reminder.
triggers
PlaybookTriggerDeclaration
The playbook's trigger instances.
Properties:
- triggers (required):
PlaybookTriggerInstance[]Trigger instances created withwfa.playbook.trigger(). Maps tosys_pd_trigger_instance. See wfa.playbook.trigger() below for trigger types, trigger inputs, and trigger mapper behavior.
The triggers array is required even when a playbook has no triggers — pass an empty array explicitly:
{ triggers: [] }
Inputs and outputs are declared on the 1st-arg config (see Inputs and Outputs below), not here.
Inputs and Outputs
Playbook inputs and outputs are declared on the 1st-arg config and use the same Column types as table fields. Inputs feed values into the playbook at launch time (from triggers or from a caller); outputs publish values when the playbook completes.
Declaring inputs
Inputs are declared using the inputs object on the config. Each trigger can provide values for these inputs via its trigger mapper — the 4th argument to wfa.playbook.trigger() that maps trigger data or literal values to the declared input schema.
{
$id: Now.ID['my_playbook'],
label: 'My Playbook',
parentTable: 'incident',
inputs: {
record: ReferenceColumn({
label: 'Record',
referenceTable: 'incident',
mandatory: true,
}),
priority: IntegerColumn({
label: 'Priority Override',
default: 3,
}),
summary: StringColumn({
label: 'Summary',
maxLength: 1000,
}),
},
}
Column options:
label: Display name shown in the designer.mandatory: Whentrue, the playbook fails to launch if the input is unmapped. Build-time error fires if a trigger mapper omits a mandatory input.default: Default value applied when no caller value is provided.maxLength: Maximum length (string columns).referenceTable: Target table (reference columns).
Declaring outputs
{
$id: Now.ID['my_playbook'],
label: 'My Playbook',
outputs: {
resolvedBy: ReferenceColumn({
label: 'Resolved By',
referenceTable: 'sys_user',
}),
closureCode: StringColumn({
label: 'Closure Code',
maxLength: 40,
}),
},
}
Outputs are declarative schema only at this layer — they describe the shape the platform will publish when the playbook completes. There is no Fluent-side helper for assigning values to outputs from inside an activity; the wiring must be done using the "Set Playbook Outputs" activity in Playbook Designer.
Outputs are also not consumable in the Fluent DSL at this time — you cannot reference them from activity inputs, experience properties, or conditions. Support for consuming outputs is planned as future work.
Declared inputs surface inside the lanes callback via params.inputs.<name>. See PlaybookBodyParams below for the callback shape and playbook-datapills-guide for valid pill usage and format.
Maps to: sys_pd_process_input, sys_pd_process_output
body
PlaybookBody
A PlaybookBody object that declaratively defines lanes and activities. Execution ordering is declared inline on each lane and activity config via startRule.
interface PlaybookBody<I> {
lanes: (params: PlaybookBodyParams<I>) => Record<string, LaneDefinition | ActivityInstance<any>>
}
Properties:
- lanes (required):
(params: PlaybookBodyParams<I>) => Record<string, LaneDefinition | ActivityInstance<any>>A function that receivesparamsand returns a record of lane definitions and/or stage-level activities (typically aDecision) keyed by name. Mixing lanes and stage-level activities in the same returned record is how stage-level Decision routing is expressed. The callback form is required — the plugin extracts the lane/activity definitions from the arrow function body, not from a plain record.
Lane input shape (wfa.playbook.lane)
wfa.playbook.lane() accepts an object with config (a plain LaneConfig) and activities (a callback that receives params and returns the activity instances).
type LaneFunction = <A extends Record<string, ActivityInstance<any>>>(definition: {
config: LaneConfig
activities: (params: PlaybookBodyParams) => A
}) => LaneDefinition & LaneDataReference<A>
Properties:
-
config: Lane configuration. Must be a plain
LaneConfigobject — the plugin reads its properties statically and does not invoke a callback. -
activities: Function receiving
params(the samePlaybookBodyParamsthelanescallback receives) and returning a record of activity instances keyed by name. Must useconst+ explicit-keyreturn { name: name, ... }form so the build transformer can read the property keys statically.
The returned value carries the declared activity names via LaneDataReference<A>, which is how cross-lane references like intake.review.outputs.record type-check. LaneDefinition itself is a marker interface; the developer-visible surface lives on LaneDataReference<A>.
LaneConfig
interface LaneConfig {
$id: Now.Internal.ExplicitKey | string | number
label: string
name?: string // Optional internal name (auto-generated from label if not provided)
order: number
startRule: LaneExecutionRule // Required - wfa.playbook.run.Immediately() or wfa.playbook.run.After(...)
restartRule: RestartRule // Required - 'RUN_ALWAYS' | 'RUN_ONLY_ONCE' | 'RUN_ONLY_ON_RESTART'
description?: string
conditionToRun?: string
startWithDelay?: StartWithDelay // Optional delay before the lane starts
}
Properties:
-
$id (required):
Now.Internal.ExplicitKey | string | numberUnique identifier. -
label (required):
stringDisplay name shown in Playbook Designer. Also used to auto-generatename. -
order (required):
numberDisplay position in Playbook Designer. Controls visual layout only — usestartRulefor execution order. -
startRule (required):
LaneExecutionRuleWhen this lane starts.wfa.playbook.run.Immediately(): no dependencies;wfa.playbook.run.After(...deps): starts after all listed dependencies complete. -
restartRule (required):
'RUN_ONLY_ONCE' | 'RUN_ALWAYS' | 'RUN_ONLY_ON_RESTART'Re-execution behavior when the playbook is restarted.'RUN_ONLY_ONCE': skipped on restart;'RUN_ALWAYS': re-runs on restart;'RUN_ONLY_ON_RESTART': skipped on first run, runs only on restart. -
name (optional):
stringInternal name. If provided, it is used verbatim. If omitted, thenameis auto-generated by slugifying thelabel; when sibling lanes produce duplicate slugs, a suffix is appended:lane_name,lane_name_1,lane_name_2, etc. Thenameis the lane's stable identity — once deployed, ideally do not change it on subsequent edits, as a changednameis treated as a new lane rather than an update to the existing one. -
description (optional):
stringOptional description. -
conditionToRun (optional):
stringEncoded query evaluated at runtime. The lane is skipped when the condition is false. Usewfa.playbook.dataPill()to interpolate runtime values. -
startWithDelay (optional):
StartWithDelayOptional delay applied afterstartRuleis satisfied. SeestartWithDelaybelow.
startWithDelay
Optionally delays the start of a lane or activity after its startRule is satisfied. Maps to a sys_pd_timer_attributes descendant record. Discriminated by type.
type StartWithDelay =
| { type: 'explicit'; duration: Duration }
| { type: 'relative'; duration: Duration; relativeDatetime: string; relativeOperator: 'before' | 'after' }
| { type: 'percentage'; percentage: number; percentageDatetime: string }
type Duration = {
days?: number
hours?: number
minutes?: number
seconds?: number
}
type: 'explicit' — Fixed delay specified as a duration.
Properties:
-
type (required):
'explicit'Discriminator. -
duration (required):
DurationHow long to delay. Accepts aDurationobject or a data pill.
type: 'relative' — Delay relative to a datetime, before or after it.
Properties:
-
type (required):
'relative'Discriminator. -
duration (required):
DurationHow far before or afterrelativeDatetimeto start. Accepts aDurationobject or a data pill. -
relativeDatetime (required):
stringReference datetime in'yyyy-MM-dd HH:mm:ss'format. Accepts a data pill. -
relativeOperator (required):
'before' | 'after'Whether the delay falls before or afterrelativeDatetime.
type: 'percentage' — Delay as a percentage of the time window up to a reference datetime.
Properties:
-
type (required):
'percentage'Discriminator. -
percentage (required):
numberPercentage of the time window (exclusive 0, inclusive 100; decimals allowed, e.g.10.5). Accepts a data pill. -
percentageDatetime (required):
stringReference datetime in'yyyy-MM-dd HH:mm:ss'format. Accepts a data pill.
Duration properties:
-
days (optional):
numberDays component. -
hours (optional):
numberHours component. -
minutes (optional):
numberMinutes component. -
seconds (optional):
numberSeconds component.
All Duration fields are optional; omit any component that is 0. At least one must be provided. Duration is stored internally as an epoch-relative datetime string (e.g., '1970-01-05 03:02:01') but the API accepts the friendly object form.
PlaybookBodyParams
The params object available inside the lanes callback closure:
interface PlaybookBodyParams<I> {
inputs: { [K in keyof I]: InputReference }
state: string
parentRecord: DataReference
}
Properties:
-
params.inputs.* : References to declared playbook inputs (dot-walkable for data pills).
-
params.state : Reference to the playbook's state field (dot-walkable for data pills).
-
params.parentRecord : Reference to the parent record (available when
parentTableis set on config). Dot-walkable for data pills referencing fields on the parent record.
Activity Output References
Same-lane outputs use local variables within the activities callback; cross-lane outputs use the lane variable from the lanes callback (e.g. intake.review.outputs.record). See playbook-activities-guide for the full pattern with examples.
Helper Functions
wfa.playbook.trigger()
Creates a trigger instance with a 4-argument pattern.
wfa.playbook.trigger(
triggerType: PlaybookTriggerType,
config: TriggerConfig,
triggerInputs: TriggerInputs,
playbookInputs?: (trigger: TriggerOutputs) => Record<string, unknown>
): PlaybookTriggerInstance
TriggerConfig
interface TriggerConfig {
$id: Now.ID
label?: string
}
Properties:
-
$id (required):
Now.Internal.ExplicitKey | string | numberUnique identifier. -
label (optional):
stringDisplay label.
PlaybookTriggerType
PlaybookTriggerTypes.RecordCreate // Triggered when a record is created
PlaybookTriggerTypes.RecordUpdate // Triggered when a record is updated
PlaybookTriggerTypes.RecordCreateOrUpdate // Triggered on create or update
PlaybookTriggerTypes.Scheduled // Triggered on a schedule
TriggerInputs
The 3rd argument specifies the table the trigger monitors and optional filtering conditions. Each trigger monitors a single table (record-based triggers can additionally include its extended tables via runTriggerOnExtendedTables). The structure varies by trigger type:
Record-based triggers (RecordCreate, RecordUpdate, RecordCreateOrUpdate) accept these properties:
RecordTriggerInputs properties:
-
table (required):
stringTable to monitor (for example,'incident'). -
condition (optional):
stringGlideRecord encoded query condition used to filter matching records. -
runTriggerOnExtendedTables (optional):
booleanWhether the trigger also applies to extended tables. Default:false.
Scheduled triggers use these base properties:
ScheduledTriggerInputsBase properties:
-
table (required):
stringTable to query on each scheduled run. -
condition (optional):
stringGlideRecord encoded query condition used to filter the scheduled record set. -
limit (required):
numberMaximum number of records processed per run (1-1000). -
startDateAndTime (required):
stringTimestamp for when the schedule starts, inyyyy-MM-dd HH:mm:ssformat. -
timeZone (optional):
stringTime zone for the schedule. Defaults to the system time zone.
Additional schedule-specific fields depend on the schedule type:
once— runs a single timedaily— adds frequency and end fieldsweekly— adds frequency,daysOfTheWeek(for example,'12345'), and end fieldsmonthly— adds frequency,daySelection(fixed_dayorrelative_weekday), and end fieldsyearly— addsrepeatMonth,daySelection, and end fieldsperiodically— addsrepeat(dd HH:mm:ss) and end fields
playbookInputs
The optional 4th argument is only used when the playbook declares inputs or the trigger table differs from the playbook's parentTable. It maps declared playbook inputs and parentRecord from trigger data or hardcoded literal values:
wfa.playbook.trigger(
PlaybookTriggerTypes.RecordCreate,
{ $id: Now.ID['trig_1'], label: 'On Incident Created' },
{ table: 'incident', condition: 'priority=1' },
(trigger) => ({
parentRecord: wfa.playbook.dataPill(trigger.current.assigned_to),
record: wfa.playbook.dataPill(trigger.current),
priority: wfa.playbook.dataPill(trigger.current.priority),
status: 'in_progress', // hardcoded literal
})
)
Use (trigger) => ({ ... }) when the mapper reads from trigger.current. Use () => ({ ... }) when every mapped value is hardcoded. Omit the 4th argument entirely when the playbook has no declared inputs and the trigger table matches the playbook's parentTable.
Mapper keys must match declared playbook input names or parentRecord. To map values from the triggering record, wrap trigger.current references in wfa.playbook.dataPill(...).
See playbook-triggers-guide for detailed mapper examples, whole-record pills, template literals, dot-walk usage, and diagnostics.
Maps to: sys_pd_trigger_instance
wfa.playbook.activity()
Creates an activity instance. Returns an ActivityInstance — a plain data object with .outputs and .branches properties but no builder methods.
wfa.playbook.activity(
activityDefinition: ActivityDefinition,
config: ActivityConfig,
inputs?: Record<string, unknown>,
experienceProperties?: Record<string, unknown>
): ActivityInstance<TBranches>
Parameters
Properties:
-
activityDefinition (required):
ActivityDefinitionThe activity definition to instantiate. -
config (required):
ActivityConfigActivity configuration (ID, label, order, startRule, etc.). -
inputs (optional):
Record<string, unknown>Automation inputs passed to the underlying flow/action. -
experienceProperties (optional):
Record<string, unknown>UI component configuration — controls how the activity is rendered and what data is displayed to users.
ActivityConfig
interface ActivityConfig {
$id: Now.Internal.ExplicitKey | string | number
label: string
order: number // Required - display order within the parent scope (lane or lanes body)
startRule: ActivityExecutionRule // Required - wfa.playbook.run.Immediately() or wfa.playbook.run.After(...)
description?: string
conditionToRun?: string
restartRule: 'RUN_ALWAYS' | 'RUN_ONLY_ONCE' | 'RUN_ONLY_ON_RESTART' // Required
startWithDelay?: StartWithDelay // Optional delay before the activity starts
}
Note:
sys_pd_activityalso has AI-agent fields (enableAiAgent,aiAgentObjective,aiAgentExecutionMode,aiAgentRunWithRoles,aiAgentRunAs,aiAgentUser,aiAgentObjAdditionalDetail,conversationalAgents,launchAgentWhenActivityStart). These are internal and not part of the authoring surface — they are preserved when youtransforman existing activity to Fluent, but are not intended to be set by hand.
Properties:
-
$id (required):
Now.Internal.ExplicitKey | string | numberUnique identifier. -
label (required):
stringDisplay name. -
order (required):
numberDisplay order within the parent scope (lane for in-lane activities, lanes body for stage-level Decision activities). -
startRule (required):
ActivityExecutionRulewfa.playbook.run.Immediately()— no dependencies;wfa.playbook.run.After(...deps)— starts after all listed dependencies complete. -
restartRule (required):
'RUN_ONLY_ONCE' | 'RUN_ALWAYS' | 'RUN_ONLY_ON_RESTART''RUN_ONLY_ONCE': skipped on restart;'RUN_ALWAYS': re-runs on restart;'RUN_ONLY_ON_RESTART': skipped on first run, runs only on restart. -
name (optional):
stringInternal name. If provided, used verbatim; otherwise auto-generated fromlabel. See Field notes below for details. -
description (optional):
stringDescription. -
conditionToRun (optional):
stringEncoded query evaluated at runtime. -
startWithDelay (optional):
StartWithDelaySame shape asLaneConfig.startWithDelay— delays the activity start afterstartRuleis satisfied.
Field notes:
name— Optional internal name. If provided, it is used verbatim. If omitted, it is slugified fromlabeland deduplicated across sibling activities within the same lane. Thenameis the activity's stable identity — once deployed, ideally do not change it on subsequent edits, as a changednameis treated as a new activity rather than an update to the existing one.lane— Automatically set to the parent lane's sys_id.process_definition— Automatically set to the playbook's sys_id.active— Defaults totrue.
Decision Activity
The Decision activity evaluates an ordered list of branch conditions and routes execution to matching branches.
wfa.playbook.activity(
ActivityDefinitions.Core.Decision,
{ $id: Now.ID['decision_route'], label: 'Route by Priority', order: 1, startRule: wfa.playbook.run.Immediately() },
{
type: 'match_first', // 'match_first' | 'match_all'
branches: [
{ id: 'critical', label: 'Critical', condition: `${wfa.playbook.dataPill(params.inputs.record.priority)}=1` },
{ id: 'high', label: 'High', condition: `${wfa.playbook.dataPill(params.inputs.record.priority)}=2` },
{ id: 'else', label: 'Else' }, // ELSE branch - must be last, no condition
],
},
)
DecisionInputs properties:
-
type (required):
'match_first' | 'match_all'Branch selection mode.match_firstruns only the first matching branch;match_allruns every matching branch in parallel. -
branches (required):
DecisionBranch[]Ordered list of branches. Branch display order follows array position.
DecisionBranch properties:
-
id (required):
stringUnique identifier within the decision. Used indecision.branches.<id>references inwfa.playbook.run.After().'else'is reserved for the fallback branch. -
label (required):
stringDisplay name. For theelsebranch this must be the exact string'Else'. -
condition (optional):
stringEncoded query with optional data pills. Omit for theelsebranch.
ELSE branch: id: 'else', label: 'Else' (exact string), must be the last entry in branches, no condition.
Branch IDs are typed automatically in wfa.playbook.run.After(...). See playbook-anti-patterns-guide for the as const convention and playbook-guide for branching examples.
wfa.playbook.run Namespace
Execution rule helpers used in startRule properties on lane and activity configs. Accessed via the wfa namespace imported from @servicenow/sdk/automation.
import { wfa } from '@servicenow/sdk/automation'
wfa.playbook.run.Immediately()
Activity or lane starts immediately with no dependencies.
wfa.playbook.run.Immediately(): ExecutionRule
Use for the first activity in a lane or the first lane in a playbook.
wfa.playbook.run.After(...deps)
Activity or lane starts after all specified dependencies complete.
wfa.playbook.run.After(...deps: Dependency[]): ExecutionRule
Accepts varargs (not an array). Each argument can be an ActivityInstance, ActivityReference, LaneReference, or BranchReference.
// Single dependency
startRule: wfa.playbook.run.After(validate)
// Multiple dependencies (all must complete)
startRule: wfa.playbook.run.After(notify, log)
// Lane-level dependency
config: { ..., startRule: wfa.playbook.run.After(intake) }
// Branch dependency (Decision activity)
startRule: wfa.playbook.run.After(routeCase.branches.critical)
wfa.playbook.dataPill()
Creates runtime references to playbook data for use in trigger mappers, activity inputs, experience properties, conditions, and timer fields.
wfa.playbook.dataPill(reference: DataReference): string
See playbook-datapills-guide for additional details on usage, what is allowed in pills, and where pills are allowed.
Type Definitions
Run Namespace
declare namespace Run {
function Immediately(): LaneExecutionRule & ActivityExecutionRule
function After(...deps: Dependency[]): LaneExecutionRule & ActivityExecutionRule
}
Both helpers return a value assignable to either LaneConfig.startRule or ActivityConfig.startRule.
ExecutionRule
interface LaneExecutionRule {
readonly __laneExecutionRule: true
}
interface ActivityExecutionRule {
readonly __activityExecutionRule: true
}
type ExecutionRule = LaneExecutionRule | ActivityExecutionRule
Dependency
type Dependency = ActivityInstance<any> | ActivityReference | LaneReference | BranchReference
ActivityInstance
interface ActivityInstance<TBranches = never> extends ActivityReference {
readonly branches: TBranches
}
outputs, state, and sysId come from ActivityReference. branches is never for non-Decision activities and a record of typed BranchReferences for Decision activities.
ActivityReference
interface ActivityReference {
readonly __activityRef: true
readonly outputs: any
readonly state: string
readonly sysId: string
}
LaneReference
interface LaneReference {
readonly __laneRef: true
}
BranchReference
interface BranchReference {
readonly __branchRef: true
readonly id: string
}
PlaybookTriggerTypes Namespace
namespace PlaybookTriggerTypes {
const RecordCreate: PlaybookTriggerType
const RecordUpdate: PlaybookTriggerType
const RecordCreateOrUpdate: PlaybookTriggerType
const Scheduled: PlaybookTriggerType
}
ActivityDefinitions Namespace
namespace ActivityDefinitions {
namespace Core {
// Interactive
const Instruction: ActivityDefinition
const TwoStepInstruction: ActivityDefinition
const RecordForm: ActivityDefinition
const NewRecordForm: ActivityDefinition
const AutocompletingRecordForm: ActivityDefinition
const KnowledgeArticle: ActivityDefinition
const ChecklistTask: ActivityDefinition
// Automation
const UpdateRecord: ActivityDefinition
const CreateNewRecord: ActivityDefinition
const NewRecordFormWithList: ActivityDefinition
const SendEmail: ActivityDefinition
const EmailForm: ActivityDefinition
const WaitForCondition: ActivityDefinition
const Placeholder: ActivityDefinition
// Approval
const RequestManagerApproval: ActivityDefinition
const RequestAdHocApproval: ActivityDefinition
const AskForMultiLevelApproval: ActivityDefinition
// Branching
const Decision: DecisionActivityDefinition
// List
const RecordList: ActivityDefinition
}
}
Definition source: src/api/playbook/built-ins/activity-definitions/index.ts.
Data Model Mapping
| Fluent Concept | ServiceNow Table | Key Fields |
|---|---|---|
PlaybookDefinition config | sys_pd_process_definition | label, name, description, status, run_strategy, etc. |
wfa.playbook.trigger() | sys_pd_trigger_instance | trigger_type, trigger_inputs, launcher_inputs |
| Lane | sys_pd_lane | label, name, order, description, start_rule_name, starts_after_lanes, condition_to_run, restart_rule, permission |
Lane or Activity startWithDelay | sys_pd_timer_attributes | source (FK to lane or activity), source_type (sys_pd_lane or sys_pd_activity), duration_type, timer_duration, timer_relative_duration_datetime, etc. |
wfa.playbook.activity() config | sys_pd_activity | activity_definition, label, name, order, lane (auto-set), process_definition (auto-set), start_rule, etc. |
wfa.playbook.activity() inputs/experienceProperties | sys_variable_value | document, document_key, variable, value |
wfa.playbook.dataPill() in inputs/experienceProperties | sys_element_mapping | field, id, table, value |
inputs | sys_pd_process_input | (extends var_dictionary) |
outputs | sys_pd_process_output | (extends var_dictionary) |
See
Examples
Example with 1 trigger
import { PlaybookDefinition, PlaybookTriggerTypes, ActivityDefinitions } from '@servicenow/sdk/automation'
import { wfa } from '@servicenow/sdk/automation'
PlaybookDefinition(
{
$id: Now.ID['p1_incident_notes'],
label: 'P1 Incident Notes',
name: 'p1_incident_notes',
parentTable: 'incident',
},
{
triggers: [
wfa.playbook.trigger(
PlaybookTriggerTypes.RecordCreate,
{ $id: Now.ID['p1_trig'], label: 'On P1 Incident' },
{ table: 'incident', condition: 'priority=1' }
),
],
},
{
lanes: (params) => ({
stamp_note: wfa.playbook.lane({
config: {
$id: Now.ID['p1_lane'],
label: 'Stamp Note',
order: 1,
startRule: wfa.playbook.run.Immediately(),
restartRule: 'RUN_ONLY_ONCE',
},
activities: () => {
const stamp = wfa.playbook.activity(
ActivityDefinitions.Core.UpdateRecord,
{
$id: Now.ID['p1_act'],
label: 'Stamp Note',
order: 1,
startRule: wfa.playbook.run.Immediately(),
restartRule: 'RUN_ONLY_ONCE',
},
{
table_name: 'incident',
record: wfa.playbook.dataPill(params.parentRecord),
values: TemplateValue({ work_notes: 'Priority 1 received'}),
}
)
return { stamp: stamp }
},
}),
}),
}
)
Example with 1 trigger and inputs and outputs
import { PlaybookDefinition, PlaybookTriggerTypes, ActivityDefinitions } from '@servicenow/sdk/automation'
import { wfa } from '@servicenow/sdk/automation'
import { ReferenceColumn, IntegerColumn, StringColumn } from '@servicenow/sdk/core'
PlaybookDefinition(
{
$id: Now.ID['p1_incident_notes_with_inputs_outputs'],
label: 'P1 Incident Notes with Inputs and Outputs',
name: 'p1_incident_notes_inputs_outputs',
parentTable: 'incident',
inputs: {
record: ReferenceColumn({
label: 'Record',
referenceTable: 'incident',
mandatory: true,
}),
priority: IntegerColumn({
label: 'Priority Override',
default: 3,
}),
summary: StringColumn({
label: 'Summary',
maxLength: 1000,
}),
},
outputs: {
resolvedBy: ReferenceColumn({
label: 'Resolved By',
referenceTable: 'sys_user',
}),
closureCode: StringColumn({
label: 'Closure Code',
maxLength: 40,
}),
},
},
{
triggers: [
wfa.playbook.trigger(
PlaybookTriggerTypes.RecordCreate,
{ $id: Now.ID['p2_trig_inp_out'], label: 'On P2 Incident Creation' },
{ table: 'incident', condition: 'priority=2' }
),
],
},
{
lanes: (params) => ({
stamp_note: wfa.playbook.lane({
config: {
$id: Now.ID['p2_lane'],
label: 'Stamp Note',
order: 1,
startRule: wfa.playbook.run.Immediately(),
restartRule: 'RUN_ONLY_ONCE',
},
activities: () => {
const stamp = wfa.playbook.activity(
ActivityDefinitions.Core.UpdateRecord,
{
$id: Now.ID['p2_act'],
label: 'Stamp Note',
order: 1,
startRule: wfa.playbook.run.Immediately(),
restartRule: 'RUN_ONLY_ONCE',
},
{
table_name: 'incident',
record: wfa.playbook.dataPill(params.parentRecord),
values: TemplateValue({ work_notes: 'Priority 2 incident received'}),
}
)
return { stamp: stamp }
},
}),
}),
}
)