One of the best ways to build reusable components to share with other developers in your organization (or with developers of other organizations through Bot Store) is through the creation of custom packages in Enterprise A2019. Custom packages look and operate just like the standard package set available from Automation Anywhere - but with the flexibility to be customized to meet the specific needs of your organization or your customers. Be it automating service calls to an internal application to validate customers by ID, or integration with cognitive services to make machine learning and AI capabilities available to other bot builders within your organization - custom packages have the power to greatly extend the out-of-box capabilities of Enterprise A2019. That capability paired with the new data types available for use in Enterprise A2019 means that there are LOTS of available options for package creation. Some of those return datatypes can be a bit tricky to work with though - so in this blog post, we'll look at how to return a dictionary to a user in a custom-developed package. If you arent familiar with the package development process, take a look at the How to build a Twilio Package tutorial for some background on how packages are developed, compiled, and tested.
If you want to download the sample code and take a look at it before following through with the rest of this blog post, you can find the code on the Automation Anywhere GitHub page.
The quickest way to start building a package is to start with the Enterprise A2019 Software Development Kit (SDK). The SDK includes examples of how to use different field types in the Enterprise A2019 UI as well as some advanced package capabilities like custom variables types, conditional statements, and attended automation capabilities. The example code that we'll be walking through for the remainder of this article was build off of the 2.0.7 release of the SDK - with lots of comments throughout to hopefully guide developers on what each section of code is doing. The screenshots and sample code were all built/taken using IntelliJ - though feel free to use the Java IDE of your choosing.
The ValuesToDictionary Class is the only non-test class defined in the project, and the only action defined in the package. Opening the class, the annotations above the class definition indicate that this class is eligible to be considered an action, and set up some of the labels/descriptions that are used in the Enterprise A2019 UI. Typically these label/description values should reference the resources>locales>language json values to make language translation of a package easier - but since this is just a POC, the values have been hard set. Most of this is all standard across any action, but the one thing important thing to call out here is how the return_label is set on the last line from the code block below. Here, we define the message label that will display above the return variable, as well as define the return type. Since this blog post is all about returning a dictionary, DICTIONARY (com.automationanywhere.commandsdk.model.DataType) is used.
//BotCommand makes a class eligible for being considered as an action.
//CommandPks adds required information to be displayed on GUI.
//Unique name inside a package and label to display.
//Typically these should be references to a locales.json variable - but this is just a Demo
name = "ValuestoDictionary", label = "Values to Dictionary",
node_label = "Dictionary Demo", description = "Demo package to demonstrate returning values in a dictionary data type", icon = "pkg.svg",
//Return type information. return_type ensures only the right kind of variable is provided on the UI.
//Setting to DICTIONARY here to establish a dictionary return
return_label = "Demo Dictionary Return", return_type = DICTIONARY, return_required = true)
Inside the class definition, the Execute annotation serves as an entry point to the action. Again - because this is a sample for explanation purposes, the comments try to go above and beyond - but the most important call-out for the top part is that the action definition determines the returned datatype - which in this case is DictionaryValue. Inside the action, two fields are defined for input - one that takes in a String value from the Enterprise A2019 interface, the other that takes in a Number value from the Enterprise A2019 interface. The only reason for taking one of each is to demonstrate how to add values of each type to a dictionary.
//Identify the entry point for the action. Because the whole point of this is to demonstrate the return of a
//a DictionaryValue, this is set accordingly.
//The purpose of this bot is just to take in 2 values...one string, one number, and use those values to return as
//a dictionary in A2019.
public DictionaryValue action(
//Idx 1 would be displayed first, with a text box for entering the value. Because we want to take in
//a String, this should be set as TEXT
@Idx(index = "1", type = TEXT)
@Pkg(label = "String to return in Dictionary")
//Ensure that a validation error is thrown when the value is null.
//Idx 2 would be displayed second, with a text box for a number only. Because we want to take in
//a Number (A2019 data format), this should be set as NUMBER
@Idx(index = "2", type = NUMBER)
@Pkg(label = "Number to return in Dictionary")
//Dictionary isn't standard a Java datatype, so we'll create a Map.
//Within AA, a dictionary is going to be of type <String, Value> - where Value is an AA botcommand.datatype
//So we'll use Value in the map definition, then fill that with a String, Number, or Boolean
Map<String, Value> sampleMap = new HashMap<String, Value>();
//Because Value is a botcommand.datatype, we need to only put other botcommand datatypes in it.
//So we need to convert from standard Java types to botcommand datatypes
StringValue botcommandString = new StringValue(providedString);
//Same thing for storing the number in the map
NumberValue botcommandNumber = new NumberValue(providedNumber);
//Because we need to return this as a Dictionary Value, we'll create a new dictionary
//value and provide our Java Map.
return new DictionaryValue(sampleMap);
Once the fields are defined, a Map variable is established with <String, Value> - where String is the key, and Value (com.automationanywhere.botcommand.data) is the value type. Because Enterprise A2019 doesn't use the same Object Types as Java, we use Value here, then use the automationanywhere.botcommand variable types when putting data into a dictionary. This process starts by converting the provided String into a StringValue (com.automationanywhere.botcommand.data.impl) followed by a put command to add the key/value pair to the map with the key of "FirstValue". The same process is done for the number value - which is taken in as a Double (as defined in the fields definition), converted to a NumberValue (com.automationanywhere.botcommand.data.impl), then added to the Map with the key "SecondValue". Finally, because we need to return a DictionaryValue, a new DictionaryValue is defined and the Map variable (sampleMap) is provided.
Building the Project (Optional)
If you want to actually compile the package for testing in your Control Room, click to open the Gradle tab on the far right side of your screen (if it's not showing up, navigate to Window > Restore Default Layout). Once there, click the Execute Gradle Task button (the elephant).
From there, the Run Anything window appears and enables you to build the project by typing clean build shadowJar. Once executed, the project will build in the Run interface at the bottom of the screen and the package jar file will be generated in the /build/libs directory of your project.
Alternatively, you could navigate to the project root directory using Bash Shell/PowerShell and execute the following command:
.gradlew.bat clean build shadowJar
Packages enable endless possibilities for reusable components - to accelerate your own bot builds as well to empower other developers in your organization to build using custom packages as well. Now that you understand how to return a Dictionary value to users and compile the package - the sky is the limit in the creativity that you can inject into your bot builds. Go build awesome bots (and packages)! Go be Great! For more on package development, see the full tutorial on How to Build a Twilio Package using the Enterprise A2019 Package SDK.