Tools: JavaScript Client Library in Use
Let's make an app to solve the challenge from the previous lesson.
Under the hood, an Automation Job will load a web-page, go through its content picking up the bits as prescribed by the Script, and produce the data for the app to display.
The Script for the Job gets published to the Automation Cloud and executes remotely. The app receives notifications about Job state updates, requested inputs and emitted outputs.
Job Prerequisites
With your Automation Cloud account:
- Create an Application to obtain authentication credentials (secret key).
- Save your Script to a Service in the Automation Cloud.
- Connect the Service and the Application.
Scripting part
Let's keep it simple yet illustrative. Here is the idea:
- Job navigates to this URL and emits the
ingredients
output for a user to review. - When a user provides an
ingredientToAvoid
input, Job can proceed with the data extraction. - Eventually, Job emits the
menu
output: a list of meals, excluding those with the ingredient to avoid, if any.
My result is in the sidebar on the right. Feel free to download and explore →
Coding part
JS Client library works in NodeJS 12+ and the latest browser environments.
Node example
Check the code below. Feel free to explore this interactive notebook , and observe how an Automation Job gets created, goes through a few state changes and finally outputs the data.
const { Client } = require('@automationcloud/client');
// Create Client instance
const client = new Client({
serviceId: '691030cf-57ae-47bc-b863-75e9a12f973e',
auth: process.env.SECRET_KEY // << Secret
});
// Create the Job. Let's start with no input whatsoever.
const job = await client.createJob();
// Subscribe to Job state updates to know what's happening.
job.onStateChanged(newState => console.log(`job: ${newState}`));
// Once the list of ingredients is ready...
job.onOutput('ingredients', async ingredients => {
console.log('output: ingredients', ingredients);
// Pick first and return to the Job as an input
const ingredientToAvoid = ingredients[0];
await job.submitInput('ingredientToAvoid', ingredientToAvoid);
console.log('input: ' + ingredientToAvoid);
});
// Wait for the Job to finish. Resolves once the job reaches
// the "success" state (e.g. enters a "success" context).
await job.waitForCompletion();
// And finally, let's get the "menu" output
const output = await job.getOutput('menu');
console.log('output: menu', output);
Browser example
There is a limitation with browsers: it's not ok to use authentication credentials (secrets), exposing sensitive information to the outside world. As a solution, consider the following two-step approach:
STEP 1: On the server-side, start the Job and obtain your Job specific accessToken
.
const { Client } = require('@automationcloud/client');
post('/', async (req, res) => {
const serviceId = '691030cf-57ae-47bc-b863-75e9a12f973e';
// Create Client instance
const client = new Client({
serviceId,
auth: process.env.SECRET_KEY // << Secret
});
// Create Job
const job = await client.createJob();
// Get access token
const accessToken = await job.getAccessToken();
// Respond with secure credentials
res.send({
serviceId,
jobId: job.jobId,
accessToken
});
});
Here is the interactive runkit notebook for you to explore.
STEP 2: In the browser, use serviceId
and accessToken
to create a Client instance, then pick up the Job by jobId
and proceed with all the things. Check the code below.
import { Client } from '@automationcloud/client';
// Call the endpoint to obtain credentials
const res = await fetch(
'https://school-menu-job-init-szydqtonfa6f.runkit.sh/',
{ method: 'POST' }
);
const { serviceId, jobId, accessToken } = await res.json();
// Create Client instance
const client = new Client({
serviceId,
auth: accessToken // << Your access token
});
// Pick up the Job
const job = await client.getJob(jobId);
// Proceed with the Job safely
job.onAwaitingInput('ingredientToAvoid', async () => await 'almond');
await job.waitForCompletion();
Here is a live example for you to play. It calls the endpoint based on the "Step 1: Start the Job" code to obtain credentials, then proceeds with all the other things front-end.