npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@webuildbots/webuildbots-sdk

v11.5.0

Published

webuildbots sdk

Downloads

432

Readme

[[TOC]]

Getting started with the Webuildbots sdk

Connecting IA to your server

1. Use ngrok to expose your server

  1. Download and Install ngrok
  2. Use the command ngrok http <server port to expose> in terminal or cmd
  3. Note the HTTPS Forwarding URI

2. Configure Webhook settings in IntelAgent

  1. Login to IntelAgent
  2. Go to Settings -> Webhook
  3. Set Endpoint to the forwarding URI from ngrok
  4. Note JWT Secret

3. Setup and use WebhookClient (See also the Division example)

  1. Initialise instance of WebhookClient from the sdk, providing JWT Secret as argument, to authenticate
  2. Find handler-name from function block in IA
  3. handleRequest from Client, with the body of the event from the function block as stringified json, as well as the token
  4. Return response from handleRequest

4. Creating a function

  1. Using Visual Bot Builder in IntelAgent, 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

5. Adding a form to our function

  1. In IntelAgent go to the Forms tab
  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

6. Create function Handler

  1. Create instance of WebhookHandler
  2. Add logic to handler
  3. Add handler to Client using addHandler(<handler-name>, handler)

A Handler is a container for logic, which is run when the Client receives a request for the specified function One handler is usually equivalent to one function

Implementing a handler

This is an example of a Handler implementation, final implementation can be found in the divide example project For this case, the handler takes two number values from a Form created in IntelAgent, divides one with the other, and sends a block with the answer to the ChatBot

First a WebhookClient is instantiated, using the JWT Secret. This is used to call the handler function

    export const whClient: WebhookClient = new WebhookClient('secret');

Then a new WebhookHandler is initiated

    export const divisionHandler: WebhookHandler = async (
    webhookReq: WebhookRequest,
    responseBuilder: ResponseBuilder
    ): Promise<void> => {
        // Logic goes here
    }

The WebhookHandler has two argument values, the WebhookRequest and the ResponseBuilder

The WebhookRequest is where information and data from the request is found, such as FormValues, if a form was used. In this case there are two values from a Form

    const {value: baseNumber} = webhookReq.formValue.baseNumber;
    const {value: divisionNumber} = webhookReq.formValue.divisionNumber;

The above FormValues are structured as the following interface:

    {
        baseNumber: {
            title: string,
            value: string
        },
        divisionNumber: {
            title: string,
            value: string
        }
    }

Generally all Forms are structured similarly, containing the title and value of the question

Then the logic is implemented, in this case the result is the baseNumber divided by divisionNumber

    const resultNumber = baseNumber / divisionNumber;

The ResponseBuilder is how responses are sent back to the chat bot.

The ResponseBuilder takes two different response types, Blocks and BlockPointers

BlockPointer

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

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.

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

With the logic and result in hand, a BlockPointer is added to the responseBuilder, this points to a block containing the message "Ah, the result is...", to be displayed before the result is shown to the user

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

Building Blocks

Blocks can otherwise be built at run-time, using a subclass of BlockBuilder these classes can be found within the sdk and are suffixed with BB e.g. BasicBB

BasicBB

Basic block example

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

    const basicBB = new BasicBB();

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

    basicBB.addText(Languages.ENGLISH, `${resultNumber}!`);

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());
UrlCB

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

    basicBB.pushChoice(new UrlCB()
    .addTitle(Languages.ENGLISH, "Google")
    .addUrl(Languages.ENGLISH, "https://www.google.com/"));

GalleryBB

Gallery block with choice

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

    const complexBB = new ComplexBB();
    const ib = new 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

    ib.image(<url>)
    ib.addSubtitle(Languages.ENGLISH, "subtitle text")

    complexBB.pushItem(ib)

Gallery block with image

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

Response Builder

The main functions used

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();

Error Handling

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

    responseBuilder.functionFailure(failureParams);

In the division handler one such case of invalid input, is a divisionNumber set to 0, a number that cannot be divided by as of yet, so that number is checked early in the function, before further logic

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

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

    const failureParams: FunctionFailureParams = {
        errorBP: <error BlockPointer>,
    };

Once Handler has been set up, add the handler to the WebhookClient, when starting the server

    whClient.addHandler('division-handler', divisionHandler);

Finally, call handleRequest with the request body, and the token and return the body with the status code from the client,

      const { status, body } = await whClient.handleRequest(
    req.body,
    getToken(req)
  );
  res.status(status).send(body);

Development

NPM Versioning details

|Code status|Stage|Rule|Example version| |--- |--- |--- |--- | |Backward compatible bug fixes|Patch release|Increment the third digit|1.0.1| |Backward compatible new features|Minor release|Increment the middle digit and reset last digit to zero|1.1.0| |Changes that break backward compatibility|Major release|Increment the first digit and reset middle and last digits to zero|2.0.0|

Changes to models involving both sdk and webuildbots changes require a major release as changing the sdk model will break the main repo.

##Making a pre-release (You might want to make a prerelease to test your SDK changes in another repo)

  1. Make commit

  2. npm version prerelease --preid <prelease identifier>

  3. npm publish

  4. Install on the other repo npm i <npm identifier>

##Making a release

  1. Create PR, make any necessary changes, verify PR

  2. npm version <major | minor | patch>

  3. Version command automatically commits, make sure to push new version to PR

  4. Verify & Merge PR

  5. git push upstream --tags

  6. npm login #only first time

  7. npm publish