Only this pageAll pages
Powered by GitBook
1 of 15

SDK

Loading...

Loading...

Loading...

Reference

Loading...

Loading...

Loading...

Loading...

Loading...

Content Types

Loading...

Loading...

Loading...

Loading...

Loading...

LogicDialog SDK

Welcome to the SDK

The LogicDialog SDK is a Node JS project that allows you to construct replies to a conversation programmatically. By providing an SDK and using the Webhook functionality in the product your conversations can become much more dynamic and meaningful to your users.

Getting Started

The SDK is simple to use and so you'll be up and running in no time. If you are keen to dive in then take a look at our quick start guide.

Want to deep dive?

Dive a little deeper and start exploring our API reference to get an idea of everything that's possible with the API:

Quick Start
API Reference
All Content Types

Quick Start

On this page we'll get you setup using the SDK to provide a simple "Hello World" reply to a users message.

In this guide we are going to setup a simple web server that can respond to requests. This web server will be triggered using the "webhook" capability within logicdialog. There are just a few steps we'll need to take to get you all setup. These are as follows :

  1. Setting the Webhook URL settings

  2. Building some content that will trigger the webhook

  3. Setting up a project and creating an instance of the Webhook Client

  4. Adding functionality to the project to handle specific types of request

These steps are all described below.

Setting the webhook URL

In this example we are going to use ngrok to provide an internet accessible hostname. You will need to install ngrok first. Once installed open a command terminal and type

ngrok http <server port to expose>

In this case the <server port to expose> is going to be 8080.

The command will start and provide to URLs, one on http and the other on https. Make a note of the https URL as you will need this shortly.

Once you have the URL we'll need to add this to the settings in IA. To do this :

  1. Login to logicdialog

  2. Go to Settings -> Webhook

  3. Set Endpoint to the forwarding URI from ngrok

Please make a note of the JWT secret that is shown on the Webhook settings page. We'll use this to authenticate our requests later.

Building Content in IA

  1. Using Visual Bot Builder in logicdialog, add new Choice using plus buttons to the far left or right of the existing choices, or add to existing choice by using the plus button on said choice

  2. Choose New Block and then Function Block

  3. Give block a name, and pick module if applicable

  4. If function has not been implemented, leave Todo field ticked, and add Temporary Text, usually a description of function implementation, and add button to simulate response. If you want your webhook to receive an event when this block is hit by a user, "Todo" must be unchecked

  5. Pick Form from dropdown if applicable

  6. Pick Handler Name, note this as it is used when adding handlers to the WebhookClient

We will also need to...

  1. In logicdialog go to the Forms page

  2. Click add new form, and give form a descriptive title

  3. Add new question, or pick one from the question bank

    1. Give descriptive title to question

    2. Write question text, to be displayed when question is asked

    3. Pick input type given to the user, followed by data type

    4. A question can also be added to the question bank from the Question Bank tab

Creating a project and code

Install the library

The best way to interact with our API is to use one of our official libraries:

# Install via NPM
npm install --save @webuildbots/webuildbots-sdk

Setting up an express server

The webhook from IA will make an HTTP request to a webserver containing your application logic. This could be a number of things, including a serverless function however in this example we are going to use express to host our API. We can setup express using the following simple bits of code.

import { createServer } from 'http';
import express, { Request, Response } from 'express';
import { divisionHandler } from './handler';
import { WebhookClient } from '@webuildbots/webuildbots-sdk/lib/util/webhook-client';
import dotenv from 'dotenv';

// Load Webhook Secret, this can be found in IntelAgent settings
dotenv.config();

const secret = process.env['WEBHOOK_SECRET'] || '';

// WebhookClient used to run handlers, intialised with JWT token copied previously
const whClient: WebhookClient = new WebhookClient(secret);

// Add handler to the list of handlers in the Client, name must match the functions handler-name
whClient.addHandler('division-handler', divisionHandler);

// Function to getToken from request, used to authorise request and secret
function getToken(request: Request): string {
  const token = request.headers.authorization?.split('Bearer ')[1];
  if (!token) {
    throw Error('No token found');
  }
  return token;
}

const app: express.Application = express();

// Text body-parser, as handleRequest function takes body from request as a string
// Content-type of request is plaintext, which is parsed by the handleRequest function
app.use(express.text());

// This should match the endpoint set in IntelAgent
app.post('/', async (req: Request, res: Response) => {
  // handleRequest returns a JSON object and a statusCode
  const { status, body } = await whClient.handleRequest(
    req.body,
    getToken(req)
  );
  res.status(status).send(body);
});

const server = createServer(app);
server.listen(8080);

This example will allow us to POST data to the / endpoint running on port 8080. First we create an instance of the WebhookClient which will allow us to handle the request and return various values back to the user. You'll notice on line 13 we construct a handler which will handle the division-handler requests. By adding this handler we can build an application that can handle different requests from different parts of the application, each one using a different name that is set in IA on a block by block level. On line 36 the webhook client will handle the request - specifically looking for a handler that matches the incoming requests handle name.

Make your first hander

A webhook handler is a simple function that will be called any time a block is triggered from IA. Its passed the webhookReq object which represents the information in the conversation, and a responseBuilder that helps you construct a reply to the user.

The following example shows a simple case where one number is divided by another, and an error is thrown if this combination of numbers provides a divide by zero error. A plain text message will be sent back to the user containing the answer.

export const divisionHandler: WebhookHandler = async (
  webhookReq: WebhookRequest,
  responseBuilder: ResponseBuilder
): Promise<void> => {
  // read values from the form completed by the user before the call over the webhook was made
  const { value: baseNumber } = webhookReq.formValue.baseNumber;
  const { value: divisionNumber } = webhookReq.formValue.divisionNumber;

  if (divisionNumber.value === 0) {
    responseBuilder.functionFailure(failureParams);
    return;
  }

  const resultNumber = baseNumber / divisionNumber;

  responseBuilder.pushBlockPointer(resultBlock);

  const basicBB = new BasicBB()
    .addText(Languages.ENGLISH, `${resultNumber}!`)
    .pushChoice(backToMenu());

  responseBuilder
    // Add the block to the response
    .pushBlock(basicBB)
    // Reset the form values after the response is sent to the user
    .unsetFunctionForm();
};

For more information please see the following pages :

WebhookClient
ResponseBuilder

BlockPointer

Using a BlockPointer you can route the conversation to different blocks, potentially to handle different questions or continue the next steps.

A BlockPointer points to an already existing Block using the Block Id, found in logicdialog.

Where possible this method should be used as it allows for block content to be edited easily without having to deploy changes to your code.

A block pointer is a simple object containing the ID of the block you wish to link to. In the example below, the ID of this block would be 5c62ead3ab358c3780bb60dc.

To use a BlockPointer, the pushBlockPointer function in the ResponseBuilder is used, with a BlockPointer object, containing the id of a block. This block can be a basic block, or a function block.

responseBuilder.pushBlockPointer({
  id: "60db2d02d19a13bc109c5bd4"
});

For further reference on the ResponseBuilder, please see the API page.

Basic Text

Initialise a new instance of BasicBB to start building a block.

Add text with the addText function, specifying a Language with the Languages Enum, if the text needs to be translated to different languages, do addText for each language. Here the text added is the result of the calculation done earlier

Error Handling

Errors can happen, and so by including an error handler in your response processing we can ensure that users are always informed.

If an input is invalid, or another error is caught, the responseBuilder can return a functionFailure,

The failureParams object is a particular type used to indicate how to handle the error. It contains an error BlockPointer, pointing to a block with an error message, as well as two optional fields, resetForm and tryAgain, defaulting to true.

resetForm indicates that the form should be unset, similarly to the unsetFunctionForm function

tryAgain offers a button to try again if true

For example, in the division handler, one such case of invalid input, is a divide by zero error. This is a number that cannot be divided by as of yet, so that number is checked early in the function, before further logic.

All Content Types

A number of content types are available when using the SDK. These are as follows :

ResponseBuilder
Basic Text
Choices
URL Buttons
Galleries
if (divisionNumber.value === 0) {
    responseBuilder.functionFailure(failureParams);
    return;
}

URL Buttons

The UrlCB works similarly to the BlockCB as a choice, however rather than point to a Block, it contains a URL.

Galleries

The GalleryBB is used to show a list of elements, such as an array of products, or when info should be displayed in a particular way Each item in the GalleryBB is built using the ItemBuilder.

The ItemBuilder is used similarly to the BasicBB, in that a title, text, and Choices can be added They differ in the additional features, such as being able to contain an image, from a URL, and adding a subtitle.

If multiple items are added, each of these Items are be displayed in a Carousel, letting the user flip through them like a book, to find what they are looking for.

Choices

A block can also contain buttons, or Choices. These can be added using the pushChoice function to push a ChoiceBuilder Block, of which there are several, depending on need. UrlCB links to a URL, BlockCB points to a BlockId. Here a button, that leads points back to the Menu, is added to the BasicBB with the result string

basicBB.pushChoice(
    new BlockCB("60e2b7f2ba7625f3fb73dd56")
        .addTitle(Languages.ENGLISH, "Back to Menu")
);

Some Choices that are used quite often, including the one above, has been pre-built so there is no need to build it repeatedly.

basicBB.pushChoice(backToMenu());
const basicBB = new BasicBB();
basicBB.addText(Languages.ENGLISH, `${resultNumber}!`);
/**
 * BlockPointer containing block id found in IntelAgent
 */
const errorBlock: BlockPointer = {
  id: '60db2d02d19a13bc109c5bd4'
};

/**
 * Function failure params used to handle errors, for example in the case of bad data
 */
const failureParams: FunctionFailureParams = {
  errorBP: errorBlock,
  resetForm : true,
  tryAgain : true
};

responseBuilder.functionFailure(failureParams);
basicBB.pushChoice(new UrlCB()
  .addTitle(Languages.ENGLISH, "Google")
  .addUrl(Languages.ENGLISH, "https://www.google.com/"));
const complexBB = new ComplexBB();
const ib = new ItemBuilder();
ib.image("<url>")
ib.addSubtitle(Languages.ENGLISH, "subtitle text")

complexBB.pushItem(ib)

API Reference

Dive into the specifics of each API endpoint by checking out our complete documentation.

API Reference

All the methods associated with CRUDing some pets. Which isn't as weird as it sounds:

WebhookClient

The WebhookClient is the entrypoint into the SDK. Here we can setup handlers that will respond to various events from the bot.

A WebhookClient is instantiated using the JWT Secret found in logicdialog. This is used to call the handler function.

There are two main methods on the Webhook client - handleRequest and addHandler

handleRequest

The handleRequest function is called from within a code that has been setup to handle HTTP requests made to your application. This might be part of an express route, or some other process. The function is passed two arguments. The first of these arguments is the body of the HTTP request which has originated from logicdialog. The second argument provides the authorization token used on the incoming request. This token is used to verify the payload that has been sent has not been modified in transit.

Examples of these function calls are provided below.

addHandler

The addHandler function allows you to specify a function that can be run to process the data coming in from logicdialog. Much like event subscriptions, this handler is associated with a specific name and as such you can add multiple handlers to a webhook client so that they can handle different types of events from your bot.

The handler that you create is an asynchronous function that accepts two parameters - a WebhookRequest object and a link to a ResponseBuilder.

A new WebhookHandler is initiated as follows :

Once you have created a handler, you can add it to your webhook client using the addHandler method.

In the example above, only forms in logicdialog that have a handler specified as division-handler will trigger the function.

Inside the function you can find the parameters that have been set in the conversation within the webhookReq object. Each form will differ depending on the number and type of questions that are asked to the user however the following example shows how you might access two values of a form.

The formValues in the example are structured as the following interface:

For more information about constructing a reply to the user, please see the ResponseBuilder section.

WebhookClient
BlockPointer
ResponseBuilder
Error Handling
export const divisionHandler: WebhookHandler = async (
  webhookReq: WebhookRequest,
  responseBuilder: ResponseBuilder
  ): Promise<void> => {
    // Logic goes here
}
whClient.addHandler('division-handler', divisionHandler);
const {value: baseNumber} = webhookReq.formValue.baseNumber;
const {value: divisionNumber} = webhookReq.formValue.divisionNumber;
{
  baseNumber: {
    title: string,
    value: string
  },
  divisionNumber: {
    title: string,
    value: string
  }
}
export const whClient: WebhookClient = new WebhookClient('secret');
// This should match the endpoint set in IntelAgent
app.post('/', async (req: Request, res: Response) => {
  // handleRequest returns a JSON object and a statusCode
  const { status, body } = await whClient.handleRequest(
    req.body,
    getToken(req)
  );
  res.status(status).send(body);
});
function getToken(request: Request): string {
  const token = request.headers.authorization?.split('Bearer ')[1];
  if (!token) {
    throw Error('No token found');
  }
  return token;
}
ResponseBuilder

ResponseBuilder

The ResponseBuilder can store multiple Blocks and BlockPointers, to be displayed in the Chat Bot, in the order they were added to the response. If a Form was used, it may be necessary to unset it once finished, letting the user trigger the function again, with different input

responseBuilder.unsetFunctionForm();

Sample Project

Along with the Quick Start pages, we've also provided a sample project via gitlab which can help you get up and running. This project is designed as as Google Cloud Function meaning that it'll only be running for the times that it needs to be used. You can find out more about cloud functions here.

Within the project you'll find the following folders :

  • src - this is the main folder for the project. All of your application logic should go in here.

    • src/config - here we've provided a way of allowing you to swap configuration variables between environments.

    • src/const - Any constants that might be used in your code. As an example we provide const variables for environment.

    • src/handlers - This contains the logic for your function and will be the entry point for the function.

    • src/model - this provides a utility function to help manage the configuration between environments.

    • src/util - a few other utility functions that you might find useful.

  • scripts - add any build scripts you need in here. We've provided one script in this folder to help get your environment variables into you project.

  • package.json - As a NodeJS project, this file determines the tasks that you can run, as well as any dependancies you might need for your application.

  • tsconfig.json - This is the configuration for the TypeScript files.

  • webpack.config.js - This is the configuration for Webpack

Setup

To get the project running you will first need a NodeJS environment on your computer. We'd recommend using Node Version Manager or nvm for short to help you manage the various different versions of NodeJS to install.

The page above provides instructions for installing nvm. Once installed, we recommend a version 12.x of NodeJS. You can install this on your computer by running nvm install 12.

Building the Project

The file contains all the various scripts and commands you will need to build the source code into an executable format.

To start with you'll need to run npm install from within the project folder to install all the external dependancies listed in the package.json. These dependancies will include TypeScript.

The project source code is written in TypeScript however as part of the build process we compile the typescript into normal JavaScript. This is done using the tsc command. As defined in the package.json file, we have provided a watch command which will run this command with the -w flag so that it automatically builds any modified files in the source directory. Depending on how you are working you can either run tsc once, or npm run watch to build the files as they change.

If you are running npm run watch its useful to do this in a different terminal window so that you can also start the cloud function in another.

The result of the tsc command will be a series of files in the .build folder which mirror that of the src folder, but are .js files rather than .ts files. It is these files that are used to run the cloud function.

Running the Cloud Function

To start the cloud function, use npm start. This will use the functions-framework tool that emulates what it will be like running the function via Google Cloud. This process will start the webserver and expose the application on typically port 8080. This means that once running you should be able to send network requests to your application via http://localhost:8080

Note that the application itself doesn't provide any user interface and so accessing that URL via a browser will not work.

As mentioned in the documentation, to test this when running locally you will need something like ngrok to make your local application available to the internet. You can read more about that here. Once you have done this, or if the application is deployed to a public URL then you can modify the settings of your digital assistant to point to it.

Package & Deploy

Also provided within the package.json file is a build task that will help you package the files in an appropriate format for a live environment. This process will combine all the files into one, and "minimise" them so that they can be transferred and loaded as quick as possible. To run this process use npm run build. The output of this task will be in the .webpack folder and will be essentially an index.js file, along with a package.json file.

As each environment is different we have not provided samples to help you deploy your application to something like Google Cloud, however if you have followed the steps above then you should have everything you need. For reference, the documentation for Google Cloud is below.

In this context, we would use the following command to deploy this project, however please adapt this to suit your needs.

gcloud functions deploy sample_project --source=.webpack --entry-point handler --runtime nodejs12 --trigger-http --allow-unauthenticated --region europe-west2

If you have used environment variables with your application then we'd recommend the use of a env.yaml file to provide the variables to the Cloud environment. More information is available below.

To make use of this file, simply add --env-vars-file env.yaml to the end of the deployment command line options.

GitHub - nvm-sh/nvm: Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versionsGitHub
Deploying from Your Local Machine  |  Cloud Functions Documentation  |  Google CloudGoogle Cloud
WebhooksIntelAgent
Using Environment Variables  |  Cloud Functions Documentation  |  Google CloudGoogle Cloud
Logo
Logo
Logo
Logo