Automation Cloud API Client
Status: beta (public interfaces are settled, but details may change)
- Official JavaScript/TypeScript client library for Automation Cloud API.
- Works in NodeJS 12+ and latest browser environments.
- Full TypeScript support.
Usage
Prerequisites
- Sign up for Automation Cloud account.
- Create a Service in AC Dashboard and publish a script to it from Autopilot.
- Create an Application in Dashboard to obtain authentication details.
npm i @automationcloud/client
Quick start
import { Client } from '@automationcloud/client';
const client = new Client({
serviceId: 'service-uuid-from-dashboard',
auth: 'app-secret-key',
});
const job = await client.createJob({
inputs: { ... }
});
const [output1, output2] = await job.waitForOutputs('output1', 'output2');
await job.waitForCompletion();
Please refer to Robot School to learn more about scripting.
Job
Job is a high level abstraction that allows you to think about your automations in terms of inputs, outputs and state updates.
Creating the job
const job = await client.createJob({
category: 'test' | 'live',
input: {
foo: { arbitrary: 'data' }
},
});
Job runs immediately after creation.
Note: it is not required to pre-supply all inputs that script expects. Whenever script uses an input that hasn't been provided, it will produce an awaitingInput
event and will only continue once the requested input is submitted. See deferred inputs for more information.
Waiting for completion
The Job instance tracks lifecycle events up to the point when the job is either finished successfully or failed with an error. waitForCompletion
resolves or rejects when the tracking is over.
await job.waitForCompletion();
Note: always make sure to include await job.waitForCompletion()
to prevent dangling promises or unhandled promise rejections.
Waiting for outputs
Outputs provide a mechanism to receive the results that script produces. This can be the results of web page scraping, or collected options, or any other information retrieved by the script.
Job offers a convenient way of waiting for the outputs you expect from your script:
const [products, deliveryOptions] = await job.waitForOutputs('products', 'deliveryOptions');
In other scenarios it might be more practical to use event-based API to get notified when a particular output is emitted:
job.onOutput('myOutputKey', async () => {
});
Deferred inputs
Inputs provide a mechanism of passing the information to the script.
Some inputs are known upfront so it makes sense to specify them when the job is created.
Other inputs cannot be pre-supplied. For example, the website may ask its users to select a delivery option — in such case the script would first collect the available options and emit them as an output and subsequently request the selected option via an input.
job.onAwaitingInput('selectedDeliveryOption', async () => {
return { option: 3 };
});
A special *
key can be used to subscribe to all requested inputs with a single handler:
job.onAwaitingInput('*', requestedInputKey => {
});
If the handler doesn't return a value, the input is not submitted:
job.onAwaitingInput('selectedDeliveryOption', () => {
});
Inputs can also be submitted individually at any point in time whilst the job is still running:
await job.submitInput('selectedDeliveryOption', { option: 3 });
Events
You can also subscribe to various job lifecycle events.
job.onSuccess(async () => { ... });
job.onFail(async err => { ...});
job.onOutput(outputKey, async outputData => { ... });
job.onAnyOutput(async (outputKey, outputData) => { ... });
job.onStateChanged(async newState => { ... });
To unsubscribe for event:
const unsubscribe = job.onSuccess(() => { ... });
unsubscribe();
Note 1: All callbacks are asynchronous. Exception thrown inside a callback will result in an unhandled rejection.
Note 2: It is advisable to not depend on the order of the events, because they can vary between different engine versions, between scripts and even within one script (i.e. depending on some script logic).
Note 3: As with all event-based APIs it is possible to miss the event if the subscription is done after the event has already emitted.
License
See LICENSE.