Custom Commands

Custom Commands extend Voice+ by allowing developers to define domain-specific, voice-driven commands that map directly to actions on the webpage or app. Instead of relying only on predefined Knowledge Base answers, Voice+ can listen for structured commands in real time and pass actionable payloads to the frontend SDK, where handlers carry out the requested behavior.

Overview

  • Custom Commands are powered by the Touchpoint SDK

  • Commands are defined using the setCustomBidirectionalCommands API

  • Each command has an action name, description, schema for validation, and handler function

  • Voice+ analyzes user utterances and matches them to registered commands

  • When a command matches, Voice+ returns a structured payload to the command handler

Quick Example

Here's a simple color selector command setup:

import { create } from '@nlxai/touchpoint-ui';
import * as z from 'zod/v4';

const COLOR_CHANGE_ACTION = 'changeColor';

const colorSchema = z.object({
  color: z.string().describe('The color to change to'),
});

function handleColorChange(payload: any) {
  document.body.style.backgroundColor = payload.color;
}

// Initialize touchpoint
const touchpoint = await create({
  config: {
    applicationUrl: 'YOUR_APPLICATION_URL',
    headers: { 'nlx-api-key': 'YOUR_API_KEY' },
    languageCode: 'en-US',
  },
  input: 'voiceMini',
  bidirectional: {},
});

// Register commands
touchpoint.setCustomBidirectionalCommands([
  {
    action: COLOR_CHANGE_ACTION,
    description: 'Change the background color',
    schema: colorSchema,
    handler: handleColorChange,
  }
]);

User says: "Change color to blue" → Handler executes and changes the background color.

Command Properties

Each command object passed to setCustomBidirectionalCommands supports these properties:

Property
Type
Required
Description

action

string

Yes

Unique identifier for the command

description

string

Yes

Human-readable description of what the command does

schema

ZodSchema

Yes

Zod schema for validating command payloads

handler

function

Yes

Function that executes when the command is triggered

Setup and Registration

Initialize Touchpoint and register custom commands:

import { create, TouchpointInstance } from '@nlxai/touchpoint-ui';
import * as z from 'zod/v4';

// Configuration constants
const NLX_APP_URL = 'https://bots.dev.studio.nlx.ai/c/YOUR_APPLICATION_URL';
const NLX_APP_API_KEY = 'your-api-key';
const DEFAULT_LANGUAGE = 'en-US';

let touchpointInstance: TouchpointInstance;

// Define schemas
const incrementSchema = z.object({
  amount: z.number().optional().describe('Amount to increment by'),
});

const colorSchema = z.object({
  color: z.string().describe('Color to change to'),
});

// Initialize Voice+
async function initializeTouchpoint() {
  try {
    const headers = { 'nlx-api-key': NLX_APP_API_KEY };
    
    touchpointInstance = await create({
      config: {
        applicationUrl: NLX_APP_URL,
        headers,
        languageCode: DEFAULT_LANGUAGE,
      },
      input: 'voiceMini',
      bidirectional: {},
    });
    
    // Register all commands after touchpoint is loaded
    touchpointInstance.setCustomBidirectionalCommands([
      {
        action: 'increment',
        description: 'Increment a counter by a specified amount',
        schema: incrementSchema,
        handler: (payload: any) => {
          const amount = payload.amount || 1;
          console.log(`Incrementing by ${amount}`);
        }
      },
      {
        action: 'changeColor',
        description: 'Change the background color',
        schema: colorSchema,
        handler: (payload: any) => {
          console.log(`Changing color to ${payload.color}`);
        }
      }
    ]);
    
    console.log('Voice+ initialized successfully');
  } catch (e) {
    console.error('Failed to initialize Voice+:', e);
  }
}

// Initialize on page load
initializeTouchpoint();

Schema Validation with Zod

Optionally, Use Zod schemas to define the expected structure of command payloads:

import * as z from 'zod/v4';

// Simple string parameter
const nameSchema = z.object({
  name: z.string().describe('The name to use'),
});

// Optional number parameter
const incrementSchema = z.object({
  amount: z.number().optional().describe('Amount to increment by'),
});

// Email validation
const emailSchema = z.object({
  email: z.string().email().describe('Valid email address'),
});

// Enum values
const colorSchema = z.object({
  color: z.enum(['red', 'blue', 'green']).describe('Color to apply'),
});

// Complex nested object
const filterSchema = z.object({
  category: z.string().optional().describe('Category to filter by'),
  price: z.object({
    min: z.number().optional(),
    max: z.number().optional(),
  }).optional().describe('Price range filter'),
});

// Register commands using these schemas
touchpointInstance.setCustomBidirectionalCommands([
  {
    action: 'greet',
    description: 'Greet a user by name',
    schema: nameSchema,
    handler: (payload: any) => {
      console.log(`Hello, ${payload.name}!`);
    }
  },
  {
    action: 'increment',
    description: 'Increment a counter',
    schema: incrementSchema,
    handler: (payload: any) => {
      const amount = payload.amount || 1;
      console.log(`Incrementing by ${amount}`);
    }
  },
  {
    action: 'sendEmail',
    description: 'Send an email to a valid address',
    schema: emailSchema,
    handler: (payload: any) => {
      console.log(`Sending email to ${payload.email}`);
    }
  },
  {
    action: 'changeTheme',
    description: 'Change the theme color',
    schema: colorSchema,
    handler: (payload: any) => {
      console.log(`Changing theme to ${payload.color}`);
    }
  },
  {
    action: 'filterProducts',
    description: 'Filter products by category and price',
    schema: filterSchema,
    handler: (payload: any) => {
      console.log('Filtering products:', payload);
    }
  }
]);

Common Use Cases

  • UI Interactions: Button clicks, form submissions, modal dialogs

  • Data Management: CRUD operations, filtering, sorting

  • Navigation: Page transitions, tab switching, section scrolling

  • Media Control: Play/pause, volume control, track selection

  • E-commerce: Add to cart, checkout, product filtering

Last updated