Skip to main content

Sharing action tags across projects

JAICP DSL has special action tags, which allow a state to execute a separate script. If the features of built-in action tags aren’t enough for you, you can create your own.

By default, your custom tags are only available within the project where they were created. However, through additional configuration you can make any tag available from all projects in the same account. For example, you can assign a project to be a “library” of action tags that you need frequently. You can then use these tags in other projects without any prior initialization.

How to create a shared tag

This article is a step-by-step tutorial describing how to develop an InputName tag, which will make the bot ask the user their name and save it to the $client.name variable.

tip
The How to create custom action tags article explains how to create a tag in more detail. It is advised to read it first before continuing to this one.

Step 1. Create the project

Create a new project for your future action tag library. In this project, create the files and directories for the InputName action tag. The final project may be structured like this:

├── src
│ ├── blocks
│ │ └── InputName
│ │ ├── block.json
│ │ └── block.sc
│ └── main.sc
├── test
│ └── test.xml
└── chatbot.yaml

Step 2. Configure the tag settings

Configure the tag settings in the block.json file.

tip
To make the tag shared across the account, specify the "sharedForAccount": true property.
{
"tagName": "InputName",
"startState": "/Blocks/InputName",
"scenarioFile": "blocks/InputName/block.sc",
"sharedForAccount": true,
"parameters": [
{
"name": "prompt",
"type": "string",
"required": true
},
{
"name": "fallbackName",
"type": "string",
"required": true
},
{
"name": "then",
"type": "state",
"required": false
}
]
}

Step 3. Write the script

Write the tag script in block.sc.

# The script imports the built-in dictionary of given names.
# This will enable it to recognize names using the `$Name` pattern.
require: name/nameEn.sc
module = sys.zb-common

theme: /Blocks

state: InputName
script:
// The values of tag parameters are copied from the `$request.data.args` object to `$session`.
// This will allow referencing them from the following state rather than `InputName` only.
$session.InputName = $request.data.args;
# The bot sends a reply with the text passed as the `prompt` parameter.
a: {{$session.InputName.prompt}}

state: CatchName
# This state is triggered by the `noMatch` event, so the bot will transition to it on any input.
# However, processing the input with the `$Name` pattern is specified separately.
q: * $Name *
event: noMatch
script:
// `$client.name` is assigned either the recognized dictionary name
// or the fallback name passed as a tag parameter.
$client.name = $parseTree._Name
? $parseTree._Name.name
: $session.InputName.fallbackName;

// Here we build a `context-return` reply to exit from the tag to the main script.
var reply = { type: "context-return", data: {} };
// If the next state is passed as a tag parameter, it is saved as a reply property.
// Otherwise, the appropriate state will be selected dynamically during the bot runtime.
if ($session.InputName.then) {
reply.state = $session.InputName.then;
}
// The `$response.replies` array is formed using the reply.
$response.replies = [reply];

Additionally, since users won’t be able to interact with this project as a regular bot, remove all existing states from main.sc. The only remaining state should be NoMatch with this bit of custom logic:

theme: /
state: NoMatch
event!: noMatch
script:
$response.replies = [{ type: "context-return", data: {} }];

Step 4. Enable the tag

  1. In the customTags section of the chatbot.yaml configuration file, specify the path to the settings file:

    customTags:
    - src/blocks/InputName/block.json
  2. Select in the top right corner to save the changes made in the source code editor.

  3. Select Test the bot to deploy the script.

tip
Don’t worry if the test widget displays the Bot stack is empty error. Real users will not encounter this error because they won’t be launching this bot directly.
caution
Any time you make changes to the script tag, you should always save and deploy them so they are applied to other projects.

Step 5. Use the tag in other projects

Now you can go to any other project and use the newly created tag. Just like any other tag, it will be available in the project code as well as in J‑Graph an action block.

state: Start
q!: $regex</start>
a: Hi!
InputName:
prompt = What‘s your name?
fallbackName = stranger
then = /Start/NiceToMeetYou

state: NiceToMeetYou
a: Nice to meet you, {{$client.name}}!

Context management

When you use action tags, it is crucial to understand what happens to the context of users’ conversations with the bot whose script contains these tags.

Context switch

When dealing with local action tags (tags created and used in the same project), calling one of these tags does the same thing as transitioning to its start state using go! or $reactions.transition. Returning from this tag to the main script can also be achieved with a simple transition.

However, if a tag is shared, its usage is actually implemented as switching the context to another project via context-switch rather than a transition. At the end of any tag script, you need to return the context from the bot containing shared tags back to the main one.

Context return

Any shared tag script should always end with a context return via a context-return reply. Users shouldn’t be able to make a transition anywhere other than the tag script: this is why the example above recommends removing almost every state from main.sc and adding a context return to the global NoMatch.

caution
If you don’t implement context-return in a shared tag, users will “get stuck” in the tag’s script and will not be able to resume the conversation with the main bot.

Sharing tags across all users

On-premise

If JAICP is installed in your own infrastructure, your employees can create action tags that will be available to all users of your installation.

  1. Developers create a remote repository with a JAICP project, where they add a new tag as per the tutorial above. The "sharedForPlatform": true property should be specified in the tag settings.
  2. System administrators should add the repository settings to the overriding configuration of the EditorBE component, then restart the component:
configs/hosts/{env_name}/editorbe/application-override.yml
system-projects:
projects:
# Default system projects…

- url: https://gitlab.custom.com/custom-tags # Repository URL.
project-id: custom-tags # Project ID.
bot-id: custom-tags # Bot ID. Can be the same as project-id.
branch: main # Branch in the project repository, master by default.
tip
Always specify bot-id for system projects with action tags, so that these projects get deployed and JAICP can use them for context switching via context-switch.
  1. Users of your JAICP installation will be able to use the new tag just like any other built-in tag.