ワークフロー自動化のためのローコード開発

Workflow Automation

「ワークフロー工程の自動化」(サーバサイドでの無人処理化)を実現したい場合、アプリ設計担当者は、”ヒューマン工程” ではなく “自動処理工程” を配置します。

実現したい自動化が見当たらない? そんな場合には[スクリプトタスク][サービスタスク(アドオン)]による実装(自動処理工程の実装)を検討します。

Low Code で Workflowオートメーション

◆コーディングが “不要” な自動処理工程(No-Code)

  • 標準で組み込まれているサービスタスク
    • データ設定 <M227> / コンバータ(テキストファイル to 文字型データ)/ コンバータ(Date to 和暦テキスト) / etc.
    • PDF生成 <M228> / ジェネレータ(テキストファイル) / コンバータ(テーブル型データ to Excel-CSV ファイル) / etc.
    • Google ドライブ: フォルダ作成 <M229> / Google カレンダー: 予定追加 / Google スプレッドシート: 行追加 / Microsoft 365 OneDrive for Business: ファイルアップロード / Microsoft 365 OneDrive for Business: フォルダ作成 / Box: ファイルアップロード / Box: フォルダ作成 / Box: フォルダ共有リンク作成 / kintone: レコード取得 / kintone: ファイルアップロード / kintone: 選択肢データの一括取得 / Slack: チャット投稿(Bots) / Slack: ファイルアップロード(Bots) / etc.
  • アドオンで利用可能になるサービスタスク <M415>, <公開リスト>
    • コンバータ: テーブル to TSV文字列 / TSV文字列, テキストソート / 2つのTSV文字列, セル一致行の抽出 / URL 文字列, パーツの抽出 / etc.
    • Google ドライブ: ファイル, コンバート / Google ドライブ: Gファイル, PDFエクスポート / Google ドキュメント: 文書, 全置換 / Google スプレッドシート: 範囲データ, TSVエクスポート / Google スライド: ページ, 複製 / Google グループ: メンバー, 一覧 / Google グループ: メンバー, 追加 / Google 翻訳: Translation API Basic, 翻訳 / PayPal: 請求書, ドラフト作成 / PayPal: 請求書, 送信 / PayPal: 請求書, 詳細確認 / Stripe: 顧客オブジェクト, 生成 / Stripe: 課金オブジェクト, 分配金を指定して生成 / etc.

◆コーディングを “要する” 自動処理工程(Low-Code)

M230: 業務データの複雑なデータ加工が自動実行されるように設定する
M416: 業務プロセス定義で利用可能な自動工程を自作する
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>

いずれの場合も、JavaScriptエンジン (Rhino, Nashorn, GraalJS) を指定して実装します。推奨エンジン GraalJS (GraalVM JavaScript) は、最新の ECMAScript 仕様(ECMAScript 2020)に準拠しています。基本的には JavaScript/ECMAScript で実装しますが、業務データを参照更新する部分(やJavaクラスライブラリを利用する部分)において JavaScript と Java のオブジェクト変換を意識する必要があります。

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

◇よく使うメソッド

  1. ワークフロー基盤を参照更新する関数
    • void engine.log( strLogMessage )
    • String engine.getTimeZoneId()
    • int engine.getTimeZoneOffsetInMinutes()
  2. ワークフローアプリの定義(業務プロセス定義)を参照する関数
    • 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. ワークフローアプリのアドオン設定を参照する関数(Addon専用), #addon_examples
    • String configs.get( strConfigName )
    • qPocket configs.getObject( strConfigName )
  4. ワークフローアプリに流れるプロセスプロパティを参照更新する関数
    • 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. ワークフローアプリに流れるプロセス格納されている業務データを参照更新する関数
    • 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. 選択型データを操作する関数(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. 日付型データを操作する関数(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. 日時型データを操作する関数(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. ユーザ型データを操作する関数(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. 組織型データを操作する関数(QGROUP)
    • qObjQgroup ⇔ com.questetra.bpms.core.event.scripttask.QgroupView
    • long qObjQgroup.getId()
    • String qObjQgroup.getName()
    • qObjQgroup qgroupDao.findById( numQgroupId )
    • List<qObjQgroup> qgroupDao.findByQuser( aObjQuser )
  11. テーブル型データを操作する関数(LIST)
    • String qObjTable.get( intRowIndex, intColIndex ) // qObjTable ⇔ com.questetra.bpms.core.event.scripttask.ScriptListArray
    • String qObjTable.toXmlString()
    • int qObjTable.size()
  12. ファイル型データを操作する関数(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 fileRepository.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. 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. “オープンチャット” への投稿を制御する関数, #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. HTTP通信を制御する関数, #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. SMTP(Email)通信を制御する関数
    • 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

◇オフィシャル Reference

  • R2300: スクリプトタスクで利用できる Java クラス
  • R2301: Scriptデータ取得/代入
  • R4160: Addon-XML config 設定値の各属性

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

上部へスクロール