UNPKG

@webuildbots/webuildbots-sdk

Version:
301 lines (213 loc) 10.7 kB
[[_TOC_]] # Getting started with the Webuildbots sdk ## Connecting IA to your server #### 1. Use [ngrok](https://ngrok.com/) to expose your server 1. Download and Install [ngrok](https://ngrok.com/) 2. Use the command **ngrok http &lt;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(&lt;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`](https://gitlab.com/webuildbots/webuildbots-sdk/tree/master/examples/divide) 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 ``` typescript export const whClient: WebhookClient = new WebhookClient('secret'); ``` Then a new `WebhookHandler` is initiated ``` typescript 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 ``` typescript const {value: baseNumber} = webhookReq.formValue.baseNumber; const {value: divisionNumber} = webhookReq.formValue.divisionNumber; ``` The above FormValues are structured as the following interface: ``` typescript { 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 ``` typescript 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 ``` typescript 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](./.docs/images/basic.png) Initialise a new instance of `BasicBB` to start building a block. ``` typescript 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 ``` typescript 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 ``` typescript 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. ``` typescript 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. ``` typescript basicBB.pushChoice(new UrlCB() .addTitle(Languages.ENGLISH, "Google") .addUrl(Languages.ENGLISH, "https://www.google.com/")); ``` #### GalleryBB ![Gallery block with choice](./.docs/images/gallery.png) 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 ``` typescript 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 ```typescript ib.image(<url>) ib.addSubtitle(Languages.ENGLISH, "subtitle text") complexBB.pushItem(ib) ``` ![Gallery block with image](./.docs/images/gallerywithimg.png) 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 ```typescript responseBuilder.unsetFunctionForm(); ``` #### Error Handling If an input is invalid, or another error is caught, the `responseBuilder` can return a `functionFailure`, ``` typescript 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 ``` typescript 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 ```typescript const failureParams: FunctionFailureParams = { errorBP: <error BlockPointer>, }; ``` Once Handler has been set up, add the handler to the `WebhookClient`, when starting the server ```typescript 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, ```typescript 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 ``