Implement an activity that creates a QR Code image using a Third Party Library

Implementing a custom activity allows you to build a reusable, completely custom behavior to augment the existing activities that come with Geocortex Workflow.

In this article, you will learn how to create a custom activity that generates a QR code image as a data URL using a third party library.

Prerequisites#

Follow the instructions in the Web Applications SDK page to set up your development environment.

note

A working knowledge of TypeScript is recommended before extending Workflow for web-based hosts.

Overview#

Implementing a QR code activity for web applications using a third party library consists of the following steps:

  1. Adding third party library dependencies to your project.
  2. Creating the custom activity.
  3. Implementing the custom activity using the third party library.

Adding Dependencies#

  1. Run npm install qrcode in the terminal to install the third party qrcode library that generates QR codes.
  2. Run npm install @types/qrcode in the terminal to install type information for the third party library. This is optional, but it provides an improved developer experience.

Set up Activity Skeleton#

To create a new activity:

  1. Open the Workflow activity SDK in Visual Studio Code
  2. Run npm run generate in the terminal.
  3. When prompted enter the name of the activity you would like to create and press Enter. For example, CreateQrCodeImage.
  4. Open the newly created src/activities/CreateQrCodeImage.ts file.

Implement the Activity#

Modify the skeleton activity implementation in src/activities/CreateQrCodeImage.ts to match the following example which provides a minimal QR code implementation.

src/activities/CreateQrCodeImage.ts
import type { IActivityHandler } from "@geocortex/workflow/runtime/IActivityHandler";
import QRCode, { QRCodeToDataURLOptions } from "qrcode";
/** An interface that defines the inputs of the activity. */
export interface CreateQrCodeImageInputs {
/**
* @description The text to encode into the QR code.
* @required
*/
text: string;
}
/** An interface that defines the outputs of the activity. */
export interface CreateQrCodeImageOutputs {
/**
* @description The data URL of the resulting the QR code image.
*/
result: string;
}
/**
* @displayName Create QR Code Image
* @category Custom Activities
* @defaultName qrCode
* @description Creates a QR code image as a data URL.
*/
export class CreateQrCodeImage implements IActivityHandler {
async execute(
inputs: CreateQrCodeImageInputs
): Promise<CreateQrCodeImageOutputs> {
const { text } = inputs;
// Generate the QR code
const dataUrl = await QRCode.toDataURL(text);
return {
result: dataUrl,
};
}
}

Deploy the Activity#

Follow the instructions to build and deploy the activity pack.

Test the Activity#

Once your activity pack is hosted and registered, your custom activity should appear in the activity toolbox in Geocortex Workflow Designer alongside the built-in activities, and can be used in the graphical interface like any other activity.

tip

The result output of the activity is a data URL. You can use the Set Form Element Property activity to assign the URL to the value property of an Image form element.

Now you can build a workflow that uses your new custom activity!

Enhance the Activity#

Once you've seen your activity in action you may want to take advantage of the many different options offered by the qrcode library. To do this you can add additional inputs to the activity that correspond to options on the QRCode.toDataURL(text: string, options?: QRCodeToDataURLOptions) method.

Modify the previous activity implementation in src/activities/CreateQrCodeImage.ts to match the following more complete example.

src/activities/CreateQrCodeImage.ts
import type { IActivityHandler } from "@geocortex/workflow/runtime/IActivityHandler";
import QRCode, { QRCodeToDataURLOptions } from "qrcode";
/** An interface that defines the inputs of the activity. */
export interface CreateQrCodeImageInputs {
/**
* @description The text or data to encode into the QR code.
* @required
*/
text:
| string
| {
data: string;
mode: "alphanumeric" | "numeric" | "kanji" | "byte";
}[];
/**
* @description The RGBA color of the dark module. The default is #000000ff (black).
*/
darkColor?: string;
/**
* @description Error correction level. The default is medium.
*/
errorCorrectionLevel?: "low" | "medium" | "quartile" | "high";
/**
* @description The RGBA color of the light module. The default is #ffffffff (white).
*/
lightColor?: string;
/**
* @description The size of the quiet zone around the QR code. The default is 4.
*/
margin?: number;
/**
* @description A Number between 0 and 1 indicating image quality if the requested type is image/jpeg or image/webp. The default is 0.92.
*/
quality?: number;
/**
* @description The Scale factor. A value of 1 means 1px per modules (black dots). The default is 4.
*/
scale?: number;
/**
* @description The image format. The default is image/png.
*/
type?: "image/png" | "image/jpeg" | "image/webp";
/**
* @description The width of the output image. If the width is too small to contain the QR code, this option will be ignored. This input takes precedence over the scale input.
*/
width?: number;
/**
* @description The QR Code version. A number between 1 and 40. If not specified, a suitable value will be calculated.
*/
version?: number;
}
/** An interface that defines the outputs of the activity. */
export interface CreateQrCodeImageOutputs {
/**
* @description The data URL of the resulting the QR code image.
*/
result: string;
}
/**
* @displayName Create QR Code Image
* @category Custom Activities
* @defaultName qrCode
* @description Creates a QR code image as a data URL.
*/
export class CreateQrCodeImage implements IActivityHandler {
async execute(
inputs: CreateQrCodeImageInputs
): Promise<CreateQrCodeImageOutputs> {
const { darkColor, lightColor, quality, text, ...other } = inputs;
// Assemble the QR code options from the activity inputs
const options: QRCodeToDataURLOptions = {
...other,
color: {
dark: darkColor,
light: lightColor,
},
rendererOpts: {
quality,
},
};
// Generate the QR code
const dataUrl = await QRCode.toDataURL(text, options);
return {
result: dataUrl,
};
}
}

Next Steps#

Learn how to create a QR Code form element

Learn how to to use this same third party library to create a form element that generates and displays QR codes