Workflow Automation

The Workflow Designer places “Automated Tasks” instead of ‘User Tasks’ in order to realize Workflow Automation (automated processing on the server side).

Can’t find the automation you want to achieve? In such a case, consider implementing “Script Task” or your own “Service Task (Add-on)”.

Workflow-Automation-with-Low-Code

No Coding required – Automated Tasks

  • Service Task standard built-ins
    • Data Assignment <M227> / Converter (Date to Japanese calendar text) / Converter (Text File to String type) / etc.
    • PDF generation <M228> / Generator (Text File) / Converter (Table type data to Excel-CSV File) / etc.
    • Google Drive: File Upload <M229> / Google Drive: Create Folder / Google Calendar: Insert Event / Google Sheets: Append New Row / Microsoft 365 OneDrive for Business: Upload File / Microsoft 365 OneDrive for Business: Create Folder / Box: Upload File / Box: Create Folder / Box: Create Shared Link to Folder / kintone: Get Record / kintone: Upload File / kintone: Download Choice Data / Slack: Post Chat (Bots) / Slack: Upload File (Bots) / etc.
  • Service Task add-ons <M415>, available for free <List>
    • Converter: Table to TSV-String / TSV String, Sort by Text / Two Tsv Strings, Extract Cell-Matched Lines / UrlEncoded String, Decode UriComponent / etc.
    • Google Drive: File, Convert / Google Drive: GFile, Export as PDF / Google Docs: Document, Replace All / Google Sheets: ValueRanges, Export as TSV / Google Slides: Page, Duplicate / Google Groups: Members, List / Google Groups: Members, Insert / Google Translate: Translation API Basic, Translate / PayPal: Invoice, Create Draft / PayPal: Invoice, Send / PayPal: Invoice, Check Detail / Stripe: Customer Object, Create / Stripe: Charge Object, Create / Stripe: Charge Object, Create with Transfer Amount / etc.

Low Coding required – Automated Tasks

M230: Auto Executing Complicated Data Processing (ECMAScript)
M416: Create your own Auto-Step for Business Process Definitions
Hello World for ScriptTask (click to open)
//// == Data Retrieving / ワークフローデータの参照 ==
const strInput  = engine.findDataByVarName( "q_StringInput" );

//// == Calculating / 演算 ==
let   strOutput = strInput.toUpperCase(); //ECMAScript (ECMA-262)

//// == Data Updating / ワークフローデータへの代入 ==
engine.setDataByVarName( "q_StringOutput", strOutput );
Hello World for ServiceTaskAddon (click to open)
<?xml version="1.0" encoding="UTF-8"?><service-task-definition>
<label>Hello World</label>
<configs>
  <config name="SelectConfA" form-type="SELECT" select-data-type="STRING">
    <label>A: Select STRING DATA which contains input string</label>
  </config>
  <config name="SelectConfB" form-type="SELECT" select-data-type="STRING">
    <label>B: Select STRING DATA that output string will be stored (update)</label>
  </config>
</configs>
<engine-type>2</engine-type>
<script><![CDATA[// GraalJS Script (engine type: 2)
main();
function main(){ 
  //// == Config Retrieving / 工程コンフィグの参照 ==
  const strPocketInput  = configs.getObject( "SelectConfA" );
  const strPocketOutput = configs.getObject( "SelectConfB" );
  //// == Data Retrieving / ワークフローデータの参照 ==
  const strInput  = engine.findData( strPocketInput );
  //// == Calculating / 演算 ==
  let   strOutput = strInput.toUpperCase(); //ECMAScript (ECMA-262)
  //// == Data Updating / ワークフローデータへの代入 ==
  engine.setData( strPocketOutput, strOutput );
}
]]></script>
</service-task-definition>

In either case, you need to specify the JavaScript engine: Rhino, Nashorn, GraalJS. GraalJS (GraalVM JavaScript) is compliant with the latest ECMAScript specification (ECMAScript 2019, ECMAScript 2020). Both are basically implemented in JavaScript / ECMAScript. However, when you refer to or update business data, or when you use the Java class library, you need to be aware of the conversion between JavaScript Object and Java Object.

  • JavaScript: string, number, bigint, boolean, undefined, symbol, null
  • Java: byte, short, int, long, float, double, boolean, char, null

Frequently-used methods

  1. Methods to refer/update the workflow platform
    • void engine.log( strLogMessage )
    • String engine.getTimeZoneId()
    • int engine.getTimeZoneOffsetInMinutes()
  2. Methods to refer the definition of the Workflow App
    • long processInstance.getProcessModelInfoId()
    • long processInstance.getProcessModelVersion()
    • qPocket engine.findDataDefinitionByVarName( strFieldName ) // qPocket ⇔ com.questetra.bpms.core.event.scripttask.ProcessDataDefinitionView
    • boolean qPocket.matchDataType( strDataType )
      • strDataType: STRING (STRING_TEXTFIELD, STRING_TEXTAREA), DECIMAL, SELECT, DATE, DATETIME, FILE, QUSER, QGROUP, LIST
    • List<qSubPocket> qPocket.getSubDataDefinitions()
    • boolean qSubPocket.matchDataType( strSubDataType ) // qSubPocket ⇔ com.questetra.bpms.core.event.scripttask.SubDataDefinitionView
      • strSubDataType: STRING, DECIMAL, SELECT, DATE
  3. Methods to refer the Addon configs of the Workflow App (only in ServiceTask Addon), #addon_examples
    • String configs.get( strConfigName )
    • qPocket configs.getObject( strConfigName )
  4. Methods to refer/update the properties of the process instance flowing in the Workflow App
    • String processInstance.getProcessInstanceTitle()
    • long processInstance.getProcessInstanceId()
    • long processInstance.getProcessInstanceSequenceNumber()
    • qObjDatetime processInstance.getProcessInstanceStartDatetime()
    • qObjQuser processInstance.getProcessInstanceInitQuser()
    • String processInstance.getProcessInstanceInitQuserName()
    • long processInstance.getProcessInstanceInitQuserId()
    • qObjQgroup processInstance.getProcessInstanceInitQgroup()
    • String processInstance.getProcessInstanceInitQgroupName()
    • long processInstance.getProcessInstanceInitQgroupId()
    • void processInstance.setProcessInstanceTitle( strNewProcessTitle )
  5. Methods to refer/update the business data stored in the process instance flowing in the Workflow App
    • qObj engine.findData( qPocket )
    • qObj engine.findDataByVarName( strFieldName )
    • qObj engine.findDataByNumber( strDataDefNum )
    • void engine.setData( qPocket, qObj )
      • void engine.setData( qPocket, strValue )
      • void engine.setData( qPocket, new java.math.BigDecimal( numValue ) )
      • void engine.setData( qPocket, List<strId> )
      • void engine.setData( qPocket, new java.sql.Date( numMillisecValue ) )
      • void engine.setData( qPocket, new java.sql.Timestamp( numMillisecValue ) )
      • void engine.setData( qPocket, qObjFile )
      • void engine.setData( qPocket, qObjQuser )
      • void engine.setData( qPocket, qObjQgroup )
      • void engine.setData( qPocket, qObjTable )
    • void engine.setDataByVarName( strFieldName, qObj )
      • void engine.setDataByVarName( strFieldName, strValue )
      • void engine.setDataByVarName( strFieldName, new java.math.BigDecimal( numValue ) )
      • void engine.setDataByVarName( strFieldName, List<strId> )
      • void engine.setDataByVarName( strFieldName, new java.sql.Date( numMillisecValue ) )
      • void engine.setDataByVarName( strFieldName, new java.sql.Timestamp( numMillisecValue ) )
      • void engine.setDataByVarName( strFieldName, qObjFile )
      • void engine.setDataByVarName( strFieldName, qObjQuser )
      • void engine.setDataByVarName( strFieldName, qObjQgroup )
      • void engine.setDataByVarName( strFieldName, qObjTable )
  6. Methods for manipulating Select-type data (SELECT, SELECT_SINGLE, SELECT_CHECKBOX)
    • String qObjSelect.get(i).getValue() // qObjSelect ⇔ List<com.questetra.bpms.core.event.scripttask.ItemView>
    • String qObjSelect.get(i).getDisplay()
    • List<ItemView> itemDao.findAll( strOptionsXmlName, boolIsSharedFile)
    • ItemView itemDao.findByValue( strOptionsXmlName, boolIsSharedFile, strId )
  7. Methods for manipulating Date-type data (DATE, DATE_YMD, DATE_YM, DATE_Y, DATE_MD)
    • String qObjDate.toString() // “yyyy-MM-dd”
    • qObjDate qObjDate.addDays( intDays ) // qObjDate ⇔ com.questetra.bpms.util.AddableDate
    • qObjDate qObjDate.addMonths( intMonths )
    • qObjDate qObjDate.getFirstDateInMonth()
    • qObjDate qObjDate.getLastDateInMonth()
  8. Methods for manipulating Datetime-type data (DATETIME)
    • String qObjDatetime.toString() // “yyyy-MM-dd HH:mm”
    • qObjDatetime qObjDatetime.addHours( intHours ) // qObjDatetime ⇔ com.questetra.bpms.util.AddableTimestamp
    • qObjDatetime qObjDatetime.addDays( intDays )
    • qObjDatetime qObjDatetime.addMonths( intMonths )
    • qObjDatetime qObjDatetime.getFirstTimeInDate()
    • qObjDatetime qObjDatetime.getFirstTimeInMonth()
    • qObjDatetime qObjDatetime.getLastTimeInMonth()
  9. Methods for manipulating User-type data (QUSER)
    • long qObjQuser.getId() // qObjQuser ⇔ com.questetra.bpms.core.event.scripttask.QuserView
    • String qObjQuser.getName()
    • String qObjQuser.getEmail()
    • qObjQuser quserDao.findByEmail( strQuserEmail )
    • qObjQuser quserDao.findById( numQuserId )
    • List<qObjQuser> quserDao.findByQgroup( qObjQgroup )
    • List<qObjQuser> quserDao.findByQrole( qObjQrole ) // qObjQrole ⇔ com.questetra.bpms.core.event.scripttask.QroleView
  10. Methods for manipulating Group-type data (QGRUOP)
    • qObjQgroup ⇔ com.questetra.bpms.core.event.scripttask.QgroupView
    • long qObjQgroup.getId()
    • String qObjQgroup.getName()
    • qObjQgroup qgroupDao.findById( numQgroupId )
    • List<qObjQgroup> qgroupDao.findByQuser( aObjQuser )
  11. Methods for manipulating Table-type data (LIST)
    • String qObjTable.get( intRowIndex, intColIndex ) // qObjTable ⇔ com.questetra.bpms.core.event.scripttask.ScriptListArray
    • String qObjTable.toXmlString()
    • int qObjTable.size()
  12. Methods for manipulating File-type data (FILE), #fileRepository_examples
    • QfileView qObjFile.get(i) // qObjFile ⇔ List<com.questetra.bpms.core.event.scripttask.QfileView>
    • String qObjFile.get(i).getName()
    • long qObjFile.get(i).getLength()
    • String qObjFile.get(i).getContentType()
    • void readFile( QfileView, “UTF-8”, function(line){} )
    • void qFileObj.add( NewQfile ) // if(qFileObj===null) qFileObj = new java.util.ArrayList()
    • NewQfile NewQfile( strFileName, “application/xml”, strXmlText ) // NewQfile ⇔ com.questetra.bpms.core.event.scripttask.NewQfile
    • NewQfile NewQfile( strFileName, strContentType, binaryData )
  13. Methods for manipulating XML, #xpath_examples
    • nodeObj xpath.findNode( strXml, strXpathText) // nodeObj ⇔ com.questetra.bpms.core.event.scripttask.XPathWrapper.NodeWrapper
    • nodeListObj xpath.findNodeList( nodeObj, strXpathText ) // nodeListObj ⇔ com.questetra.bpms.core.event.scripttask.XPathWrapper.NodeListWrapper
    • nodeListObj xpath.findNodeList( strXml, strXpathText )
    • String xpath.findNodeText( nodeObj, strXpathText )
    • String xpath.findNodeText( strXml, strXpathText)
    • String nodeObj.getNodeName()
    • String nodeObj.getNodeValue()
    • Short nodeObj.getNodeType()
    • boolean nodeObj.hasChildNodes()
    • boolean nodeObj.hasAttributes()
    • long nodeListObj.getLength()
    • nodeObj nodeListObj.item( intIndex )
  14. Methods for controlling “OpenChat” Post, #feedService_examples
    • qOpenChat feedService.begin() // qOpenChat ⇔ com.questetra.bpms.core.event.scripttask.FeedServiceWrapper.FeedMessageWrapper
    • qOpenChat qOpenChat.setMessage( strMessage )
    • qOpenChat qOpenChat.setShareQgroup( qObjQgroup )
    • qOpenChat qOpenChat.attachFile( QfileView )
    • qOpenChat qOpenChat.attachLink( strUrl )
    • long qOpenChat.post()
  15. Methods for controlling HTTP Communication, #authSetting_examples
    • request1 httpClient.begin() // request1 ⇔ com.questetra.bpms.core.event.scripttask.HttpClientWrapper
    • request1 request1.authSetting( strAuthSettingName )
    • request1 request1.formParam( strKey, strValue )
    • request1 request1.queryParam( strKey, strValue )
    • response1 request1.get( strUrl ) // response1 ⇔ com.questetra.bpms.core.event.scripttask.HttpClientWrapper.HttpResponseWrapper
    • response1 request1.post( strUrl )
    • int response1.getStatusCode()
    • binary response1.getResponse()
    • String response1.getResponseAsString()
    • String response1.getContentType()
  16. Methods for controlling Email Communication
    • emailMessage emailService.begin() // emailMessage ⇔ com.questetra.bpms.core.event.scripttask.EmailServiceWrapper.EmailMessageWrapper
    • emailMessage emailMessage.addTo( strEmailAddress, strFullName )
    • emailMessage emailMessage.addCc( strEmailAddress, strFullName )
    • emailMessage emailMessage.addBcc( strEmailAddress, strFullName )
    • emailMessage emailMessage.setFrom( strEmailAddress, strFullName )
    • emailMessage emailMessage.setReplyTo( strEmailAddress, strFullName )
    • emailMessage emailMessage.setSubject( strEmailSubject )
    • emailMessage emailMessage.setTextBody( strEmailTextBody )
    • emailMessage emailMessage.setHtmlBody( strEmailHtmlBody )
    • emailMessage emailMessage.addAttachment( QfileView )

ECMAScript 2020 / java.lang.String / java.lang.Long / java.lang.Math / java.util.ArrayList / java.util.Date / java.util.HashMap / java.util.Locale / java.util.regex.Pattern / java.util.regex.Matcher / java.math.BigDecimal / java.text.SimpleDateFormat / java.text.DecimalFormat / java.sql.Date / java.sql.Timestamp

Official Reference

  • R2300: Java Classes available in Script Task
  • R2301: Script Data Retrieving / Updating
  • R4160: Settings Values for each Add-on XML Config Attribute

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: