aura-behavior-manager utility

Guidelines for using aura-behavior-manager utility that allows modifying the behavior of Aura Bot or Aura Bridge in development environments without restarting them

Introduction

The main feature of the aura-behavior-manager is to be able to change the application (aura-bot or aura-bridge) behavior in development environments. All these changes can be made to the fly, without the need to restart the bot/bridge instance.

For this purpose, the aura-behavior-manager makes use of a series of commands linked to each of the previously configured behavior that can be sent to application in a specific format.

⚠️ WARNING

  • aura-behavior-manager must be exclusively used in development environments.
  • Do not use in production environments, as it disrupts Aura behavior and can lead to a faulty operation of the system.

As an example, aura-behavior-manager could change the value of an environment variable AURA_TERMS_AND_CONDITIONS_EXPIRATION:

/bot:set:property AURA_TERMS_AND_CONDITIONS_EXPIRATION 10000

Components and class hierarchy

To implement the aura-behavior-manager, you should make use of @telefonica/aura-behavior-manager library. This contains the following components:

  • BehaviorManager: Base class from which you must extend a specific BehaviorManager (Example: BotBehaviorManager, BridgeBehaviorManager).

  • BehaviorCommandControl: Responsible for the tasks associated with user commands.

  • BehaviorStubsHandler: It allows to register/modify/restore the modified methods in the code.

  • BehaviorCoreCommands: It contains the basic commands of the behavior manager.

  • RemotelyConfigurable: Utility that allows any class to read configuration from Azure using cron.

@startuml BehaviorManager class diagram
class RemotelyConfigurable {
  storageCredentials
  storageManager
  containerName
  sourceFilePath
  cronExpression
  cronTask
  settings
  status
  lastUpdated
  +start()
  +stop()
  +read()
}

class BehaviorManager {
  name
  commandPattern
  behaviors
  commandControl
  stubsHandler
}

class BehaviorStubsHandler {
  stubs
  +start()
  +restore()
  +getStubs()
}

class BehaviorCommandControl {
  component
  commandPattern
  +isCommand()
  +getCommandList()
  +execute()
}

class BehaviorProperty {
    +setProperty()
    +unsetProperty()
    +getProperty()
    +getDefaultProperty()
    +getBehavior()
}


RemotelyConfigurable <|--down BehaviorManager
BehaviorManager *---right BehaviorCommandControl
BehaviorManager *---right BehaviorStubsHandler
BehaviorManager <|--down BehaviorProperty
BehaviorProperty <|--down BotBehaviorManager
BehaviorProperty <|--down BridgeBehaviorManager

@enduml

How that works?

In order to use the aura-behavior-manager, it must be loaded at the component start (aura-bot/aura-bridge).

Once it has started, it will load the list of behaviors (can be identified as plugins) that will allow certain actions to modify the behavior of the component. Examples of these behaviors can be: Property, Profile, etc. In the section Description of a Behavior, a behavior is described in detail.

When a message is received, the BehaviorCommandControl is responsible for detecting if it is a command. If so, it tries to execute the command associated with the behavior that defines it:


@startuml Behavior manager command control flow
start
#palegreen:message;

if (text message is command?) then (true)
  #cyan:Execute command using "commandControl";
  #cyan:Reply with command response;
  end
endif

#palegreen:Process the message normally;

stop
@enduml

Description of a behavior

A behavior is the minimum unit that allows defining a change in the behavior of the system (aura-bot, aura-bridge).

Every behavior to be incorporated to aura-behavior-manager must implement the following interface:

/**
 * @interface BehaviorComponent
 */
export interface BehaviorComponent {
    getBehavior: () => BehaviorComponentInformation;
}

/**
 * @interface BehaviorComponentInformation
 * Behavior information
 */
export interface BehaviorComponentInformation {
    /**
     * Behavior name.
     */
    name: string;
    /**
     * Behavior description.
     */
    description?: string;
    /**
     * Information with the piece of code used as a substitute for other functionality.
     */
    stub?: BehaviorStubInformation;
    /**
     * Command information associated with this behavior.
     */
    commands: BehaviorCommand[];
}

Therefore, a behavior has the following properties:

  • name (*): Behavior name.
  • description: Behavior description.
  • stub: As it is done in unit tests, it allows defining a code that will replace the original functionality in the code.
  • commands: List of commands to invoke the different functionalities that the behavior defines.

As an example, we will create a new HelloBehavior, which will respond with a simple ‘Hello’ in the command response:

export class HelloBehavior implements BehaviorComponent {

    /**
     * Get behavior (hello).
     * @returns {BehaviorComponentInformation} Get behavior information
     */
    public getBehavior(): BehaviorComponentInformation {
        return {
            name: 'Hello',
            description: 'Hello example behavior',
            // stub -> We don't need to "stub" any code for this example
            commands: [
                { name: 'get:hello', description: 'Say hello', execute: this.getHello.bind(this) }
            ]
        };
    }

    /**
     * Say hello.
     * @param {CommandControlOptions} options Options
     */
    private async getHello(options: CommandControlOptions) {
        return 'Hello';
    }
}

Now, it would be possible to send to aura-bot:

/bot:get:hello

You can check other examples of behaviors here

Predefined behavior: the core behavior

The aura-bot-behavior library already defines a behavior that includes a series of common commands to be used by aura-bot and aura-bridge:

Name Description
get:commands Get command list
get:stubs Get stub list
set:stubs Start configured stubs
unset:stubs Restore stubs
get:status Get behavior manager status
get:settings Get full settings
get:remoteSettings Reload and Get settings from remote (force reload)
get:profiles Get profile list

As an example, we will show the list of available commands:

/bot:get:commands     # You can also use: /bot get commands

Thus, you should have a response similar to the following:

[
  {
    "name": "get:commands",
    "description": "Get command list"
  },
  {
    "name": "get:stubs",
    "description": "Get stub list"
  },
  {
    "name": "set:stubs",
    "description": "Start stubs"
  },
  {
    "name": "unset:stubs",
    "description": "Restore stubs"
  },
  {
    "name": "get:status",
    "description": "Get behavior manager status"
  },
  {
    "name": "get:settings",
    "description": "Get full settings"
  }
]

Aura Bot Behavior Manager

How to activate Aura Bot Behavior Manager?

In order to activate aura-behavior-manager in aura-bot, two environment variables must be configured with the following values:

  • AURA_SERVICE_ENVIRONMENT, with the value "DEV" and
  • DEV_AURA_BEHAVIOR_MANAGER_ACTIVE, with the value true.

With these two variables correctly configured, the BotBehaviorManager module will be added to the Orchestrator module list and a message will be shown in the startup process: ‘Behavior manager loaded’.

Defined behaviors

Below are the different behaviors defined in the Bot and the commands to be able to interact with them.

Those behaviors marked with ‘(*)’ are necessary for the BotBehaviorManager to work properly.

CommandBehavior (*)

It is the necessary behavior to be able to interact with the Bot’s behavior system, so without this behavior it will not be possible to send commands.

Stub:

Name Stub destination Description
Command control beginDialogStep Modify “beginDialogStep” function to detect and execute commands

Property behavior

It allows you to modify a list of environment variables without the need to restart the system. Currently, only the following list of variables have been enabled to be modified by the Behavior Manager:

  • AURA_ACCESS_TOKEN_EXPIRATION_MARGIN
  • AURA_MONGODB_BOT_COLLECTION_CONTEXT_INDEX_TTL

If you need to add new variables, you should use the ConfigurationManager.instance.get method on all sites where you can use that variable.

Stub:

Name Stub destination Description
Property ConfigurationManager.get Modify get function to change the value of a variable

Commands:

Name Description
set:property Set property
get:property Get property
get:properties Get properties. All properties configured by the user (conversationId)
get:defaultProperty Get default environment property. The value of the current environment variable
get:defaultProperties Get default environment properties. All current environment variables

Examples:

/bot:set:property AURA_MONGODB_BOT_COLLECTION_CONTEXT_INDEX_TTL 10 # Set property value for conversationId
/bot:get:property AURA_MONGODB_BOT_COLLECTION_CONTEXT_INDEX_TTL # Get property value for conversationId
/bot:get:properties # All properties configured by the user
/bot:get:defaultProperty AURA_MONGODB_BOT_COLLECTION_CONTEXT_INDEX_TTL # The value of the current environment variable
/bot:get:defaultProperties # All current environment variables

Aura Bridge Behavior Manager

How to activate Aura Bridge Behavior Manager ?

In order to activate aura-behavior-manager in aura-bridge, two environment variables must be configured with the following values:

  • AURA_SERVICE_ENVIRONMENT, with the value "DEV" and
  • DEV_AURA_BEHAVIOR_MANAGER_ACTIVE, with the value true.

With these two variables correctly configured, the BridgeBehaviorManager module will be added to the Orchestrator module list and a message will be shown in the startup process: ‘Behavior manager loaded’.

Settings

Environment variables that can be configured to adapt the Behavior Manager:

Name Description
DEV_AURA_BEHAVIOR_COMMAND_PATTERN Pattern to recognize a behavior command
DEV_AURA_BEHAVIOR_SETTINGS_FILE_MICROSOFT_AZURE_STORAGE Profile configuration file location for the behavior-manager
DEV_AURA_BEHAVIOR_SETTINGS_FILE_CRON_PATTERN CRON expression associated with the reload time of the configuration file

Using the default value for DEV_AURA_BEHAVIOR_COMMAND_PATTERN allows you to run commands of the type:

    /bridge:get:property DEV_AURA_BEHAVIOR_COMMAND_PATTERN
    /bridge get property DEV_AURA_BEHAVIOR_COMMAND_PATTERN
    /bridge unset proxies

The aura-behavior-manager allows to use a configuration file to manage profiles (currently disabled). This file is read at start-up and refreshed according to the variable settings DEV_AURA_BEHAVIOR_SETTINGS_FILE_CRON_PATTERN. The configuration file is stored in Azure Blob Storage. The path to this configuration file is built as follows:

AURA_MICROSOFT_AZURE_STORAGE_STATIC_CONTAINER_NAME/AURA_VERSION/DEV_AURA_BEHAVIOR_SETTINGS_FILE_MICROSOFT_AZURE_STORAGE}

An example of default location can be:

static-resources/7.2.0/aura-bridge/aura-bridge-behavior-manager.json

Further information about aura-bridge environment variables section.

Description of a bridge behavior

A behavior allows defining a change in the behavior of the aura-bridge.

In order to allow an aura-bridge plugin to manage BridgeBehaviorManager commands, the interface BehaviorComponentInformation has been extended as follows:

/**
 * @interface BehaviorComponentInformationBridge
 * Bridge behavior component information
 */
export interface BehaviorComponentInformationBridge extends BehaviorComponentInformation {
    pluginControllerStub?: (
        req: Request, res: Response, next: NextFunction,
        behaviorController: BehaviorController,
        original: (req: Request, res: Response, next: NextFunction) => Promise<void>
    ) => Promise<void>;
}

This new pluginControllerStub field defines the decorator function for plugin controllers. The original function (endpoint controller defined in the swagger) will be passed as the last argument (the original parameter).

Enable a plugin to manage behavior commands

Only the Api or Processor (extends API type) plugins can manage Behavior Manager commands.

The only action by a plugin to enable Behavior Manager command controller is to complete the information from the behaviorController field defined in the PluginApi interface:

export interface PluginApi extends Plugin {
    /**
     * If defined, the plugin can manage commands for the behavior manager.
     * This only takes effect in development environments.
     */
    behaviorController?: BehaviorController;
}

export interface BehaviorController {
    /**
     * Get request information.
     *
     * @param {express.Request} req Express request
     * @returns {AuraBridgeRequestInfo} Request information
     */
    getRequestInformation(req: Request): AuraBridgeRequestInfo;
    /**
     * Get text from input message.
     *
     * @param {express.Request} req Express request
     * @returns {string} Text message
     */
    getTextFromMessage(req: Request): string;
    /**
     * Send text message using client.
     *
     * @param {string} message Text message
     * @param {express.Request} req Express request
     * @param {AuraBridgeRequestInfo} requestInfo Request information
     */
    sendTextMessage?(message: string, req: Request, requestInfo: AuraBridgeRequestInfo): Promise<void>;
}

The getRequestInformation and getTextFromMessage functions are required and necessary to be able to recognize and execute commands. The sendTextMessage function is optional and allows the user to receive feedback from the command execution.

Defined behaviors

Below are the different behaviors defined in aura-bridge and the commands to be able to interact with them.

Those behaviors marked with ‘(*)’ are necessary for the BridgeBehaviorManager to work properly.

CommandBehavior (*)

It is the necessary behavior to be able to interact with the aura-bridge behavior system, so without this behavior it will not be possible to send commands.

Plugin controller stub:

Name Stub destination Description
Command control plugin controller Modify plugin controller to detect and execute commands

This behavior will affect those plugins that define the behaviorController field in the API type plugin definition.

CommonBehavior (*)

It defines commands that are associated with BridgeBehaviorManager itself.

Commands:

Name Description
get:conversationId Get conversation id
get:all Get all configuration associated with the current conversation
unset:all Unset all cache information associated with the current conversation

PropertyBehavior

It manages information from the aura-bridge environment variables.

Currently, only the following list of variables have been enabled to be modified by the BridgeBehaviorManager:

  • AURA_BOT_APIKEY
  • AURA_BOT_ENDPOINT
  • AURA_BRIDGE_ENDPOINT
  • AURA_FP_WHATSAPP_ENDPOINT
  • AURA_BRIDGE_REQUEST_VERSION

If you need to add new variables, you should use the ConfigurationManager.instance.get method on all sites where you can use that variable.

Stub:

Name Stub destination Description
Property ConfigurationManager.get Modify get function to change the value of a variable

Commands:

Name Description
set:property Set property
get:property Get property
get:properties Get all the properties configured
get:defaultProperty Get default environment property
unset:property Unset property (If property name is not present, all will be deleted)
unset:allProperties Unset all properties
How to redirect requests to your local Aura Bot

Set the property AURA_BOT_ENDPOINT with the next aura-bridge command and all requests in the conversation will be redirected to the local aura-bot. For example, at a local address using ngrok (https://1111-11-11-111-11.ngrok.io):

/bridge set property AURA_BOT_ENDPOINT  "https://1111-11-11-111-11.ngrok.io/api/messages"

To see the answer, you need to modify the service URL of the activity with the aura-bridge enpoint of the environment.

ProxyBehavior

It allows redirecting requests made to aura-bridge to an alternative URL.

This redirection is based on the configuration of two parameters:

  • urlPath: String to match with the value of req.path in the original request.
  • endpointDestination: URL base where the petition will be redirected.

Plugin controller stub:

Name Stub destination Description
Bridge proxy plugin controller Modify plugin controller to perform a redirection of incoming request

This behavior will affect those plugins that define the behaviorController field in the API type plugin definition.

Commands:

Name Description
set:proxy Set new proxy. Params
get:proxy Get proxy. Params [urlPath]
get:proxies Get all proxies
unset:proxy Remove proxy. Params
unset:proxies Remove all proxies

PluginBehavior

It allows you to display information regarding the aura-bridge plugins.

Commands:

Name Description
get:plugins Get all loaded bridge plugins
get:stubPlugins Get plugins with behavior manager active (can manage commands)

Use cases

How to redirect requests from WhatsApp to your local Aura bridge

Set proxy with the following aura-bridge command and all requests from WhatsApp (“whatsapp/messages”) in the conversation will be redirected to the local aura-bridge. For example, at a local address using ngrok (https://1111-11-11-111-11.ngrok.io):

/bridge set proxy "whatsapp/messages" "https://1111-11-11-111-11.ngrok.io"