Backend Integration
You can integrate skills with backend services, such as your company's APIs and the Oracle Cloud Infrastructure APIs, using either the built-in Call REST Service component or through your own custom components. Custom components are also useful for complex processing.
Note that, in addition to the Call REST Service component and custom components, you can use entity event handlers (EEH) to access backend services and do complex processing. When deciding which one to use, ask yourself these questions:
-
Is the call needed in the context of a composite bag entity? In this case, you can use an EEH.
-
Should the outcome of the call determine the next transition? This would be a case for the Call REST Service component or a custom component.
Access Backends Using the REST Service Component
If your skill needs to retrieve or update some data through a backend service, you can quickly implement this by adding a REST service configuration for the API's endpoint and calling that service from your skill using the Call REST Service component.
Add a REST Service for an Endpoint
Oracle Digital Assistant provides a built-in Call REST Service component that you can use in Visual Dialog skills to send a request to a REST service's endpoint. Before you can make the request from a Call REST Service component, you must first configure the endpoint in the REST Services tab.
To add a REST Service:
-
In Oracle Digital Assistant, click
to open the side menu, select Settings, select API Services, and then click the REST Services tab.
-
Provide this general information:
Field Description Name A unique name that lets you easily identify the endpoint that you are configuring. For example, for an appointments API, you might name the REST services "appointmentsUser" and "appointmentsUserEntry". Endpoint The endpoint to access the REST operation. Use curly braces to delineate path parameters. For example: https://example.com/appointments/{userId}
.For Oracle Cloud Infrastructure endpoints, ensure that you use the endpoint for your tenancy's region.
Description An optional description that explains the purpose of the endpoint. For example: "Adds and retrieves a user's appointments." Authentication Type Select how to authenticate the REST call.
-
No Authentication Required: Select this when the service doesn't require authentication.
-
Basic Authentication: Select this when the service uses a Basic authentication. You’ll then need to provide a user name and a password..
-
API Key: Select this when the service uses an API Key for authentication. You’ll then need to indicate whether the key must be passed as a path parameter or a query parameter, and you'll need to specify the key name and value.
-
Bearer Token: Select this when the service uses a Bearer token for authentication. You’ll then need to specify the token.
-
OCI Resource Principal: Select this when you are accessing an Oracle Cloud Infrastructure API.
Private Endpoint If you have a private endpoint set up for the service that you need to access, turn this switch to the On position and select the private endpoint you are using. Note: You can set up private endpoints for services that are not exposed publicly on the internet. See Private Endpoint.
-
-
For each method that you want to configure for the endpoint, click + Add Method, select the method, and then provide this information:
Field Description Content Type The type of the content that's included in the request body. application/json
andtext/plain
are supported.Body For POST, PUT, and PATCH requests, the request body to send with the request. You can override this value in the Call REST Service component. For large request bodies, click Use Edit Dialog to open an editor.
Parameters You can add path and query parameters for testing the request. You also can add path and query parameters to configure default values. Note that the skill developers can override these parameter values from the Call REST Service component. That is, they can add parameters in the component to override the values configured in the REST service, and not add the parameters where they want to use the values set in the REST service configuration. For the path parameters that are in the endpoint, add a parameter of type Path, set the key to match the path parameter, and set the desired value.
For query parameters that you want to pass in the REST request, add a parameter of type Query, set the key to match the query parameter, and set the desired value.
If the authentication type is API Key, and the key is passed in as a query parameter, don't add a query parameter for that key value here as it's already configured.
After you edit the parameter, click
to add the parameter to the list.
Headers Add any headers that you want to pass in the request. If the authentication type is API Key, and the key is passed in a header, don't add a header for that key value here as it's already configured.
Static Response You can use the static response configuration for cases where you need a fallback response whenever there's an error. You can also use it to set up mock data for development or testing purposes. To configure a static response, select a return status code and then define the response body. Alternatively, set the desired parameters and headers, click Test Request, and then click Save as Static Response to save values for the static response.
-
If you want to test the method, set the path and query parameters to use for the path, set any necessary headers, provide a request body if necessary, and click Test Request. A Response Status dialog appears with the response status and body.
Tip:
You can click Save as Static Response to save the status code and body in the static response fields.
Use the Call REST Service Component
When a skill needs to retrieve or update some data through a backend service, add a state that uses the Call REST Service component. Here's how to use that component.
The Call Service Component is supported in visual dialogs only, not in YAML dialogs.
-
Configure the endpoint on the Settings > API Services > REST Services page as described in Add a REST Service for an Endpoint. This is where you define the endpoint, authentication type, supported methods, request body, path and query parameters, headers, and an optional static response.
-
In the desired flow in the skill's flow designer, add the state, choose Service Integration > Call Rest Service, provide a name, and then click Insert.
-
Select the REST service that you configured on the REST Services page.
-
Select the method.
- For POST, PUT, and PATCH requests, you'll typically need to provide a request body.
Tip:
If the body contains FreeMarker expressions, then you can switch Expression to On to see FreeMarker syntax coloring. However, if you do so, JSON syntax validation is turned off. -
In the Parameters section, configure the path and query parameters that you want to send with the request.
Parameters that you set in the component override the parameters that are set in the REST service configuration. Conversely, if you don't set a parameter in the component, then the request uses the parameter value from the REST service configuration.
For query parameters that are defined in the REST service configuration, if you don't want to pass that query parameter, set its value to
${r""}
. -
Set any headers that you want to send with the request.
Headers that you set in the component override the headers that are set in the REST service configuration. Conversely, if you don't set a header in the component, then the request uses the header value from the REST service configuration.
-
Specify which response you want returned after the call completes:
-
Use Actual REST API Response: This returns the actual response from the REST service.
-
Always Use Static REST Response: This returns the static response that is configured on the REST Services tab. This response is helpful during development and test phases, among other uses.
-
Fallback Using Static Response: If the REST request is successful, then the REST response is returned. Otherwise, the static response that's configured on the REST Services tab is returned.
Note that if the REST service configuration doesn't have a static response, then the only choice is Use Actual Response.
-
-
For the result variable, select the map variable for storing the response data. If it doesn't exist yet, click Create to make one.
After the request completes, the map will contain a
responsePayload
property for the response body and astatusCode
property for the status code. How the response body is stored in the variable depends on the whether the response is a JSON object, JSON Array, or plain text (string):-
JSON Object: The object is stored in the
responsePayload
property. -
JSON Array: The array is stored in the
responsePayload.responseItems
property. -
Plain Text: The text is stored in the
responsePayload.message
property.
-
- On the Transitions tab, specify the next transition and the transitions for the success and failure actions.
-
The success action occurs when the
statusCode
is between 100 and 299. -
The failure action occurs when the
statusCode
is 300 and above.
-
For more details about this component, see Call REST Service.
Access Backends Using Custom Components
Oracle Digital Assistant has many built-in components to support basic actions like setting variables and prompting for user input. In cases where your bot design calls for actions outside of the provided components, such as calling REST APIs, implementing complex business logic, and customizing messages, you can write custom components.
Tip:
If the logic or processing is needed in the context of a composite bag entity, consider using entity event handlers, which you can create directly from the composite bag's configuration page. See Entity Event Handlers.To use a custom component, complete these tasks:
-
Implement: Using JavaScript and the Oracle Digital Assistant Node.js SDK, implement a custom component that transfers data to and from the skill using the SDK's metadata and conversation objects. See Task 1: Implement Custom Components.
-
Deploy: If you are hosting the components on Oracle Mobile Hub backend, Oracle Cloud Infrastructure Functions, or a Node.js server, deploy the component package. See Task 2: Deploy the Component Package to a Service.
-
Add to Skill: Make the components available to a skill by adding a component service for it. See Task 3: Add Component Package to a Skill.
Task 1: Implement Custom Components
To implement custom components, you use the Oracle Digital Assistant Node.js SDK to interface with Digital Assistant's custom component service.
Here's how to implement custom components that you can deploy to the Digital Assistant embedded container, Oracle Cloud Infrastructure Functions, a Mobile Hub backend, or a Node.js server:
If you plan to deploy the custom component package to an embedded custom component service, each skill that you add the package to is counted as a separate service. There's a limit to how many embedded custom component services an instance can have. If you don't know the limit, ask your service administrator to get the
embedded-custom-component-service-count
for you as described in View Service Limits in the Infrastructure Console. Consider packaging several components per package to minimize the number of embedded component services that you use. If you try to add a component service after you meet that limit, the service creation fails.
Step 1: Install the Software for Building Custom Components
To build a custom component package, you need Node.js, Node Package Manager, and the Oracle Digital Assistant Bots Node.js SDK.
Oracle Cloud Infrastructure Functions currently supports Node 11 and Node 14. If you plan to deploy to the embedded container, your package should be compatible with Node 14.17.0.
Step 2: Create the Custom Component Package
To start a project, you use the bots-node-sdk init
command from the SDK’s command line interface (CLI) to create the necessary files and directory structure for your component structure.
The init
command has a few options, such as whether to use JavaScript (the default) or TypeScript, and what to name the initial component's JavaScript file. These options are described in CLI Developer Tools. Here's the basic command for starting a JavaScript project:
bots-node-sdk init <top-level folder path> --name <component service name>
This command completes the following actions for a JavaScript package:
-
Creates the top-level folder.
-
Creates a
components
folder and adds a sample component JavaScript file namedhello.world.js
. This is where you'll put your component JavaScript files. -
Adds a
package.json
file, which specifiesmain.js
as the main entry point and lists@oracle/bots-node-sdk
as adevDependency
. The package file also points to somebots-node-sdk
scripts.{ "name": "myCustomComponentService", "version": "1.0.0", "description": "Oracle Bots Custom Component Package", "main": "main.js", "scripts": { "bots-node-sdk": "bots-node-sdk", "help": "npm run bots-node-sdk -- --help", "prepack": "npm run bots-node-sdk -- pack --dry-run", "start": "npm run bots-node-sdk -- service ." }, "repository": {}, "dependencies": {}, "devDependencies": { "@oracle/bots-node-sdk": "^2.2.2", "express": "^4.16.3" } }
-
Adds a
main.js
file, which exports the package settings and points to the components folder for the location of the components, to the top-level folder. -
Adds an
.npmignore
file to the top-level folder. This file is used when you export the component package. It must exclude.tgz
files from the package. For example:*.tgz
. -
For some versions of npm, creates a
package-lock.json
file. - Installs all package dependencies into the
node_modules
subfolder.
If you don't use the
bots-node-sdk init
command to create the package folder, then ensure that the top-level folder contains an .npmignore
file that contains a *.tgz
entry. For example:*.tgz
spec
service-*
Otherwise, every time you pack the files into a TGZ file, you include the TGZ file that already exists in the top-level folder, and your TGZ file will continue to double in size.
If you plan to deploy to the embedded container, your package should be compatible with Node 14.17.0.
Step 3: Create and Build a Custom Component
Here are the steps for building each custom component in your package:
Create the Component File
Use the SDK's CLI init component
command to create a JavaScript or TypeScript file with the framework for working with the Oracle Digital Assistant Node.js SDK to write a custom component. The language that you specified when you ran the init
command to create the component package determines whether a JavaScript or a TypeScript file is created.
For example, to create a file for the custom component, from a terminal window, CD to the package’s top-level folder and type the following command, replacing <component name>
with your component's name:
bots-node-sdk init component <component name> c components
For JavaScript, this command adds the <component name>.js
to the components folder
. For TypeScript, the file is added to the src/components
folder. The c
argument indicates that the file is for a custom component.
Note that the component name can't exceed 100 characters. You can only use alphanumeric characters and underscores in the name. You can't use hyphens. Nor can the name have a System.
prefix. Oracle Digital Assistant won't allow you to add a custom component service that has invalid component names.
For further details, see https://github.com/oracle/bots-node-sdk/blob/master/bin/CLI.md
.
Add Code to the metadata and invoke Functions
Your custom component must export two objects:
-
metadata
: This provides the following component information to the skill.-
Component name
-
Supported properties
-
Supported transition actions
For YAML-based dialog flows, the custom component supports the following properties by default. These properties aren't available for skills designed in Visual dialog mode.
-
autoNumberPostbackActions
: Boolean. Not required. Whentrue
, buttons and list options are numbered automatically. The default isfalse
. See Auto-Numbering for Text-Only Channels. -
insightsEndConversation
: Boolean. Not required. Whentrue
, the session stops recording the conversation for insights reporting. The default isfalse
. See Model the Dialog Flow. -
insightsInclude
: Boolean. Not required. Whentrue
, the state is included in insights reporting. The default istrue
. See Model the Dialog Flow. -
translate
: Boolean. Not required. Whentrue
, autotranslation is enabled for this component. The default is the value of theautotranslation
context variable. See Translation Services in Skills.
-
-
invoke
: This contains the logic to execute. In this method, you can read and write skill context variables, create conversation messages, set state transitions, make REST calls, and more. Typically, you would use theasync
keyword with this function to handle promises. Theinvoke
function takes the following argument:context
, which names the reference to theCustomComponentContext
object in the Digital Assistant Node.js SDK. This class is described in the SDK documentation at https://oracle.github.io/bots-node-sdk/. In earlier versions of the SDK, the name wasconversation
. You can use either name.
Note
If you are using a JavaScript library that doesn't support promises (and thus aren't usingasync
keyword), it is also possible to add adone
argument as a callback that the component invokes when it has finished processing.
Here’s an example:
'use strict';
module.exports = {
metadata: {
name: 'helloWorld',
properties: {
human: { required: true, type: 'string' }
},
supportedActions: ['weekday', 'weekend']
},
invoke: async(context) => {
// Retrieve the value of the 'human' component property.
const { human } = context.properties();
// determine date
const now = new Date();
const dayOfWeek = now.toLocaleDateString('en-US', { weekday: 'long' });
const isWeekend = [0, 6].indexOf(now.getDay()) > -1;
// Send two messages, and transition based on the day of the week
context.reply(`Greetings ${human}`)
.reply(`Today is ${now.toLocaleDateString()}, a ${dayOfWeek}`)
.transition(isWeekend ? 'weekend' : 'weekday');
}
}
To learn more and explore some code examples, see Writing Custom Components in the Bots Node SDK documentation.
Control the Flow with keepTurn and transition
You use different combinations of the Bots Node SDK keepTurn
and
transition
functions to define how the custom component interacts with a
user and how the conversation continues after the component returns flow control to the
skill.
-
keepTurn(boolean)
specifies whether the conversation should transition to another state without first prompting for user input.Note that if you want to set
keepTurn
to true, you should callkeepTurn
after you callreply
becausereply
implicitly setskeepTurn
tofalse
. -
transition(action)
causes the dialog to transition to the next state after all replies, if any, are sent. The optionalaction
argument names that action (outcome) that the component returns.If you don't call
transition()
, the response is sent but the dialog stays in the state and subsequent user input comes back to this component. That is,invoke()
is called again.
invoke: async (context) ==> {
...
context.reply(payload);
context.keepTurn(true);
context.transition ("success");
}
Here are some common use cases where you would use keepTurn
and transition
to control the dialog flow:
Use Case | Values Set for keepTurn and transition |
---|---|
A custom component that transitions to another state without first prompting the user for input. |
For example, this custom component updates a variable with a list of values to be
immediately displayed by the next state in the dialog
flow.
|
A custom component that enables the skill to wait for input after control returns to the skill and before the skill transitions to another state. |
For
example:
|
A custom component that gets user input without returning flow control back to the skill. For example:
|
For example, this custom component outputs a quote and then displays
Yes and No buttons to request another quote. It
transitions back to the skill when the user clicks
No .
If a component doesn’t transition to another state, then it needs to keep track of its own state, as shown in the above example. For more complex state handling, such as giving the user the option to cancel if a data retrieval is taking too long, you can create and use a context variable. For example: Note that as long as you don't transition, all values that are passed in as component properties are available. |
The component invocation repeats without user input. For example:
|
Here's a somewhat contrived example that shows how to repeat the invocation without
waiting for user input, and then how to transition when
done:
|
Access the Backend
You'll find that there are several Node.js libraries that have been built to make HTTP requests easy, and the list changes frequently. You should review the pros and cons of the currently available libraries and decide which one works best for you. We recommend that you use a library that supports promises so that you can leverage the async
version of the invoke
method, which was introduced in version 2.5.1, and use the await
keyword to write your REST calls in a synchronous way.
One option is the node fetch API that's pre-installed with the Bots Node SDK. Access the Backend Using HTTP REST Calls in the Bots Node SDK documentation contains some code examples.
Use the SDK to Access Request and Response Payloads
You use CustomComponentContext
instance methods to get the context for the invocation, access and change variables, and send results back to the dialog engine.
You can find several code examples for using these methods in Writing Custom Components and Conversation Messaging in the Bots Node SDK documentation
The SDK reference documentation is at https://github.com/oracle/bots-node-sdk
.
Custom Components for Multi-Language Skills
When you design a custom component, you should consider whether the component will be used by a skill that supports more than one language.
If the custom component must support multi-language skills, then you need to know if the skills are configured for native language support or translation service.
When you use a translation service, you can translate the text from the skill. You have these options:
-
Set the
translate
property in the custom component's state to true to translate the component's reply, as described in Send Responses Directly to the Translation Service. -
Send raw data back to the skill in context variables and use the variables' values in a system component that composes the output. Set that component's
translate
property to true. See Use a System Component to Pass the Message to the Translation Service. -
Send raw data back to the skill in context variables and use the variables' values in a system component that uses the resource bundle key for the language. See Use a System Component to Reference a Resource Bundle.
For native language skills, you have these options:
-
Pass the data back to the skill in context variables and then output the text from a system component by passing the variables' values to a resource bundle key, as described in Use a System Component to Reference a Resource Bundle. With this option, the custom component must have metadata properties for the skill to pass the names of the context variables to store the data in.
-
Use the resource bundle from the custom component to compose the custom component's reply, as described in Reference Resource Bundles from the Custom Component. You use the
conversation.translate()
method to get the resource bundle string to use for your call tocontext.reply()
. This option is only valid for resource bundle definitions that use positional (numbered) parameters. It doesn't work for named parameters. With this option, the custom component must have a metadata property for name of the resource bundle key, and the named resource bundle key's parameters must match those used in the call tocontext.reply()
.
Here's an example of using the resource bundle from the custom component. In this example, fmTemplate
would be set to something like ${rb('date.dayOfWeekMessage', 'lundi', '19 juillet 2021')}
.
'use strict';
var IntlPolyfill = require('intl');
Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat;
module.exports = {
metadata: () => ({
name: 'Date.DayOfWeek',
properties: {
rbKey: { required: true, type: 'string' }
},
supportedActions: []
}),
invoke: (context, done) => {
const { rbKey } = context.properties();
if (!rbKey || rbKey.startsWith('${')){
context.transition();
done(new Error('The state is missing the rbKey property or it uses an invalid expression to pass the value.'));
}
//detect user locale. If not set, define a default
const locale = context.getVariable('profile.locale') ?
context.getVariable('profile.locale') : 'en-AU';
const jsLocale = locale.replace('_','-');
//when profile languageTag is set, use it. If not, use profile.locale
const languageTag = context.getVariable('profile.languageTag')?
context.getVariable('profile.languageTag') : jslocale;
/* =============================================================
Determine the current date in local format and
the day name for the locale
============================================================= */
var now = new Date();
var dayTemplate = new Intl.DateTimeFormat(languageTag,
{ weekday: 'long' });
var dayOfWeek = dayTemplate.format(now);
var dateTemplate = new Intl.DateTimeFormat(languageTag,
{ year: 'numeric', month: 'long', day: 'numeric'});
var dateToday = dateTemplate.format(now);
/* =============================================================
Use the context.translate() method to create the ${Freemarker}
template that's evaluated when the reply() is flushed to the
client.
============================================================= */
const fmTemplate = context.translate(rbKey, dateToday, dayOfWeek );
context.reply(fmTemplate)
.transition()
.logger().info('INFO : Generated FreeMarker => '
+ fmTemplate);
done();
}
};
Ensure the Component Works in Digital Assistants
In a digital assistant conversation, a user can break a conversation flow by changing the subject. For example, if a user starts a flow to make a purchase, they might interrupt that flow to ask how much credit they have on a gift card. We call this a non sequitur. To enable the digital assistant to identify and handle non sequiturs, call the context.invalidInput(payload)
method when a user utterance response is not understood in the context of the component.
In a digital conversation, the runtime determines if an invalid input is a non sequitur by searching for response matches in all skills. If it finds matches, it reroutes the flow. If not, it displays the message, if provided, prompts the user for input, and then executes the component again. The new input is passed to the component in the text
property.
In a standalone skill conversation, the runtime displays the message, if provided, prompts the user for input, and then executes the component again. The new input is passed to the component in the text
property.
This example code calls context.invalidInput(payload)
whenever the input doesn’t convert to a number.
"use strict"
module.exports = {
metadata: () => ({
"name": "AgeChecker",
"properties": {
"minAge": { "type": "integer", "required": true }
},
"supportedActions": [
"allow",
"block",
"unsupportedPayload"
]
}),
invoke: (context, done) => {
// Parse a number out of the incoming message
const text = context.text();
var age = 0;
if (text){
const matches = text.match(/\d+/);
if (matches) {
age = matches[0];
} else {
context.invalidUserInput("Age input not understood. Please try again");
done();
return;
}
} else {
context.transition('unsupportedPayload");
done();
return;
}
context.logger().info('AgeChecker: using age=' + age);
// Set action based on age check
let minAge = context.properties().minAge || 18;
context.transition( age >= minAge ? 'allow' : 'block' );
done();
}
};
Here’s an example of how a digital assistant handles invalid input at runtime. For the first age response (twentyfive
), there are no matches in any skills registered with the digital assistant so the conversation displays the specified context.invalidUserInput
message. In the second age response (send money
), the digital assistant finds a match so it asks if it should reroute to that flow.

You should call either context.invalidInput()
or context.transition()
. If you call both operations, ensure that the system.invalidUserInput
variable is still set if any additional message is sent. Also note that user input components such as System.CommonResponse
, System.Text
, System.List
, and System.ResolveEntities
reset system.invalidUserInput
.
Say, for example, that we modify the AgeChecker component as shown below, and call context.transition()
after context.invalidInput()
.
if (matches) { age = matches[0]; } else {
context.invalidUserInput("Age input not understood. Please try again");
context.transition("invalid");
context.keepTurn(true);
done();
return;
}
In this case, the data flow needs to transition back to askage
so that the user gets two output messages – "Age input not understood. Please try again" followed by "How old are you?".
askage:
component: "System.Output"
properties:
text: "How old are you?"
transitions:
next: "checkage"
checkage:
component: "AgeChecker"
properties:
minAge: 18
transitions:
actions:
allow: "crust"
block: "underage"
invalid: "askage"
Task 2: Deploy the Component Package to a Service
You can host the custom component package from a Digital Assistant embedded container, Oracle Cloud Infrastructure Functions, Mobile Hub, or an external Node.js server. For embedded component services, you deploy the package when you create the service. For Oracle Cloud Infrastructure Functions, external Node.js server, and Mobile Hub services, you must first deploy the package to the service, as described here, before you add it to a skill as a component service.
Deploy to a Node.js Server
To host a custom component package on an external Node.js server, use the bots-node-sdk pack --service express
CLI to copy your component package folders and make a few changes that are specific to Express, then install the component package and start it on your server.
-
From the custom component package's top-level folder (the one that contains the
main.js
file), type this command in a terminal window:bots-node-sdk pack --service express
The command does the following:
- Copies the files and subfolders to
service-express-<package version>
. - Adds an
index.js
service wrapper. - Creates an
api.js
file, which is an Express wrapper formain.js
. - Modifies the
package.json
file to set the main file toindex.js
and add the dependencies.
This step shows the basic CLI command. For more information, see
https://github.com/oracle/bots-node-sdk/blob/master/bin/CLI.md
. - Copies the files and subfolders to
-
Run these commands:
npm install npm start
Deploy to Oracle Cloud Infrastructure Functions
You can deploy your custom components to Oracle Cloud Infrastructure Functions.
Currently, Oracle Digital Assistant can't access entity event handlers in packages that you deploy to Oracle Cloud Infrastructure Functions.
This feature is not available for Digital Assistant instances that are paired with a subscription to a Fusion-based Oracle Cloud Applications service, such as HCM Cloud or Sales Cloud.
Here are the high-level steps:
Get Artifact Names and Permissions for Oracle Cloud Infrastructure Functions Deployment
Before you can deploy custom components to Oracle Cloud Infrastructure Functions, you need to obtain the names of the artifacts that are used for deployment, and you need to verify that you have permission to use them.
To set up your instance for Oracle Cloud Infrastructure Functions deployment, your tenancy administrator completed the steps in Setup and Policies for Oracle Functions. As part of the process, they created the following artifacts. Ask your administrator for their names, which you'll need when you complete the steps in Set Up Your User Account for Oracle Functions:
-
The names of the region and compartment to use for your functions.
-
The name of the compartment for the function application's virtual network (VCN). Typically, this is the same compartment as the one used for functions.
-
The name of the VCN to use for the function application.
Also, ask your administrator to verify that you belong to a group that has the necessary permissions for function developers, which includes access to these artifacts.
Set Up Your User Account for Oracle Functions
Before you can deploy custom component packages to Oracle Cloud Infrastructure Functions, you must complete these steps in the Oracle Cloud Infrastructure Console:
You'll need to know the name of the compartments and virtual network (VCN) to use and you'll need to belong to a group that allows function development as described in Get Artifact Names and Permissions for Oracle Cloud Infrastructure Functions Deployment.
-
Sign into the Console and, in the top bar, select the region that the function-development compartment is in.
-
You'll deploy to Oracle Cloud Infrastructure Functions through the Oracle Cloud Infrastructure Registry. If you don't already have a registry repository that you can use, then do the following to create one.
-
Click
on the top left to open the navigation menu, click Developer Services, click Container Registry, and then, in the List Scope section, select the compartment that's been set up for function development.
-
Click Create Repository.
-
Give the repository a name, and then click Create Repository.
-
-
If you don't have a functions application for your custom component packages, you'll need to create one. From the Developer Services page, click Functions, and then click Create Application. Provide a name, select a VCN, select at least one subnet, and click Create.
If you don't see any VCNs to choose from, you might not be in the correct region.
There are limits to the number of applications and functions. For the default limits, see Functions Limits in Oracle Cloud Infrastructure Documentation .
-
On the Applications page, click the application that you use for function deployment, click Getting Started in the Resources section, and then click Local Setup.
As shown in the following screenshot, the page displays several commands that you'll need to use to set up your local computer and to deploy your custom component package. Copy and save the commands for steps 3 through 7.
You'll use these later after you've installed the required software on your local machine and are ready to deploy your custom components. Alternatively, bookmark this page so that you can return to it when you need to use the commands.
Don't run these commands now. Just copy them.
-
In your copied command that looks similar to the following, change
[OCIR-REPO]
to the name of your registry repository.fn update context registry phx.ocir.io/devdigital/[OCIR-REPO]
-
Click the Profile icon in the top-right corner, and then click User Settings to go to the User Details page.
-
In the next step you'll create a PEM file that you need to store in a
.oci
folder on your local machine. If your home folder on your local machine doesn't have this directory, create one from a terminal window.-
Linux and Mac:
cd ~ mkdir .oci
-
Windows:
cd C:\Users\<your-user-name> mkdir .oci
-
-
You need a public and private
PEM
file for secure access. If you haven't set one up for your user account yet, then, from User Details in the Console, click API Keys from the Resources section, and then click Add API Key.Save the private key file (the
PEM
file) to the.oci
directory in your home folder. - Make a note of the Fingerprint that's associated with the API key. When you have multiple API keys, you must know which fingerprint to use for each private
PEM
file. -
If you haven't already set up a
config
file for the fingerprint on your local machine, then, from the API Keys section, do these steps:-
Click
in the row for your API key's fingerprint and then click View Configuration file.
-
Copy the Configuration File Preview content.
-
In the
.oci
folder on your local machine (the same folder that you saved your private key file in), create a file namedconfig
and paste the copied contents into the file.
-
-
In the
config
file, change thekey_file
property to point to the location of your private PEM file. For example:key_file=/home/joe/.oci/my-private.pem
-
If you don't have an auth token, click Auth Tokens in the Resources menu, and then click Generate Token. Copy the auth token immediately to a secure location from where you can retrieve it later because you won't see the auth token again in the console. You use the auth token as a password when you sign in to push your custom component package to the Oracle Infrastructure registry for deployment.
Set Up Your Local Machine for Oracle Functions
You'll need to install cURL, the OCI command line interface (CLI), Fn, and Docker on your local machine to enable deployment to Oracle Cloud Infrastructure Functions. If your machine runs on Windows, then you must do one of the following options to use Fn:
-
Install Fn and Docker on Linux in an Oracle VM VirtualBox by following the steps in this topic.
-
Install Docker and Fn on Windows, and then install the Linux subsystem for Windows as described in How-to: Run Fn client on Windows and connect to a remote Fn server.
- Deploy your custom components from Cloud Shell. See Cloud Shell in Oracle Cloud Infrastructure Documentation.
To set up your local machine:
-
(Windows on VM only) If you want to use a Linux guest on Oracle VM VirtualBox to deploy your custom component package to Oracle Cloud Infrastructure Functions, follow these steps:
-
Install VirtualBox from https://www.virtualbox.org/.
-
Download a Linux ISO. For example, to get the ISO for Ubuntu-Mate, go to https://ubuntu-mate.org/download/ and click 64-bit PCs/Macs.
-
In VirtualBox, create a virtual machine from the ISO. You can find instructions for creating a Ubunto-Mate virtual machine at https://itsfoss.com/install-linux-in-virtualbox/. This will be your Linux guest.
-
Start the Linux guest.
-
From a terminal window, run this command:
sudo apt-get update
This updates the package lists for new packages and packages that need upgrading.
Tip:
To open a terminal window in Ubuntu, press Ctrl-Alt-T. -
To be able to do things like copy and paste in a terminal window, you'll need the guest additions. Download http://download.virtualbox.org/virtualbox/<release>/VBoxGuestAdditions_<release>.iso and install and configure the additions using the instructions at https://itsfoss.com/virtualbox-guest-additions-ubuntu/
Be sure to configure configured Devices > Drag and Drop to bidirectional.
-
Enter this command in a terminal window to install node.js and npm on the guest.
sudo apt install npm
-
Drag the
.oci
folder in your home directory on your local machine into the home folder on the Linux guest.Because it's a hidden file, you must press Ctrl-H or select View > Show Hidden Files in the home folder to see it.
-
From the
.oci
folder on the Linux guest, open theconfig
file and changekey_file
to point to the location of the file in your Linux guest. For example:key_file=/home/joe/.oci/my-private.pem
-
Complete the remaining steps in this topic from the Linux guest.
-
- (Mac only) If you haven't already, install Homebrew to enable you to install cURL, OCI CLI, and Fn. See https://docs.brew.sh/Installation. Alternatively, you can use the equivalent MacPorts commands.
-
If your Internet access is through a VPN, then you might need to set up proxies. For example:
export http-proxy = http://<external_ip>:80 export https-proxy = http://<external_ip>:80 export no_proxy = localhost,127.0.0.1,<list> export noproxy = localhost,127.0.0.1,<list> export no_proxy = localhost,127.0.0.1,<list> # Example for apt nano /etc/apt/apt.conf Acquire::http::Proxy "http://<external_ip>:80"; Acquire::https::Proxy "http://<external_ip>:80";
-
Run the appropriate command to bring the packages up to date.
-
Linux:
sudo apt update && sudo apt upgrade
-
Mac:
brew update && brew upgrade
-
-
(Linux only) You'll use cURL to install OCI and Fn. Enter this commeand in a terminal window. The last statement is to verify that it installed successfully.
sudo apt install curl curl --version
-
Fn uses the OCI CLI to deploy the custom components to Oracle Cloud Infrastructure Functions. Run the appropriate command to install the CLI, and accept all defaults.
-
Linux:
bash -c "$(curl -L https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.sh)"
-
Mac:
brew update && brew install oci-cli
- Windows (if using Linux subsystem on Windows): Follow the Windows steps in Quickstart in Oracle Cloud Infrastructure Documentation.
-
-
In Set Up Your User Account for Oracle Functions, you created a
config
file. You now need to configure the CLI to use that file. Open a new terminal window, run this command, provide the location of yourconfig
file, and then entern
for the remaining questions (yourconfig
file already has the necessary settings).oci setup config
For example:
$ oci setup config This command provides a walkthrough of creating a valid CLI config file. ... Enter a location for your config [/home/joe/.oci/config]: Config file: /home/joe/.oci/config already exists. Do you want add a profile here? (If no, you will be prompted to overwrite the file) [Y/n]: n File: /home/joe/.oci/config already exists. Do you want to overwrite (Removes existing profiles!!!)? [y/N]: n
-
You need Docker 17.10.0-ce or later to push the custom component package to the registry.
-
For Ubuntu, the installation instructions are at https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository
-
For Mac, the installation instructions are at https://docs.docker.com/docker-for-mac/install/
See https://docs.docker.com/engine/install/linux-postinstall/ if you don’t want to preface the
docker
command withsudo
. -
-
If you are using VPN, then follow the instructions at https://docs.docker.com/network/proxy/
If you are using Linux subsystem on Windows, you can set the proxies from Resources page in the Docker Desktop Settings.
-
Ensure that Docker is running. You can't start Fn, which you install next, if Docker isn't running.
-
You'll use Fn, which is a lightweight Docker-based serverless-functions platform, to configure the context and deploy the package. If you haven't installed it already, follow the instructions for installing Fn, starting the Fn server, and testing the installation at https://fnproject.io/tutorials/install/
You don't need to configure the context or set the registry at this time. You'll do this when you complete the steps in Deploy the Custom Components to Oracle Cloud Infrastructure Functions.
Modify the Custom Component Package for Oracle Functions
Before you can deploy a custom component package to Oracle Cloud Infrastructure
Functions, you'll need to add func.js
and func.yaml
files, add a developer dependency for the fnproject FDK, and install the FDK.
(Windows VM only) If you are using a Linux guest, complete these steps on your local machine and then use drag-and-drop to copy the component package to your Linux guest. Alternatively, install node.js and the Bots Node SDK, as described in Step 1: Install the Software for Building Custom Components, on your Linux guest before you do the steps.
-
If you used the
bots-node-sdk init
command to create your custom component package, it may have created a file namedDockerfile
in the top folder. If so, you must delete it. Otherwise, your deployment will fail. -
In the top folder for your custom component package (the folder that contains
main.js
), create a file namedfunc.js
, and then add the following code. This is the file that Oracle Cloud Infrastructure Functions will invoke./*** This function handles an invocation that sets the "Oracle-Bots-Fn-Path" header to determine which component to invoke or if metadata should be returned. ***/ const fdk = require('@fnproject/fdk'); const OracleBotLib = require('@oracle/bots-node-sdk/lib'); const path = require("path"); const BOTS_FN_PATH_HEADER = "Oracle-Bots-Fn-Path"; const METADATA_PATH = "metadata"; const COMPONENT_PREFIX = "components/"; let shell; let componentsRegistry; const getComponentsRegistry = function (packagePath) { let registry = require(packagePath); if (registry.components) { return OracleBotLib.ComponentRegistry.create(registry.components, path.join(process.cwd(), packagePath)); } return null; } componentsRegistry = getComponentsRegistry('.'); if (componentsRegistry && componentsRegistry.getComponents().size > 0) { shell = OracleBotLib.ComponentShell({logger: console}, componentsRegistry); if (!shell) { throw new Error("Failed to initialize Bots Node SDK"); } } else { throw new Error("Unable to process component registry because no components were found in package: " + packagePath); } const _handle = function (input, ctx) { let botsFnPath = ctx.getHeader(BOTS_FN_PATH_HEADER); if (!botsFnPath) { throw new Error("Missing required header " + BOTS_FN_PATH_HEADER); } else if (botsFnPath === METADATA_PATH) { return shell.getAllComponentMetadata(); } else if (botsFnPath.startsWith(COMPONENT_PREFIX)) { let componentName = botsFnPath.substring(COMPONENT_PREFIX.length); if (!componentName) { throw new Error("The component name is missing from the header " + BOTS_FN_PATH_HEADER + ": " + botsFnPath); } return new Promise((resolve) => { let callback = (err, data) => { if (!err) { resolve(data); } else { console.log("Component invocation failed", err.stack); throw err; } }; shell.invokeComponentByName(componentName, input, {logger: () => console}, callback); }); } }; fdk.handle(function (input, ctx) { try { return _handle(input, ctx); } catch (err) { console.log("Function failed", err.stack); throw err; } });
-
In the same folder, create a file named
func.yaml
and then add the following content:schema_version: 20180708 name: <custom component package name> version: 0.0.1 runtime: [node11|node14] build_image: [fnproject/node:11-dev|fnproject/node:14-dev] run_image: [fnproject/node:11|fnproject/node:14] entrypoint: node func.js
-
In the
name
property, change<custom component package name>
to the name of your custom component package, and then save your changes. The name is typically the same as the name that you specify in thepackage.json
file.The name should be no more than 255 characters and contain only letters, numbers,
_
, and-
. -
Set these properties:
-
runtime
: The Node language and version. Specifynode11
ornode14
. -
build_image
: The build-time base image that contains the language-specific libraries and tools to build executable functions. Specifyfnproject/node:11-dev
orfnproject/node:14-dev
. -
run_image
: The runtime base image that provides the language-specific runtime environment in which to run executable functions. Specifyfnproject/node:11
orfnproject/node:14
.
-
-
In a terminal window, change to the package's top folder and enter this command to install the FDK and to add it as a package dependency in the
package.json
file:npm install --save-dev @fnproject/fdk
-
(Optional – Linux, Mac, and Linux subsystem on Windows only) Run this command to install package dependencies:
npm install
Note that if the
node_modules
folder doesn't exist, then thefn deploy
command that you do later will invokenpm install
for you. -
(Windows VM only) Complete these steps to copy your custom component code to your Linux guest for deployment:
-
Drag-and-drop the top level folder to the Linux guest.
-
In a terminal window, change to the top-level folder (the one that contains
main.js
) and type this command to add execute permissions for the folder.chmod 755 components
-
Delete the
node_modules
folder to ensure that you don't have any platform-dependent node modules. -
(Optional) Run this command to reinstall the node module dependencies.
npm install
Note that if the
node_modules
folder doesn't exist, then thefn deploy
command that you run later will invokenpm install
for you.
-
You are now ready to complete the steps in Deploy the Custom Components to Oracle Cloud Infrastructure Functions.
Deploy the Custom Components to Oracle Cloud Infrastructure Functions
After you create the func.js
file, add fnproject to the development dependencies, and install the dependencies as described in Modify the Custom Component Package for Oracle Functions, you are ready to deploy a Docker image of the component package to Oracle Cloud Infrastructure
Functions.
When you completed the steps in Set Up Your User Account for Oracle Functions, you copied commands from the Local Setup on the Getting Started page for steps 3 through 7. You'll use these copied commands to deploy your custom components.
If you're using Cloud Shell, then use the similar commands shown in Cloud Shell Setup instead.
To deploy the custom components:
-
Ensure that Docker and the Fn server are running.
-
In a terminal window, change to the top directory for your custom component package and enter your equivalent copied commands to configure the context.
fn create context <context> --provider oracle fn use context <context> fn update context oracle.compartment-id <compartment-ocid> fn update context api-url https://functions.<region-identifier>.oci.oraclecloud.com
You don't have to run these commands again until you need to change the context configurations.
If you get the error "Fn: error replacing file with tempfile" when you change the context, then manually edit
~/.fn/config.yaml
and change the context in that file. -
If your config file has multiple profiles, enter this command to point to the profile that you created in Set Up Your User Account for Oracle Functions.
fn update context oracle.profile <profile-name>
-
To point the registry repository that you created in Set Up Your User Account for Oracle Functions, enter your copied command that's equivalent to the following. If you haven't already, change
[OCIR-REPO]
to the name of your repository.fn update context registry <region-key>.ocir.io/<tenancy-namespace>/[OCIR-REPO]
You don't have to run this command again until you need to change the repository configuration.
-
If you haven't signed into Docker in your current session, run the copied command that's equivalent to the one shown here.
When it prompts you for a password, enter your auth token, which is the token that you obtained while completing the steps in Set Up Your User Account for Oracle Functions.
docker login -u '<tenancy-namespace>/<user-name>' <region-key>.ocir.io
-
To deploy the custom components, run this command:
fn deploy --app <application>
If you see the following message, open the
.oci/config
file and verify thatfingerprint
shows the correct fingerprint for the specifiedkey_file
. If not, go to your user settings in the Console, click API Keys, view the configuration file for the correct fingerprint, and then replace the content of your config file with the displayed content.Fn: Service error:NotAuthenticated. The required information to complete authentication was not provided or was incorrect.. http status code: 401.
Your custom components are ready to use in a skill as described in Add Oracle Function Service.
Deploy to Mobile Hub
To host a custom component package in Mobile Hub, use the bots-node-sdk pack --service mobile-api
CLI to copy your component package folders and make a few changes that are specific to Mobile Hub, including the RAML file. Then create the custom API from the RAML file, and upload a ZIP of the component package into the custom API.
-
From the custom component package's top-level folder (the one that contains the
main.js
file), type this command in a terminal window:bots-node-sdk pack --service mobile-api
The command does the following:
- Copies the files and subfolders to
service-mobile-api-<package version>
. - Adds a
component.service.raml
file, which contains the necessary endpoints and operations. - Creates an
api.js
file, which is a Mobile Hub wrapper formain.js
. - Modifies the
package.json
file to set the main file toapi.js
, set the dependencies, and add the Mobile Hub node configuration.
This step shows the basic CLI command. For more information, see
https://github.com/oracle/bots-node-sdk/blob/master/bin/CLI.md
. - Copies the files and subfolders to
- Review the
package.json
file and verify that the package name conforms to the following Mobile Hub constraints. Modify the name as necessary to conform.- The name must consist only of letters (A-Za-z), numbers (0-9), and underscores (_).
- The name must begin with a letter.
- The name must be 100 characters or less.
-
From the Mobile Hub APIs page, click New API > API, and then create the custom API by uploading the
component.service.raml
file. -
From the Security tab, switch off Login Required and then click Save.
-
Zip up the
service-mobile-api-<package version>
folder, and then upload the ZIP file from the custom API’s Implementation tab. -
From the Test page, invoke the
GET
request. The response should show the component metadata.Tip:
If you get a status 500, and the error is that it can’t find a matching route definition, check your files for bad JavaScript syntax, as that is the typical cause.
Task 3: Add Component Package to a Skill
You add a component package to a skill by creating a component service. For component packages that you host on an external server, Oracle Cloud Infrastructure Functions, or on Oracle Mobile Hub, a component service is an active connection from the skill to host server. Alternatively, you can upload the component package and host it from your Oracle Digital Assistant instance. This is referred to as an embedded component service.
A component service has two functions:
-
It queries the component to get the package metadata, including the names of the components, their properties, and allowed actions for each one. After a service is added to the skill, you can see this information in the Components tab, which you access by clicking Components
in the left navbar. You can reference this page to get the component names, properties, and actions, which you will need to use the components in your dialog flow.
-
It allows the skill to invoke the components.
The JSON payload of the call made by the Dialog Engine to the components includes input parameters, variable values, user-level context, and the user’s message text. The component returns the results by changing the values of existing variables or adding new ones (or both). The Dialog Engine parses the returned payload and proceeds.
To add a custom component package to a skill, go to the skill's Components tab and click Add Service, which opens a dialog for configuring the service.
How you configure the service depends on where you are hosting the component package. These topics provide instructions for each type:
After you create the service, you can invoke the custom components from your dialog flow as described in Custom Components.
When you upload a package to the embedded container, Digital Assistant verifies that the package is valid, and can reject the package for these reasons:
-
There are JavaScript errors.
-
The package doesn't contain all the node module dependencies.
-
A component name has more than 100 characters, begins with
System.
, or contains other than alphanumeric characters and underscores, then the service creation fails. -
Your instance already has the maximum number of embedded component services.
-
The TGZ file is too large. This typically happens when the
.npmignore
file doesn't contain a*.tgz
entry and therefore, every time you pack the files, a nested copy of the existing TGZ is added.
See Add Embedded Component Service for more information about these verification checks.
Add Embedded Component Service
If you want to host the custom component package from your Oracle Digital Assistant instance, complete these steps:
Prepare the Package for an Embedded Container Service
If you want to host the custom component package from Oracle Digital Assistant as an embedded component service, you must first pack the custom components into a TGZ file. Then, when you create the embedded component service, you upload this file.
This TGZ file, which you package using bots-node-sdk pack
, must contain the assets and structure described in Task 1: Implement Custom Components. It also must contain all the node modules that it depends on (the bots-node-sdk pack
does that for you).
There's a limit to how many embedded custom component services an instance can have. If you don't know the limit, ask your service administrator to get the
embedded-custom-component-service-count
for you as described in View Service Limits in the Infrastructure Console. If you try to add a component service after you meet that limit, then the service creation fails.
To prepare a package for uploading to the embedded container service:
-
Ensure that you have the latest version of the Bots Node.js command line tools.
The embedded container requires that the TGZ file includes all
dependencies
. Earlier versions did not bundle thedependencies
into the file. Now, the command that you'll use to create the TGZ file ensures that yourpackage.json
file contains abundledDependencies
node that lists all the dependent modules that need to be included in the TGZ file. -
In the directory that contains the
main.js
file, run the following command for each of the modules that your package depends on. You don't need to do this fordevDependencies
, such as the Bots Node SDK.This command adds the module to the
node_modules
folder and adds it as a dependency inpackage.json
.npm install <module>
If your
package.json
already names all the dependencies, then you can runnpm install
instead. -
Ensure that the top-level folder contains an
.npmignore
file that has a*.tgz
entry. For example:*.tgz spec service-*
Otherwise, when you pack the files into a TGZ file, you include the TGZ file that already exists in the top-level folder, and your TGZ file will double in size. After you pack the files a few times, the TGZ file will be to large to upload into the container.
-
Run this command:
bots-node-sdk pack
This command validates the component package, updates it to include
devDependencies
if necessary, and then creates a TGZ file, which you'll upload when you create an embedded component service from the skill’s Components tab. Note that the files you've listed asdependencies
are included asbundledDependencies
, with the exception of the Bots Node SDK and Express, which aredevDependencies
.
Your package should be compatible with Node 14.17.0.
For more information about the pack
command, see https://github.com/oracle/bots-node-sdk/blob/master/bin/CLI.md
.
Upload Package to Create an Embedded Component Service
After you pack a custom component package into a TGZ file, you can upload it to create an embedded component service from the skill's Components tab.
To learn how to create the TGZ file, see Prepare the Package for an Embedded Container Service.
When you upload the package to the embedded component service, it's deployed to Oracle Functions Service. If your instance is provisioned on the Oracle Cloud Platform (as all version 19.4.1 instances are), then the service is instead deployed within the Digital Assistant instance.
To create the embedded component service:
-
From the skill, click Components
.
-
Click
.
-
Select Embedded Container.
-
Click Upload a component package file and point to the TGZ file to upload, or drag the file to the Package File box.
-
(Optional) If you want to send custom component
context.logger()
statements to the service's log, then switch Enable Component Logging to On. This switch is available only in instances of Oracle Digital Assistant that were provisioned on Oracle Cloud Infrastructure (sometimes referred to as the Generation 2 cloud infrastructure).You can see the log from the Components tab by clicking Diagnostics > View Logs.
Note
The skill keeps a log entry for two days. When you delete an embedded custom component service, the skill's log entries for that service are deleted. -
Click Create.
Digital Assistant uploads the TGZ file and creates the embedded component service. During the upload, Digital Assistant verifies that the package is valid, and can reject the package for the reasons that are described later in this section.
After you upload the TGZ file, the custom component service is built and its components are deployed. If the Components page displays an awaiting deployment message after you upload the TGZ file, it means that the service has been created, but is not yet available. When the service becomes available, the deployment metadata displays in place of the awaiting deployment message.
-
Ensure that Service Enabled is switched to On.
During the upload, Digital Assistant might reject the package. Here are reasons for rejection and ways to resolve the issues.
-
JavaScript contains syntax errors: If a component's JavaScript has syntax errors, then that component is not added to the container, which results in this error message:
Error Message: failed to start service built: Invalid component path:
View the component files in an editor that detects syntax errors. Also, try hosting the package on a local server that sends error messages to a console log.
Another reason for this message might be that the package doesn't contain all the node module dependencies. See the next item in this list.
-
Missing node modules: If the package doesn't contain all the node module dependencies, then you'll get the same error message as above:
Error Message: failed to start service built: Invalid component path:
To learn how to include node module dependencies, see Prepare the Package for an Embedded Container Service.
-
Component name is too long: If a component name has more than 100 characters, begins with
System.
, or contains other than alphanumeric characters and underscores, then the service creation fails.Change the name in the component's JavaScript, repackage, and upload again.
-
Exceeded component service limit: If your instance already has the maximum number of embedded custom component services, then the service creation fails. Ask your service administrator for the
embedded-custom-component-service-count
limit as described in View Service Limits in the Infrastructure Console.If you need to raise the limit, you can request an increase. See Requesting a Service Limit Increase.
-
TGZ file is too large: This typically happens when the
.npmignore
file doesn't contain a*.tgz
entry and therefore, every time you pack the files, a nested copy of the existing TGZ is added.When the top-level folder contains an
.npmignore
file with*.tgz
, the previous version of the TGZ file isn't included when you update the package.
If you want to send custom component context.logger()
statements to the service's log, then switch Enable Component Logging to On. This switch is available only in instances of Oracle Digital Assistant that were provisioned on Oracle Cloud Infrastructure (sometimes referred to as the Generation 2 cloud infrastructure).
When Enable Component Logging is switched to On, you can click the Diagnostics button for the service to access view logs and crash reports to diagnose the problem.
- Select View Logs to view messages that the custom component sends to
context.logger()
. This feature is available only in instances of Oracle Digital Assistant that were provisioned on Oracle Cloud Infrastructure (sometimes referred to as the Generation 2 cloud infrastructure). The Enable Component Logging switch must be On for the log to contain these messages. - Select View Crash Report to view details about what may have caused the container to crash.
After you create the service, you can invoke the custom components from your dialog flow as described in Custom Components.
Add Oracle Function Service
You can deploy your custom components to Oracle Cloud Infrastructure Functions and add them to a skill as an Oracle Function service.
To add an Oracle Function service:
-
You'll need to know the function's URL. A user with function development privileges can get the URL from the Integration Console for you.
- Sign in to the Integration Console.
-
Click
on the top left to open the navigation menu, click Developer Services > Functions, and then select the compartment that's been set up for function development.
-
Click the application.
-
In the Functions section, click the More icon for your function and click Copy Invoke Endpoint. Skill developers need this value to add the custom component package as a component service in a skill.
-
A skill developer adds the component service to a skill in Oracle Digital Assistant. Sign into Oracle Digital Assistant, open the skill and click Components
.
-
Click
.
-
Provide a name and description for the service.
-
Select Oracle Function.
-
In the URL text box, enter the invoke endpoint URL that you copied from the Developer Services > Functions page in the Infrastructure Console while completing the steps in Set Up Your User Account for Oracle Functions.
-
Click Create.
If you get a "Can't Create the Service" error, go to Developer Services > Functions in the Infrastructure Console, select the compartment, click the application, and click Logs in the Resources menu. Then enable the log for the function, retry the deployment, and check the logs (click the log name to see the log). To learn more about logs, see Storing and Viewing Function Logs in Oracle Cloud Infrastructure Documentation.
If you see an error like this, it's because the folder doesn't have the right permissions. On your local machine, use
chmod 775
to change the folder's permissions, then redeploy:"Error: EACCES: permission denied, stat '/function/components/hello.world.js.js'"
If you see an error like this then, on your local machine, delete
node_modules
, runnpm install
and redeploy."Error: Cannot find module '@fnproject/fdk'"
-
Ensure that Service Enabled is switched to On.
After you create the service, you can invoke the custom components from your dialog flow as described in Custom Components.
Add External Component Service
You can host your custom components on your own Node.js server and add them to a skill as an external component service.
Tip:
You can use the external service option during development, as described in Run the Component Service in a Development Environment.To add an external component service:
-
From the skill, click Components
.
-
Click
.
-
Select External.
-
In the Metadata URL text box, enter the The URL that points to the GET endpoint that returns the list of components.
-
Enter the service's user name and password.
-
Click Create.
-
Ensure that Service Enabled is switched to On.
After you create the service, you can invoke the custom components from your dialog flow as described in Custom Components.
Add Mobile Hub Component Service
You can host your custom components from Oracle Mobile Hub, and add them to a skill as an Oracle Mobile Cloud component service. Custom components that are hosted on Mobile Hub can integrate with remote services using connectors that are controlled by a Mobile Hub backend and they have access to the Mobile Hub platform APIs.
Because the backend that hosts the custom code handles the authentication for the custom components, you need to refer to the backend’s Settings page to get the information that you need to complete the configuration.
To add a component service for the Mobile Hub backend:
-
From the skill, click Components
.
-
Click
.
-
Select Oracle Mobile Cloud.
-
Enter the unique identifier assigned to the Mobile Hub backend in the Backend ID field. This ID is passed in the REST header of every call from the skill.
-
In the MetadataURL field, enter the
/components
endpoint from the custom code API. For example,http://<server>:<port>/mobile/custom/ccPackage/components
. -
Choose Use Anonymous Access if the service allows anonymous login. If you choose this option, enter the anonymous key, which is a unique string that allows your app to access anonymous APIs without sending an encoded user name and password. The anonymous key is passed in their place. You can find the anonymous key on the backend's Settings page in Mobile Hub. (You may need to click Show.)
If the component service requires a login (meaning no anonymous access), then enter the user name and password.
-
If the service requires specific parameters, click Add HTTP Header and then define the key-value pairs for the headers.
-
Click Create.
-
Ensure that Service Enabled is switched to On.
After you create the service, you can invoke the custom components from your dialog flow as described in Custom Components.
Export and Import a REST Service Endpoint
If you have registered REST service endpoints in one Oracle Digital Assistant instance, you can make those endpoints available in a separate instance by exporting them from the first instance and importing them into the other instance. Here are the steps:
-
In the Digital Assistant where you have the registered the REST service, click
to open the side menu, select Settings, select API Services, and then click the REST Services tab.
- From the More menu, select Export All REST
Services.
(Alternatively, you export individual REST services by selecting the service and then selecting More > Export Selected REST Service.)
You should see a file downloaded to your system.
- In the Digital Assistant instance where you want to import the services, go to the same page (Settings > API Services > REST Services), select More > Import REST Services, and select the file that you just exported from the first instance.