Skip to content

Commit

Permalink
New version 2.6.4:
Browse files Browse the repository at this point in the history
- Added sql query handler support for customizing SQL Dialog queries
MIECS-44978: Custom component dependencies not bundled
MIECS-42698 Creating a Text Message with Action Buttons code snippet error
MIECS-35792 Allow accessing nlpResult from EEH context
MIECS-37365 Preventing packaging of previous custom component package during pack
MIECS-45554 Calling context.getEntityItems() from an EEH on a skill scoped variable in dialog 2.0 fails because of lookup in child context only
MIECS-25211: Bots Node SDK Hello World sample requires keepTurn(true) to be set to navigate to next state
MIECS-43266: Can not add action to form with bots-node-sdk
MIECS-45175: Entity Event Handler: DisambiguationValues not cleared when invoking context.setItemValue
  • Loading branch information
stevendavelaar committed Dec 22, 2022
1 parent c2fa637 commit 4e34ee2
Show file tree
Hide file tree
Showing 46 changed files with 1,732 additions and 560 deletions.
2 changes: 1 addition & 1 deletion CUSTOM_COMPONENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ invoke: async (context) => {
...
// Get composite bag entity object (cbe), create bag item object, update bag item in cbe
let cbe = context.getVariable(variableName) || {"entityName": compositeBagEntityName};
cbe[bagItemName)] = {"entityName": "EMAIL", "email": _email};
cbe[bagItemName] = {"entityName": "EMAIL", "email": _email};
context.setVariable(variableName, cbe);
context.transition("validEmail");
context.keepTurn(true);
Expand Down
423 changes: 423 additions & 0 deletions DATA_QUERY_EVENT_HANDLER.md

Large diffs are not rendered by default.

30 changes: 28 additions & 2 deletions ENTITY_EVENT_HANDLER.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- [How to Validate an Item](#validate)
- [How to Send Acknowledgement Messages](#acknowledge)
- [How to Set or Update Bag Items](#update)
- [How to Create a Summary Message](#summary)
- [How to Use Custom Events](#custom)
- [How to Invoke a REST API](#restSample)
- [How to Send Rich Conversation Messages](#messages)
Expand Down Expand Up @@ -114,6 +115,12 @@ The second argument of each event method is the `context` object. This object r

You can find more information on creating conversation messages from an event handler [here](https://github.com/oracle/bots-node-sdk/blob/master/MESSAGE_MODEL.md).

<b>TIP</b>: if you are using a JavaScript IDE like Visual Studio Code, you can get code insight and code completion support by defining the types used in the event handlers as follows in your JavaScript handler file:
```javascript
const { EntityResolutionContext, EntityEventHandler, EntityEventHandlers, EntityEventHandlerMetadata, EntityEvent } = require ('@oracle/bots-node-sdk/lib');
```
When using TypeScript you will automatically get code completion support when your IDE supports it.

## Supported Events <a name="events">

### Entity Level Events <a name="entityEvents">
Expand All @@ -128,6 +135,7 @@ The table below lists all entity level events currently supported:
| `resolved` | A function that gets called when the composite bag entity is resolved. You will typically use this function to call some backend API to complete the transaction that the composite bag entity has collected the data for. If the backend API call returns errors, possibly forcing a re-prompting for some invalid bag items, you can enable the re-prompting by simply clearing those bag items. The `System.CommonResponse` and `System.ResolveEntities` components will notice that the entity is not fully resolved after all, and will resume prompting for the missing bag items. | none
| `attachmentReceived`| A function that gets called when the user sends an attachment. If the attachment can be mapped to a composite bag item, the validate function of that item will be called first. | <ul><li><b>value</b>: The attachment JSON object with `type` and `url` properties.</li></ul>
| `locationReceived`| A function that gets called when the user sends a location. If the location can be mapped to a composite bag item, the validate function of that item will be called first. | <ul><li><b>value</b>: The location JSON object with `latitude` and `longitude` properties.</li></ul>
| `disambiguateBagItem` | A handler that can be used to modify the message that is shown to disambiguate between bag items when an entity match applies to more than one bag item. Note that this handler only fires when the skill configuration parameter `Use Enhanced Slot Filling` is switched on. | <ul><li><b>matchValue</b>: The entity value matched based on the user input</li><li><b>matchedBagItems</b>: list of the names of the bag items that are matched against the entity value.</li><li><b>userInput</b>: the last user input message that matched to multiple bag items.</li></ul>

### Entity-Item Level Events <a name="itemEvents">
The table below lists all entity-item level events currently supported:
Expand Down Expand Up @@ -287,6 +295,25 @@ items: {
}
```
### How to Create a Summary Message<a name="summary">
When a composite bag entity is resolved, you typically want to show a summary of the the composite bag item values before proceeding.
The `getDisplayValues()` method on the entity resolution context makes this quite easy. This method return a list of name-value pairs of each composite bag item. Using the `reduce` function you can easily construct a summary message like this:
```javascript
resolved: async (event, context) => {
let msg = 'Got it. Here is a summary of your expense:';
msg += context.getDisplayValues().reduce((acc, curr) => `${acc}\n${curr.name}: ${curr.value}`, '');
context.addMessage(msg);
}
```
The summary message will look something like this:
```
Got it. Here is a summary of your expense:
Type: Taxi
Date: Thu Dec 22 2022
Amount: 20 dollar
```
### How to Use Custom Events <a name="custom">
The following example is for the use case where the expense date and expense amount are taken from the scanned receipt that's uploaded by the user. If the user then tries to change the date or the amount, the skill replies by telling him that the date or amount cannot be changed because they need to match the data on the receipt. The skill then provides the user an option to remove the receipt again so he can once more change the date. To implement the removal of the receipt, a custom event, `removeReceipt`, is invoked when the user taps the 'Yes' button:
Expand Down Expand Up @@ -339,5 +366,4 @@ entity: {
### How to Send Rich Conversation Messages <a name="messages">
As you have seen in the previous examples, you can use `context.addMessage(<payload>)` to create a bot message that is sent to the user.
You can call this function multiple times to send multiple messages. See the section on [Conversation Messaging](https://github.com/oracle/bots-node-sdk/blob/master/MESSAGE_MODEL.md) for code samples on how to create a [text message with buttons actions](https://github.com/oracle/bots-node-sdk/blob/master/MESSAGE_MODEL.md#textMessage), a [card message](https://github.com/oracle/bots-node-sdk/blob/master/MESSAGE_MODEL.md#cardMessage), and an [attachment message](https://github.com/oracle/bots-node-sdk/blob/master/MESSAGE_MODEL.md#attachmentMessage).
You can call this function multiple times to send multiple messages. See the section on [Conversation Messaging](https://github.com/oracle/bots-node-sdk/blob/master/MESSAGE_MODEL.md) for code samples on how to create a [text message with buttons actions](https://github.com/oracle/bots-node-sdk/blob/master/MESSAGE_MODEL.md#textMessage), a [card message](https://github.com/oracle/bots-node-sdk/blob/master/MESSAGE_MODEL.md#cardMessage), and an [attachment message](https://github.com/oracle/bots-node-sdk/blob/master/MESSAGE_MODEL.md#attachmentMessage).
3 changes: 1 addition & 2 deletions MESSAGE_MODEL.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,13 @@ const message = messageModel.textConversationMessage("Do you want another quote?
To create a card message with card actions buttons, first use the [`cardObject`](https://oracle.github.io/bots-node-sdk/MessageModel.html#.cardObject) function to create each card, then use the [`postbackActionObject`](https://oracle.github.io/bots-node-sdk/MessageModel.html#.postbackActionObject) function to create each button action, and, finally, use the [`cardConversationMessage`](https://oracle.github.io/bots-node-sdk/MessageModel.html#.cardConversationMessage) function to construct the message object.

```javascript
context messageModel = context.getMessageModel();
const messageModel = context.getMessageModel();
let cards = [];
cards.push(messageModel.cardObject('4 Dozen Oranges','4 dozen Mandarin oranges in a wooden crate.',
undefined, undefined, [messageModel.postbackActionObject('Oranges', undefined, { action: 'oranges' })]));
cards.push(messageModel.cardObject('Carton of Grapes', '10kg ripe grapes in a protected carton.',
undefined, undefined, [messageModel.postbackActionObject('Grapes', undefined, { action: 'grapes' })]));
let message = messageModel.cardConversationMessage('vertical', cards);
}
```

### Creating an Attachment Message <a name="attachmentMessage">
Expand Down
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ bots-node-sdk init component myEventHandler entityEventHandler

This example creates a component of type `entityEventHandler` that is named `myEventHandler`. Instead of typing `entityEventHandler` for the component type argument, you can type `e` as a shortcut.

### Add an SQL Query Event Handler to Existing Service

You use the `init component <name> sqlQueryEventHandler` command to add an event handler to an existing package. For example:

```text
bots-node-sdk init component myEventHandler sqlQueryEventHandler
```

This example creates a component of type `sqlQueryEventHandler` that is named `myEventHandler`. Instead of typing `sqlQueryEventHandler` for the component type argument, you can type `s` as a shortcut.

### Create a Component Service Package

To package the components, use the `pack` command. For example:
Expand Down Expand Up @@ -123,6 +133,7 @@ See the README.md that's created in your scaffolded TypeScript project for more
- [Using the CLI](https://github.com/oracle/bots-node-sdk/blob/master/bin/CLI.md) - Command line capabilities to facilitate writing custom components and entity event handlers.
- [Writing Custom Components](https://github.com/oracle/bots-node-sdk/blob/master/CUSTOM_COMPONENT.md) - Guidelines and tips for writing custom components.
- [Writing Entity Event Handlers](https://github.com/oracle/bots-node-sdk/blob/master/ENTITY_EVENT_HANDLER.md) - Guidelines and tips for writing entity event handlers.
- [Writing SQL Query Event Handlers](https://github.com/oracle/bots-node-sdk/blob/master/DATA_QUERY_EVENT_HANDLER.md) - Guidelines and tips for writing data query event handlers.
- [Conversation Messaging](https://github.com/oracle/bots-node-sdk/blob/master/MESSAGE_MODEL.md) - Creating conversation messages from custom code.
- [Writing Webhooks](https://github.com/oracle/bots-node-sdk/blob/master/WEBHOOK.md) - Integrate with custom messaging channels using incoming/outgoing webhook.
- [Unit Testing](https://github.com/oracle/bots-node-sdk/blob/master/testing/TESTING.md) - Unit testing facilities.
Expand All @@ -139,7 +150,7 @@ See the README.md that's created in your scaffolded TypeScript project for more

## License

Copyright © 2018-2021, Oracle and/or its affiliates. All rights reserved.
Copyright © 2018-2022, Oracle and/or its affiliates. All rights reserved.

The Universal Permissive License (UPL), Version 1.0

Expand Down
17 changes: 17 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Release Notes

- [Version 2.6.4](#v264)
- [Version 2.6.3](#v263)
- [Version 2.6.2](#v262)
- [Version 2.6.1](#v261)
Expand All @@ -13,6 +14,22 @@
- [Version 2.4.3](#v243)
- [Version 2.4.2](#v242)

## Version 2.6.4 <a name="v264">

### New Features

- **SQL Query Event Handlers**: SQL query event handlers can be used to customize the SQL Dialogs query results. See [Writing SQL Query Event Handlers](https://github.com/oracle/bots-node-sdk/blob/master/DATA_QUERY_EVENT_HANDLER.md) for more information. This feature requires Oracle Digital Assistant version 22.12 or later.

### Fixed Issues

- Item disambiguation values are not cleared when setting item value using context.setItemValue
- Bots Node SDK Hello World sample requires keepTurn(true) to be set to navigate to next state
- Cannot add action to form with bots-node-sdk
- Custom component dependencies not bundled. This has been fixed by changing the `bundledDependencies` property in `package.json` to `bundleDependencies` as this is the property name used when installing a package using `npm install`. If you are using this new SDK version with an existing component service, make sure to update your `package.json` accordingly.
- Preventing packaging of previous custom component package during pack
- Allow accessing nlpResult from EEH context
- Calling context.getEntityItems() from an EEH on a skill scoped variable in visual dialog fails because of lookup in flow scope only

## Version 2.6.3 <a name="v263">

### Fixed Issues
Expand Down
6 changes: 3 additions & 3 deletions bin/CLI.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# CLI Developer Tools

This SDK includes a command-line intertace (CLI) to help you create and package custom components and entity event handlers.
This SDK includes a command-line intertace (CLI) to help you create and package custom components and event handlers.

```text
Usage: bots-node-sdk [command] [arguments][options]
Expand Down Expand Up @@ -74,7 +74,7 @@ When neither `[dest]` nor `--name` are provided, the command writes the artifact
|--|--|--|
| `-l --language` | The language to use: `[t]ypescript` or `[j]avascript` | `javascript` |
| `-c --component-name ` | The name for the initial component in your project | `helloWorld` |
| `-t --component-type ` | The type of component to create: `[c]ustom` or `[e]ntityEventHandler` to create | `custom` |
| `-t --component-type ` | The type of component to create: `[c]ustom` or `[e]ntityEventHandler` or `[s]qlQueryEventHandler` | `custom` |
| `-s --skip-install` | Skip invoking the `npm install` command to install named dependencies after code generation | The command isn't skipped |
| `-r --run` | Start the component service after the command completes | The service isn't started |
| `-n --name ` | The name for the component package.|`my-component-service`|
Expand All @@ -84,7 +84,7 @@ When neither `[dest]` nor `--name` are provided, the command writes the artifact
Run this command in the component package's top-level directory to create a custom component or event handler. The component's language is the same as the language that you specified when you ran the `init` command to create the component package.

If `dest` isn't specified, then the component is written to the `components` directory for JavaScript and the `src/components` directory for TypeScript. If this directory doesn't exist, it will be created.
The component `name` and `type` arguments are required, and `type` must be either `[c]ustom` or `[e]ntityEventHandler`.
The component `name` and `type` arguments are required, and `type` must be either `[c]ustom` or `[e]ntityEventHandler` or `[s]qlQueryEventHandler`.

For example, to create a new entity event handler component named `resolvePizza`, you can use this command:

Expand Down
10 changes: 5 additions & 5 deletions bin/commands/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ function nameOpt(name) {

function componentTypeOpt(type) {
let t = type.toLowerCase();
t = t === 'c' ? 'custom' : (t === 'e' ? 'entityeventhandler' : (t === 'd' ? 'dataqueryeventhandler' : t));
if (!~['custom', 'entityeventhandler', 'dataqueryeventhandler'].indexOf(t)) {
throw new Error(`Invalid component type: ${type}, allowable values are [c]ustom or [e]ntityEventHandler or [d]ataQueryEventHandler..`);
t = t === 'c' ? 'custom' : (t === 'e' ? 'entityeventhandler' : (t === 's' ? 'sqlqueryeventhandler' : t));
if (!~['custom', 'entityeventhandler', 'sqlqueryeventhandler'].indexOf(t)) {
throw new Error(`Invalid component type: ${type}, allowable values are [c]ustom or [e]ntityEventHandler or [s]qlQueryEventHandler..`);
}
return t;
}
Expand All @@ -42,7 +42,7 @@ class CCInit extends CommandDelegate {
.option('-r --run', 'Start service when init completes (with defaults)')
.option('-n --name <name>', 'Specify a name for the new project', null, nameOpt)
.option('-c --component-name <name>', 'Name for the first custom component', 'helloWorld', nameOpt)
.option('-t --component-type <type>', 'Specify the component type [c]ustom or [e]ntityEventHandler or [d]ataQueryEventHandler', 'custom', componentTypeOpt);
.option('-t --component-type <type>', 'Specify the component type [c]ustom or [e]ntityEventHandler or [s]qlQueryEventHandler', 'custom', componentTypeOpt);
// add child command 'init component'
this.command.delegate(CCInitComponent, 'component');
}
Expand Down Expand Up @@ -174,7 +174,7 @@ class CCInitComponent extends CommandDelegate {
this.command
.ignore('componentName').ignore('run').ignore('skipInstall') // inherited from parent
.argument('name', 'Specify a name for the component', true, nameOpt)
.argument('type', 'Specify the component type [c]ustom or [e]ntityEventHandler or [d]ataQueryEventHandler', true, componentTypeOpt)
.argument('type', 'Specify the component type [c]ustom or [e]ntityEventHandler or [s]qlQueryEventHandler', true, componentTypeOpt)
.argument('dest', 'Destination directory where component should be added', false)
.option('-q --quiet', 'Suppress outputs')

Expand Down
6 changes: 3 additions & 3 deletions bin/commands/pack.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,11 @@ class CCPack extends CommandDelegate {
return this;
}

// TASK-19013: bundledDependencies
// TASK-19013: bundleDependencies
_setBundled() {
const { dependencies } = this.cc.json;
const bundledDependencies = Object.keys(dependencies || {});
this._setJson({ bundledDependencies });
const bundleDependencies = Object.keys(dependencies || {});
this._setJson({ bundleDependencies });
return this;
}

Expand Down
3 changes: 2 additions & 1 deletion bin/templates/ccpackage/js/__.npmignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
*.tgz
spec
service-*
package/
package/
!.npmignore
2 changes: 1 addition & 1 deletion bin/templates/ccpackage/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
"{{sdkName}}": "^{{sdkVersion}}",
"express": "{{expressVersion}}"
},
"bundledDependencies": []
"bundleDependencies": []
}
1 change: 1 addition & 0 deletions bin/templates/ccpackage/ts/__.npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ package/
src
tsconfig.json
**/*.map
!.npmignore
2 changes: 1 addition & 1 deletion bin/templates/ccpackage/ts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@
"express": "{{expressVersion}}",
"typescript": "{{typescriptVersion}}"
},
"bundledDependencies": []
"bundleDependencies": []
}
3 changes: 3 additions & 0 deletions bin/templates/components/custom/template.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

// Documentation for writing custom components: https://github.com/oracle/bots-node-sdk/blob/master/CUSTOM_COMPONENT.md

// You can use your favorite http client package to make REST calls, however, the node fetch API is pre-installed with the bots-node-sdk.
// Documentation can be found at https://www.npmjs.com/package/node-fetch
// Un-comment the next line if you want to make REST calls using node-fetch.
Expand Down Expand Up @@ -29,6 +31,7 @@ module.exports = {
// Send two messages, and transition based on the day of the week
context.reply(`Greetings ${human}`)
.reply(`Today is ${now.toLocaleDateString()}, a ${dayOfWeek}`)
.keepTurn(true)
.transition(isWeekend ? 'weekend' : 'weekday');
}
};
3 changes: 3 additions & 0 deletions bin/templates/components/custom/template.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {CustomComponent, CustomComponentMetadata, CustomComponentContext} from '@oracle/bots-node-sdk/lib';

// Documentation for writing custom components: https://github.com/oracle/bots-node-sdk/blob/master/CUSTOM_COMPONENT.md

// You can use your favorite http client package to make REST calls, however, the node fetch API is pre-installed with the bots-node-sdk.
// Documentation can be found at https://www.npmjs.com/package/node-fetch
// Un-comment the next line if you want to make REST calls using node-fetch.
Expand Down Expand Up @@ -27,6 +29,7 @@ export class {{className}} implements CustomComponent {
// Send two messages, and transition based on the day of the week
context.reply(`Greetings ${human}`)
.reply(`Today is ${now.toLocaleDateString()}, a ${dayOfWeek}`)
.keepTurn(true)
.transition(isWeekend ? 'weekend' : 'weekday');
}

Expand Down
Loading

0 comments on commit 4e34ee2

Please sign in to comment.