Skip to main content

Automation: Extracting data

The first thing Susan Shönendankergutenabendskalbsfleischermeyer does now, is to keep track of the header data of the request. And our skill will do what Susan Shönendankergutenabendskalbsfleischermeyer does:

  • Keep note of the ID of the employee requesting the parental leave
  • Keep note of the full name of the employee

Making a new step

There's a step template at steps/_template.tsx. Duplicate it to a new file in the steps folder. In this step, we'll be extracting the request data, so a good name for it would be something like extractRequestDataStep:

src/steps/extractRequestDataStep.tsx
import {Context} from '@matterway/sdk';

export async function extractRequestDataStep(ctx: Context) {
console.log('step: extractRequestDataStep');

// Write your code here

const result = {};

console.log('step: extractRequestDataStep end', result);
return result;
}

Let's also update the start step so that it will call our new step:

src/steps/@start.tsx
import {extractRequestDataStep} from 'steps/extractRequestData';

export async function startStep(ctx: Context) {
// ...

const employee = await extractRequestDataStep(ctx);

await successStep(ctx);
}

Extracting data with SDK helpers

We want to extract the employee ID and full name from the request for use later. If we look at a ticket detail page, we can see a few <input> fields that contain the information we need. To get their content, we need to extract their value.

Inspect the content page as we did earlier during matching, and look up a good selector for those fields. This time, it seems that the name attribute could be a good match:

  • Employee ID -> [name="incident.employeeId"]
  • Employee name -> [name="incident.employeeFullName"]

To extract the value of the input we can use the SDK helper functions.

src/shared/types.ts
export interface EmployeeData {
id: string;
fullName: string;
}
src/steps/extractRequestData.tsx
import {Context, getValue, waitForSelector} from '@matterway/sdk';
import {EmployeeData} from 'shared/types';

export async function extractRequestDataStep(ctx: Context) {
console.log('step: extractRequestDataStep');

const id = (await getValue(ctx, '[name="incident.employeeId"]')) || '';
const fullName =
(await getValue(ctx, '[name="incident.employeeFullName"]')) || '';

const result: EmployeeData = {
id,
fullName,
};

console.log('step: extractRequestDataStep end', result);
return result;
}

Automations execute really fast, so before accessing any field, it's good practice to wait for a selector to become present first:

src/steps/extractRequestData.tsx
export async function extractRequestDataStep(ctx: Context) {
//...
await waitForSelector(ctx, '[name="incident.employeeId"]');
const employeeId = await getValue(ctx, '[name="incident.employeeId"]');
const employeeFullName = await getValue(
ctx,
'[name="incident.employeeFullName"]',
);
// ...
}

Adding progress indicators

While automation is pretty fast, unless the user is aware of what's going on, they'll think it got stuck.

Fortunately, adding an activity indicator is very simple with SDK. Running showProgress() will show a spinning loading indicator until overridden by another user interface instruction:

src/steps/extractRequestData.tsx
import {Context, showProgress, waitForSelector, getValue} from '@matterway/sdk';
import {t} from 'i18next';
import {EmployeeData} from 'shared/types';

export async function extractRequestDataStep(ctx: Context) {
// ...
showProgress(ctx, t('extractRequestData.progress'));
await waitForSelector(ctx, '[name="incident.employeeId"]');
const employeeId = await getValue(ctx, '[name="incident.employeeId"]');
const employeeFullName = await getValue(
ctx,
'[name="incident.employeeFullName"]',
);
// ...
}

Skill displaying the activity indicator

note

We don't await the activity indicator: it will never resolve. Don't worry: we can simply leave it pending, and run whatever automation we want. The next user interface will just override it.