Custom Action Designer
The ThinkAutomation Professional Edition includes a Custom Action Designer. This allows you to create your own Custom Action types. The Custom Action Designer includes a UI builder for configuring the Action settings and a C# or Visual Basic .NET code editor for editing the execution code. Once a Custom Action has been created it appears in the available actions toolbox and can be used like any other action on any of your Automations.
Select the Custom Actions tab on the ThinkAutomation Studio Ribbon.
Click Add Action to add a new custom action.
Each action must have a unique Class Name. This must be less than 100 characters and must not contain spaces or special characters. The Class Description is the text that will show in the Actions toolbox. The Group Name is the section the action should appear in the Actions toolbox. You can select an existing group or create a new one. The Default Height/Width define the size of the Action property page.
Settings Input Fields
You can create any number of settings. These are the Action Settings that appear when the Action is added to an Automation. Your custom action execution code can access these setting values at runtime.
Click Add to add a setting.
Each setting must have a unique Setting Name (unique within the custom action). You will use this name when accessing setting values inside your custom action code.
Input Field Types
You must then select the Field Type:
Type | Details |
---|---|
TextBox | A regular textbox for text settings. |
Numeric Integer | A textbox that only allows integer values. |
Numeric Decimal | A textbox that only allows decimal values. |
Date | A date picker (setting value will be a string in 'yyyy-MM-dd HHss' format). |
CheckBox | A boolean checkbox (setting value will be 'true' or 'false'). |
ComboBox | A combo box with a list of possible values. |
ListBox | A List box with a list of possible values. |
TreeView | A tree view with a list of possible values organized with parent/child hierarchy. |
Assign To Field Picker | A combo box already populated with all other variables in the Automation. |
File Picker | A textbox with a button to select a local file. |
Folder Picker | A textbox with a button to select a local folder. |
Grid | A simple grid for editing rows & columns of data. |
Plain Text Editor | An editor for editing plain text. |
Html Editor | An editor for editing HTML. |
SQL Editor | An editor for editing SQL. |
Json Editor | An editor for editing Json text. |
Label | Display a text label - no data input. |
Button | A simple button. Allows you to execute code on button click via Settings Form Code. |
OAuth Sign-In Button | A button to sign in to a web resource that supports OAuth 2.0. |
Microsoft Graph Sign-In Button | A button to sign in to Office 365/Microsoft Graph. |
Google Sign-In Button | A button to sign in to Google API's. |
Xero Sign-In Button | A button to sign in to Xero Accounts. |
Hidden | A hidden setting. Allows you to store values against the custom action via Settings Form Code. The values will be stored with the Automation. |
Setting Input Fields have additional properties depending on the field type, such as Default Value, Is Required, Is Password, Max Length, Numeric Range.
You can add multiple setting fields depending on the type of settings you need to store with your custom action when it is used on Automations.
You can change the order that settings appear on the settings form using the Up/Down buttons.
After you have created your input fields, click Preview to see how the custom action properties form will appear when it is used on an Automation.
An 'Assign Return Value To' Assign To Field picker setting is added automatically.
ComboBox Or ListBox
For ComboBox or ListBox setting types you define a list of Items containing Display Names and optional Values. The user can then select one of the items. If the ComboBox Is Editable is enabled then the user can also type any value. If Values are specified then the Value will be assigned to the setting value rather than the Display Name. If the Value is blank then the Display Name will be assigned to the setting value.
TreeView
For TreeView setting type you define a list of Items containing Display Names, Values and Parent Values. The display names are then arranged in a tree based on the Parent Values. The setting value will be assigned to the selected node's Value.
Grid Editor
For Grid field types you define the columns in your grid. For each column you set the allowed type (String, Integer, Decimal, Date, Time, Boolean or Memo). You can also mark a column as a Field Combo. Columns marked as field combo will automatically show a drop down list of all ThinkAutomation variables when data is entered in that column.
For each string type column you can optionally also assign a list of Choices. Each choice should be separated by a | character. If Choices are specified then the column will show a drop down list. If the Choices entry starts with a | character then the grid column value can only be selected from the choices list - a different value cannot be typed. For Example: If the Choices is set to 'Red|Green|Blue' then the user can select from the list but also type in another value. If Choices is set to '|Red|Green|Blue' then the user can only select one of Red, Green or Blue. If the Choices value is set to '%variables%' then the choices will be automatically populated with all variable names used on the Automation.
OAuth Sign In Button
This Input Field type can be used if your custom action code needs to access a web API that requires an OAuth 2.0 Authorization token. You must set the additional properties of Authorization Endpoint, Token Endpoint, Client ID, Client Secret & optional Scope, depending on the OAuth service you want to sign in to.
When the Action is used on an Automation and the ThinkAutomation Studio user clicks the Sign-In button, a web browser window will start the sign-in process and return an Authorization token. The Authorization token is assigned to the input field value. Which can then be used inside your action execution code. ThinkAutomation will refresh expired tokens automatically before your custom action executes (if your sign-in provides a refresh token).
Inside your action execution code when making HTTP requests to a web API you must add the 'Authorization' header and set the value to the setting value. For Example:
string Authorization = settings.value("MySignInSettingName");
WebClient Client = New WebClient();
Client.Headers.Add("Authorization",Authorization)
You can also use the httpHelper class which simplifies http calls. See: Using The Http Helper Class
Microsoft Graph Sign In Button
This Input Field type can be used if your custom action code needs to access the Microsoft Graph API. You must set the Scope depending on the resources you need to access. The User.Read & offline_access scopes are added automatically. The sign in uses the ThinkAutomation app clientid.
When the Action is used on an Automation and the ThinkAutomation Studio user clicks the Sign-In button, a web browser window will start the sign-in process and return an Authorization token. The Authorization token is assigned to the input field value. Which can then be used inside your action execution code. ThinkAutomation will refresh expired tokens automatically before your custom action executes.
Inside your action execution code when making HTTP requests to Microsoft Graph you must add the 'Authorization' header and set the value to the setting value.
You can also use the httpHelper class which simplifies http calls. See: Using The Http Helper Class
Google Sign In Button
This Input Field type can be used if your custom action code needs to access the Google API. You must set the Scope depending on the resources you need to access. The sign in uses the ThinkAutomation app clientid. The Authorization token is assigned to the input field value.
Xero Sign In Button
This Input Field type can be used if your custom action code needs to access the Xero Accounts API. You must set the Scope depending on the resources you need to access. The accounting.contacts & offline_access scopes are added automatically. The sign in uses the ThinkAutomation app clientid. See: https://developer.xero.com for more information.
The input field value is assigned the Authorization token and the selected Xero Tenant ID in the following format:
Inside your action execution code when making HTTP requests to the Xero API you must add the 'Authorization' and 'Xero-Tenant-Id' HTTP headers.
If you use the httpHelper class to make calls to the Xero API, then both headers are added automatically. For example:
```visual basic Dim Http As New helpersHttp ' the Authorization & xero-tenent-id headers are set automatically http.AuthorizationToken = settings.value("XeroSignInButton") http.URL = "https://api.xero.com/api.xro/2.0/Contacts/" & _ settings.value("ContactID") & "/History" Return http.SendRequest
### Setting Label
The **Label** is the text that should appear next to the setting. The **Label Position** can be set to the *Left* or *Top* of the setting input. The **Label Group Name** is optional and allows you to group settings on the settings form. All settings with the same *Group Name* will appear together in a bordered group.
## Execution Code
The Execution Code pane is used to create the C# or Visual Basic .NET code that will execute when the custom action is executed for an Automation by the Message Processor. You should decide on the language (C# or Visual Basic .NET) before you start coding, since changing it will reset the code. Each separate custom action can use either language.
When ThinkAutomation executes the custom action it calls the *execute* method. This is the entry point to your execution code. You should not change the execute method name or parameters. Inside your code you can add any number of additional methods. The execute method returns a string value. The returned value will be assigned to the **Assign Return Value To** variable.
Custom action code is compiled by ThinkAutomation when it is executed for the first time. Therefore, once custom actions have executed once they will operate as fast as built-in actions.
### Accessing Message Properties, Attachments & Automation Variables
You can access the current message being processed, access or update existing Automation variables and add to the Automation log in the same way as the [Execute Script](Automation Action Types.md#execute-script) action.
### Accessing Settings Values Inside Your Code
Inside your code you can access the Settings Input Field values using:
```c#
string SomeSetting = settings.value("settingname");
Where settingname is the Setting Name. You can also simply drag a setting onto the code editor to create.
All setting values are strings. So for a Numeric Integer setting it would still be returned as a string. A CheckBox value will either be 'true' or 'false'.
All settings values will have already been 'replaced'. This means that if the user had used any %variable% replacement(s) within the setting value - each will have been replaced with actual values before your code executes.
Accessing Grid Input Type Data
Setting Input Fields that are defined as Grid input types are accessed by row/column values. You can access the number of rows and the value at each row/column. For example:
The settings.tableDataRows("settingname")
returns the number of rows entered in the grid setting called 'settingname'. Eg:
The settings.tableDataRowColumnValue("settingname" , row, col)
returns the grid value for a specific row & column (row & column are zero based). Eg:
.NET References
Scripts can reference other .NET Framework assemblies compatible with .NET Framework 4.7 or higher. Use the References tab to add additional references. You can add any of the .NET framework System assemblies. Any other .NET referenced assembly must be located in the ThinkAutomation program files folder (unless you use a NuGet package - see below).
NuGet Packages
You can also add NuGet packages to scripts. Click the NuGet Packages button to open the NuGet Package Manager. Enter a search term and click the search button to view available packages. Select a package and click the Add Reference button to download & install the package. A reference to the package (and any dependencies) will be added to your script. See: https://www.nuget.org for more information.
Validating Custom Action Code
Click the Check button to validate that the code compiles and executes successfully.
Adding To The Output Window
To assist with script development you can add data to the Output window using message.DebugPrint
:
Any calls to message.DebugPrint will show in the Output window in the script editor when the Check button is used, and are ignored when the script executes during Automation execution.
Using Visual Studio To Develop Custom Action Code
You can use Microsoft Visual Studio to develop & debug your custom action code. When development is complete you can then copy/paste the code into the Custom Action code editor.
Start a new Visual Studio console application protect. Set it use use .NET Framework 4.7 or 4.8.
Add a Reference to ThinkAutomationCoreClasses.dll (located in the \Program Files\ThinkAutomation.NET\ folder) and any other references your script code will use.
Example (Visual Basic):
Imports ThinkAutomationCoreClasses.ThinkAutomation
Imports ThinkAutomationCoreClasses.Scripting
Module Module1
Sub Main()
' create some test settings
Dim TestSettings As New actionSettings
TestSettings.Add("firstname", "John")
TestSettings.Add("lastname", "Smith")
' create a blank incoming message
Dim Solution As New clsSolution
Dim MessageSource As New clsMessageSource
Dim Automation As New clsAutomation
MessageSource.SetSolution(Solution)
Automation.SetSolution(Solution)
Dim IncomingMessage As New clsMessage(MessageSource, Automation)
' If you want to create a message with a body/subject etc use 'Mime' property
' IncomingMessage.Mime = [full mime text]
Dim Message As New currentMessage(IncomingMessage)
Dim MyAction As New ThinkAutomationScript
Console.WriteLine(MyAction.execute(TestSettings, Message))
Console.ReadLine()
End Sub
End Module
Public Class ThinkAutomationScript
Public Function execute(ByVal settings As actionSettings, message As currentMessage) As String
Try
' Action execution code
' Get custom action settings using settings.value("settingname")
' Get extracted fields/variable values using message.GetValue("name")
' Set extracted fields/variable values using message.SetValue("name","value")
Dim FullName As String = settings.value("firstname") & " " & settings.value("lastname")
Return FullName
Catch e As Exception
' Pass the error back to the automation log
message.AddErrorToLog(e.Message)
Return ""
End Try
End Function
End Class
First we need to create some settings to pass to the execute method. The setting names should match your Setting Input Fields. You then need to create a blank message to pass to the execute method.
You can the run & debug the execute method.
When you have completed development select the Public Class ThinkAutomationScript
code and paste it into the Custom Action code editor (replacing the existing ThinkAutomationScript code block).
Using The Http Helper Class
When making http requests inside your execution code you can make use of the built-in helpersHttp class. This helper class simplifies making http GET, POST, PUT & DELETE requests. It also honors any proxy settings defined in your ThinkAutomation Server Settings.
Simple Get Request:
Dim Http As New helpersHttp
' set the Url
http.URL = "https://graph.microsoft.com/v1.0/users/" & settings.value("Email")
' set the OAuth token if required.
http.AuthorizationToken = settings.value("SignIn")
' send the request
Dim Json As String = Http.SendRequest
If Json.Length = 0 Then
' if nothing returned then check the http status
message.AddErrorToLog(http.LastStatus.ToString & " " & http.LastError)
End If
Post Request
Dim Http As New helpersHttp
' set the Url
http.URL = "https://graph.microsoft.com/v1.0/me/messages/abcd1234/move"
' set the Verb to GET (default), POST, DELETE or PUT
http.Verb = "POST"
' add any additional headers using AddHeader
http.Addheader("header","somevalue")
' add any additional querystring parameters if required
http.AddQueryStringParameter("param",settings.value("settingname"))
' set the OAuth token if required.
http.AuthorizationToken = settings.value("SignIn")
' set the content-type
http.ContentType = "application/json"
' set the post body
http.PostBody = "{""desinationid"": ""defgh67890""}"
' send the request
Dim Json As String = Http.SendRequest
If Json.Length = 0 Then
' if nothing returned then check the http status
message.AddErrorToLog(http.LastStatus.ToString & " " & http.LastError)
End If
Settings Form Code
The Settings Form Code pane is used to create C# or Visual Basic .NET code that will be executed by the ThinkAutomation Studio when your custom action is used on an Automation. Changing this code is optional and is only required if you need to fine-tune the settings form functionality within the Studio. The Settings Form Code does not affect Automation execution.
The default code contains 3 methods - Loaded, EditValueChanged & Saved. You can add code inside these methods (do not change the method names or parameters). You can add additional methods of your own that can be called from these methods, and you can add additional .NET References, or NuGet packages if required.
Loaded
Loaded is called when the settings form initially loads. You can set default values for settings and show/hide or enable/disable individual settings.
To set a default value for a setting, use:
```visual basic settings.SetDefaultValue("settingname","initial value")
Where *settingname* is the name of one of your Settings Input Fields. All values are set as strings. For CheckBox type inputs you should set to *'true'* or '*false*. For Date inputs the date should be in *yyyy-MM-dd HH:mm:ss* format.
For Date inputs you can set the initial value to *'today'*, *'yesterday'* or *'tomorrow'* to have it default to todays date (or yesterday, tomorrow).
To hide a setting or mark as disabled, use:
```visual basic
settings.Hide("settingname") ' hides a setting
settings.Disable("settingname") ' disables a setting
settings.UnHide("settingname") ' show a previously hidden setting
settings.Enable("settingname") ' enable a previosly disabled setting
Grid settings can include columns that contain drop down selectors. You can set the default values contained in the drop down selector. To set the default values for any Choices column drop down lists use:
Dim values As New List(Of String)
values.Add("Value1")
values.Add("Value2")
Dim editable As Boolean = True
settings.SetDefaultGridColumnChoices("gridsettingname","columnname",editable,values)
Where settingname is the name of one of your Grid type setting, columnname is the name of the column in the grid. The editable parameter is a Boolean. Set to True if the user can also type another value (and not be restricted to the list of choices). The values parameter is a List(Of String) - containing a list of possible values for that column.
EditValueChanged
EditValueChanged is called when a setting value is changed by the user. You can use this to set values for other settings or to show/hide, enable/disable other settings. The changed setting name is passed in the SettingName parameter.
You can access the current value for any setting input field using settings.GetValue("settingname")
.
For Example:
```visual basic Public Sub EditValueChanged(ByVal settings As customActionDesignerSettings, ByVal SettingName As String) If SettingName = "PostToURL" Then Dim CurrentValue As String = settings.GetValue("PostToURL") If CurrentValue = "true" Then settings.UnHide("URL") Else settings.Hide("URL") End If End If End Sub
You can set a setting value using `settings.SetValue("settingname","value")`.
**Button Input Type**
For the Button input type the EditValueChanged will be called when the button is clicked. The button setting name will be passed in the *SettingName* parameter. You can use this to execute custom code on button clicks.
**Setting ComboBox & ListBox Setting Values**
ComboBox and ListBox input types are set as a list of *Display Name/Value* pairs. You can either set the currently selected item or replace all ComboBox/ListBox items.
To set the currently selected item in a ComboBox/ListBox setting, simply set its value, for example:
```visual basic
settings.SetValue("ListBoxSetting","value2")
Will set the ListBox with setting name 'ListBoxSetting' to the item with value 'value2'.
To replace all items in a ComboxBox or ListBox use:
```visual basic
Dim ListItems As New List(Of String) ' create a List(Of String)
ListItems.Add("List item 1|value1") ' Add items. Separate Display Name & Value with |
ListItems.Add("List item 2|value2")
ListItems.Add("List item 3|value3")
' Use SetValue and pass settings.KeyValuePairs(List)
settings.SetValue("ListBoxSetting",settings.KeyValuePairs(ListItems))
' You can also set the currently selected item when building a ComboBox/ListBox
settings.SetValue("ListBoxSetting",settings.KeyValuePairs(ListItems,"value2"))
When using ComboBox/ListBox input types, the `settings.GetValue("settingname")` will return the currently selected *value*.
To get the currently selected *DisplayName* use `settings.GetDisplayName("settingname")`.
**Setting Grid Choices Column Values**
Grid settings can include columns that contain drop down selectors. You can set the values contained in the drop down selector using:
```visual basic
Dim Choices As New List(Of String) ' create a List(Of String)
Choices.Add("Choice 1") ' populate the list with available choices
Choices.Add("Choice 2")
Choices.Add("Choice 3")
' Use SetValue and pass settings.GridColumnValues('ColumnName',IsEditable,ChoicesList)
settings.SetValue("GridSettingName",settings.GridColumnValues("Choices Col",False,Choices))
Getting Grid Row & Column Values
You can access the current row/column value for a grid setting using: settings.GetGridRowColumnValue("settingname", Row, Column)
Row & Column are zero based. To get the number of rows use: settings.GetGridRows("settingname")
OAuth SignIn Buttons
The EditValueChanged method will be called when the OAuth or Microsoft Graph/Google sign in has completed. The value of the setting will contain the Authorization token. You can then use the helpersHttp class to retrieve data and populate other settings. For example:
```visual basic Imports System Imports System.Text Imports System.Collections.Generic Imports ThinkAutomationCoreClasses.Scripting Imports Newtonsoft.Json
Public Class ThinkAutomationCustomAction
Public Sub EditValueChanged(ByVal settings As customActionDesignerSettings, ByVal SettingName As String)
Try
Select Case SettingName
Case "SignInButton"
' populate ListBoxUsers
' the SignIn value will contain the OAuth token if we have signed in.
Dim Token As String = settings.GetValue("SignInButton")
If Token.Length > 0 Then
Dim SelectedId As String = settings.GetValue("ListBoxUsers")
Dim Items As New List(Of String)
Dim http As New helpersHttp
Dim Url As String = "https://graph.microsoft.com/v1.0/users?$select=displayName,id,userPrincipalName"
http.AuthorizationToken = Token
Do
http.URL = Url
Dim Json As String = http.SendRequest
If http.LastStatusSuccess Then
Dim ThisUsersList As Users = JsonConvert.DeserializeObject(Of Users)(Json)
Dim ThisUser As User
For Each ThisUser In ThisUsersList.Value
Items.Add($"{ThisUser.displayName} ({ThisUser.userPrincipalName})|{ThisUser.id}")
Next
Url = ThisUsersList.NextLink
Else
settings.MessageBoxError = http.LastError
Url = ""
End If
Loop Until String.IsNullOrEmpty(Url)
settings.SetValue("ListBoxUsers",settings.KeyValuePairs(Items,SelectedId))
settings.SetValue("LabelUserCount",Items.Count.ToString & " Users")
End If
Case "ListBoxUsers"
settings.SetValue("LabelSelectedUserName",settings.GetDisplayName("Users"))
End Select
Catch e As Exception
settings.MessageBoxError = e.Message
End Try
End Sub
Private Class Users
<JsonProperty("@odata.nextLink")>
Public Property NextLink As String
Public Property Value As List(Of User)
End Class
Private Class User
Public Property id As String
Public Property displayName As String
Public Property userPrincipalName As String
End Class
End Class ```
Saved
Saved is called when the form is saved. You can use this to perform additional validation and to prevent the user saving the action.
By default the Saved method returns a blank string. If you want to prevent the settings form from being saved, return a string value. The returned string will be shown to the user in a message box. For example:
visual basic
If settings.GetValue("PostToURL") = "true" And settings.GetValue("URL") = "" Then
Return "You must specify the URL if the Post To URL is enabled."
Else
Return ""
End If
Help Text
Action Description Template
This setting is used to define the text that appears in the Automation Action List. By default it will show the Class Description. You can add additional text - and include setting names. The template is in the following format:
Where 'text' is any text. Any %settingname% enclosed in % will be replaced with the setting value. If you enclose text with {} you can set its color. Eg: {1:%name%} will show the value of the %name% setting in color 1. There are 3 colors and an 'assign to' color. You can show a setting in the 'assign to' color using {a:%assignto%}.
Help Details And Notes
These optional settings are stored with the Custom Action. The help text will show in the Action Properties page Help tab, when the custom action is used on an Automation. Help text can contain Markdown.
Publishing
Custom Actions will not appear in the Actions toolbox until marked as 'Published'. This enables you to work on a custom action before it is available to use on your Automations. To mark as published, click the Publish button and then click Save to save the custom action. The custom action will then show in the Actions toolbox when designing your Automations. You can drag it to the Actions list and use it like any other action.
ThinkAutomation checks that the custom action code compiles successfully before you can publish it.
Sharing You Custom Action
You can share your custom action with other ThinkAutomation users once it is marked as 'Published'. Click the Share button to enable sharing. The custom action will then be uploaded to the online library each time it is saved. Other ThinkAutomation users will then see it in the Online Actions Explorer and can add it to their own custom actions.
Your custom action will not be visible to other users until Parker Software has verified it.