// GraalJS Script (engine type: 2)
//////// START "main()" /////////////////////////////////////////////////////////////////
main();
function main(){
//// == Config Retrieving / 工程コンフィグの参照 ==
const strAuthzSetting = configs.get ( "AuthzConfU" ); /// REQUIRED ///////////
engine.log( " AutomatedTask Config: Authz Setting: " + strAuthzSetting );
const strPlatformUrl = configs.get ( "StrConfA1" ); /// REQUIRED ///////////
if( strPlatformUrl === "" ){
throw new Error( "\n AutomatedTask ConfigError:" +
" Config {A1: Target PlatformURL} is empty \n" );
}
engine.log( " AutomatedTask Config: Target PlatformURL: " + strPlatformUrl );
const strProcessModelInfoId = configs.get ( "StrConfA2" ); /// REQUIRED ///////////
if( strProcessModelInfoId === "" ){
throw new Error( "\n AutomatedTask ConfigError:" +
" Config {A2: ProcessModelInfoId} is empty \n" );
}
engine.log( " AutomatedTask Config: Workflow App ID: " + strProcessModelInfoId );
let strLimit = configs.get ( "StrConfA3" ); // NotRequired /////////
if( strLimit === "" ){
strLimit = "100";
}else if( isNaN( parseInt(strLimit) ) || parseInt(strLimit) < 0 ){
throw new Error( "\n AutomatedTask ConfigError:" +
" Config {A3: Max Num of Extraction} must be a positive integer \n" );
}else if( parseInt(strLimit) > 1000 ){
engine.log( " AutomatedTask ConfigWarning: " +
" {A3: Max Num of Extraction} is limited to 1000" );
strLimit = "1000";
}
const strDataitemIds = configs.get ( "StrConfB1" ); /// REQUIRED ///////////
if( strDataitemIds === "" ){ // processInstanceId,string:0,date:2,select:3
throw new Error( "\n AutomatedTask ConfigError:" +
" Config {B1: DataitemIds} is empty \n" );
}
engine.log( " AutomatedTask Config: Dataitem IDs: " + strDataitemIds );
const arrDataitemIds = strDataitemIds.split(",");
let strDateRange = configs.get ( "StrConfC1" ); // NotRequired /////////
if( strDateRange === "start" ){ // "start" or "end" or {ID of DATE data}
engine.log( " AutomatedTask Config: DateRange is applied to StartDatetime" );
}else if( strDateRange === "" ){ // default
strDateRange = "start";
engine.log( " AutomatedTask Config: DateRange is applied to StartDatetime" );
}else if( strDateRange === "end" ){
engine.log( " AutomatedTask Config: DateRange is applied to EndDatetime" );
}else if( parseInt(strDateRange, 10) >= 0 ){
engine.log( " AutomatedTask Config: DateRange is applied to DateData " + strDateRange );
}else{ // isNaN( parseInt(strDateRange) ) || parseInt(strDateRange) < 0
throw new Error( "\n AutomatedTask ConfigError:" +
" Config {C1: Date-Range data} must be 'start' 'end' or an integer \n" );
}
const regBpmsYMD = /^\d{4}-\d{2}-\d{2}$/;
const regBpmsYMDHM = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/;
let strRangeFrom = configs.get ( "StrConfC2" ); // NotRequired /////////
if( strRangeFrom === "" ){ // default
strRangeFrom = "#today.addDays(-7)";
}else if( ! regBpmsYMD.test(strRangeFrom) && ! regBpmsYMDHM.test(strRangeFrom) ){
throw new Error( "\n AutomatedTask ConfigError:" +
" Config {From} must be 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM' \n" );
}
engine.log( " AutomatedTask Config: Range From: " + strRangeFrom );
let strRangeTo = configs.get ( "StrConfC3" ); // NotRequired /////////
if( strRangeTo === "" ){ // default
strRangeTo = "#today";
}else if( ! regBpmsYMD.test(strRangeTo) && ! regBpmsYMDHM.test(strRangeTo) ){
throw new Error( "\n AutomatedTask ConfigError:" +
" Config {To} must be 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM' \n" );
}
engine.log( " AutomatedTask Config: Range To: " + strRangeTo );
let boolNewestFirst = configs.getObject( "BoolConfC4" ); // Toggle //////////////
if( boolNewestFirst ){
engine.log( " AutomatedTask Config: Sort Order: Descending (Newest First)");
}else{
engine.log( " AutomatedTask Config: Sort Order: Ascending (Oldest First)");
}
const strPocketTsv = configs.getObject( "SelectConfD1" ); /// REQUIRED ///////////
const numPocketExtracted = configs.getObject( "SelectConfD2" ); // NotRequired /////////
const numPocketRange = configs.getObject( "SelectConfD3" ); // NotRequired /////////
//// == Data Retrieving / ワークフローデータの参照 ==
// (Nothing. Retrieved via Expression Language in Config Retrieving)
//// == Calculating / 演算 ==
/// Get Process Instances
/// Questetra Workflow API
/// https://questetra.zendesk.com/hc/en-us/articles/360014835832-M418
/// https://questetra.zendesk.com/hc/ja/articles/360014835832-M418
// request1, prepare
let request1Uri = strPlatformUrl + "API/OR/ProcessInstance/list";
let request1Obj = {}; // (define Range Criteria for Questetra ProcessInstance Search)
request1Obj.processModelInfoId = parseInt(strProcessModelInfoId); // int
// request1 - sort key
if( strDateRange === "end" ){
request1Obj.sortProperty = "processInstanceEndDatetime";
}else{
request1Obj.sortProperty = "processInstanceStartDatetime";
}
if( boolNewestFirst ){
request1Obj.sortDirection = "DESC";
}else{
request1Obj.sortDirection = "ASC";
}
// request1 - Date Range
if( strDateRange === "start" ){
request1Obj.processInstanceStartDateFrom = strRangeFrom; // Datetime available
request1Obj.processInstanceStartDateTo = strRangeTo;
}else if( strDateRange === "end" ){
request1Obj.processInstanceEndDateFrom = strRangeFrom;
request1Obj.processInstanceEndDateTo = strRangeTo;
}else{
request1Obj.data= [];
request1Obj.data[0] = {};
request1Obj.data[0].type = "date"; // Datetime NOT available
request1Obj.data[0].number = parseInt(strDateRange); // int number
request1Obj.data[0].method = "after-equals";
if( regBpmsYMDHM.test(strRangeFrom) ){ // if "2022-01-31 12:34"
request1Obj.data[0].value = strRangeFrom.slice(0,10);
}else{
request1Obj.data[0].value = strRangeFrom;
}
request1Obj.data[1] = {};
request1Obj.data[1].type = "date";
request1Obj.data[1].number = parseInt(strDateRange);
request1Obj.data[1].method = "before-equals";
if( regBpmsYMDHM.test(strRangeTo) ){
request1Obj.data[1].value = strRangeTo.slice(0,10);
}else{
request1Obj.data[1].value = strRangeTo;
}
}
// request1 - Extraction
const regDataitemId = /^(\w+):(\w+)$/;
request1Obj.fields = [];
for( let i = 0; i < arrDataitemIds.length; i++ ){ // processInstanceId,string:0,date:2,select:3
if( ! regDataitemId.test(arrDataitemIds[i]) ){ // "processInstanceId", "processInstanceTitle", ...
}else{ // string:0,date:2,select:3
let objTmp = {};
objTmp.type = arrDataitemIds[i].replace( /(\w+):(\w+)/, '$1' );
objTmp.number = parseInt(arrDataitemIds[i].replace( /(\w+):(\w+)/, '$2' ));
request1Obj.fields.push( objTmp );
}
}
engine.log( " AutomatedTask Criteria: \n" + JSON.stringify( request1Obj ) );
// request1 - Rest Parameters
let request1 = httpClient.begin(); // HttpRequestWrapper
request1 = request1.authSetting( strAuthzSetting ); // with "Authorization: Bearer XX"
// https://questetra.zendesk.com/hc/en-us/articles/360024574471-R2300#HttpRequestWrapper
request1 = request1.queryParam( "limit", strLimit );
request1 = request1.queryParam( "criteria", JSON.stringify( request1Obj ) );
// request1, try
const response1 = request1.get( request1Uri ); // HttpResponseWrapper
engine.log( " AutomatedTask ApiRequest1 Start: " + request1Uri );
const response1Code = response1.getStatusCode() + "";
const response1Body = response1.getResponseAsString() + "";
engine.log( " AutomatedTask ApiResponse Status: " + response1Code );
if( response1Code !== "200"){
throw new Error( "\n AutomatedTask UnexpectedResponseError: " +
response1Code + "\n" + response1Body + "\n" );
}
// response1, parse
const response1Obj = JSON.parse( response1Body );
engine.log( " AutomatedTask Parsed: Number of Received Instances: " + response1Obj.processInstances.length );
engine.log( " AutomatedTask Parsed: Number of Filtered Instances: " + response1Obj.count );
/*
//engine.log( response1Body ); // debug
// Request Example 1 //////////
{
"processModelInfoId":1422,
"sortProperty":"processInstanceStartDatetime",
"sortDirection":"ASC",
"processInstanceStartDateFrom":"2021-12-01",
"processInstanceStartDateTo":"#today",
"fields":[
{"type":"string","number":11},
{"type":"date","number":10}]}
]
}
// Response Example 1
{
"count": 15,
"processInstances": [
{
"activeTokenNodeName": null,
"data": {
"10": {
"dataType": "DATE",
"id": 55498187,
"processDataDefinitionNumber": 10,
"subType": "DATE_YM",
"value": "2021-11",
"viewOrder": 15
},
"11": {
"dataType": "STRING",
"id": 55498188,
"processDataDefinitionNumber": 11,
"subType": null,
"value": "Transportation",
"viewOrder": 16
}
},
"processInstanceDebug": false,
"processInstanceEndDatetime": "2021-12-03T14:52:21+0900",
"processInstanceId": 1641335,
"processInstanceIdForView": "p1641335",
"processInstanceInitQgroupId": 5,
"processInstanceInitQgroupName": "Development Department",
"processInstanceInitQuserId": 86,
"processInstanceInitQuserName": "SUZUKI Ichiro",
"processInstanceSequenceNumber": 5918,
"processInstanceStartDatetime": "2021-12-03T12:03:46+0900",
"processInstanceState": "ENDED",
"processInstanceTitle": "Tokyo-Kyoto 20211119",
"processModelInfoCategory": "2-Management",
"processModelInfoId": 1422,
"processModelInfoName": "222-reimbursement",
"processModelVersion": 43,
"starred": false
},
{
"activeTokenNodeName": null,
"data": {
"10": {
"dataType": "DATE",
"id": 55498238,
"processDataDefinitionNumber": 10,
"subType": "DATE_YM",
"value": "2021-11",
"viewOrder": 15
},
"11": {
"dataType": "STRING",
"id": 55498239,
"processDataDefinitionNumber": 11,
"subType": null,
"value": "Transportation",
"viewOrder": 16
}
},
"processInstanceDebug": false,
"processInstanceEndDatetime": "2021-12-03T14:52:09+0900",
"processInstanceId": 1641336,
"processInstanceIdForView": "p1641336",
"processInstanceInitQgroupId": 5,
"processInstanceInitQgroupName": "Development Department",
"processInstanceInitQuserId": 86,
"processInstanceInitQuserName": "SUZUKI Ichiro",
"processInstanceSequenceNumber": 5919,
"processInstanceStartDatetime": "2021-12-03T12:06:54+0900",
"processInstanceState": "ENDED",
"processInstanceTitle": "Tokyo-Kyoto 20211109",
"processModelInfoCategory": "2-Management",
"processModelInfoId": 1422,
"processModelInfoName": "222-reimbursement",
"processModelVersion": 43,
"starred": false
}
]
}
// Request Example 2 //////////
{
"processModelInfoId":1422,
"sortProperty":"processInstanceStartDatetime",
"sortDirection":"ASC",
"data":[
{
"type":"date",
"number":5,
"method":"after-equals",
"value":"2021-12-01"
},
{
"type":"date",
"number":5,
"method":"before-equals",
"value":"#today"
}
],
"fields":[
{
"type":"decimal",
"number":12
},
{
"type":"date",
"number":10
},
{
"type":"string",
"number":11
}
]
}
// Response Example 2
{
"count": 9,
"processInstances": [
{
"activeTokenNodeName": null,
"data": {
"10": {
"dataType": "DATE",
"id": 56086017,
"processDataDefinitionNumber": 10,
"subType": "DATE_YM",
"value": "2021-12",
"viewOrder": 15
},
"11": {
"dataType": "STRING",
"id": 56086018,
"processDataDefinitionNumber": 11,
"subType": null,
"value": "Transportation",
"viewOrder": 16
},
"12": {
"dataType": "DECIMAL",
"id": 56086019,
"processDataDefinitionNumber": 12,
"subType": null,
"value": "418",
"viewOrder": 17
}
},
"processInstanceDebug": false,
"processInstanceEndDatetime": "2021-12-21T10:32:20+0900",
"processInstanceId": 1655495,
"processInstanceIdForView": "p1655495",
"processInstanceInitQgroupId": 3,
"processInstanceInitQgroupName": "Sales",
"processInstanceInitQuserId": 16,
"processInstanceInitQuserName": "SATO Jiro",
"processInstanceSequenceNumber": 5925,
"processInstanceStartDatetime": "2021-12-20T07:07:43+0900",
"processInstanceState": "ENDED",
"processInstanceTitle": "Shinjuku-Tokyo",
"processModelInfoCategory": "2-Management",
"processModelInfoId": 1422,
"processModelInfoName": "222-reimbursement",
"processModelVersion": 43,
"starred": false
},
{
"activeTokenNodeName": null,
"data": {
"10": {
"dataType": "DATE",
"id": 56086051,
"processDataDefinitionNumber": 10,
"subType": "DATE_YM",
"value": "2021-12",
"viewOrder": 15
},
"11": {
"dataType": "STRING",
"id": 56086052,
"processDataDefinitionNumber": 11,
"subType": null,
"value": "Transportation",
"viewOrder": 16
},
"12": {
"dataType": "DECIMAL",
"id": 56086053,
"processDataDefinitionNumber": 12,
"subType": null,
"value": "220",
"viewOrder": 17
}
},
"processInstanceDebug": false,
"processInstanceEndDatetime": "2021-12-21T10:32:59+0900",
"processInstanceId": 1655496,
"processInstanceIdForView": "p1655496",
"processInstanceInitQgroupId": 3,
"processInstanceInitQgroupName": "Sales",
"processInstanceInitQuserId": 16,
"processInstanceInitQuserName": "SATO Jiro",
"processInstanceSequenceNumber": 5926,
"processInstanceStartDatetime": "2021-12-20T07:08:16+0900",
"processInstanceState": "ENDED",
"processInstanceTitle": "Kyoto-KarasumaOike",
"processModelInfoCategory": "2-Management",
"processModelInfoId": 1422,
"processModelInfoName": "222-reimbursement",
"processModelVersion": 43,
"starred": false
}
]
}
*/
// build TSV
let strTsv = "";
for( let h = 0; h < response1Obj.processInstances.length; h++ ){
for( let i = 0; i < arrDataitemIds.length; i++ ){
if( arrDataitemIds[i] === "processInstanceId" ){
strTsv += response1Obj.processInstances[h].processInstanceId;
}else if( arrDataitemIds[i] === "processInstanceTitle" ){
if( response1Obj.processInstances[h].processInstanceTitle !== null ){
strTsv += response1Obj.processInstances[h].processInstanceTitle;
}
}else if( arrDataitemIds[i] === "processInstanceState" ){
if( response1Obj.processInstances[h].processInstanceState !== null ){
strTsv += response1Obj.processInstances[h].processInstanceState;
}
}else if( arrDataitemIds[i] === "processInstanceStartDatetime" ){
if( response1Obj.processInstances[h].processInstanceStartDatetime !== null ){
strTsv += response1Obj.processInstances[h].processInstanceStartDatetime;
}
}else if( arrDataitemIds[i] === "processInstanceEndDatetime" ){
if( response1Obj.processInstances[h].processInstanceEndDatetime !== null ){
strTsv += response1Obj.processInstances[h].processInstanceEndDatetime;
}
}else if( arrDataitemIds[i] === "processModelInfoId" ){
if( response1Obj.processInstances[h].processModelInfoId !== null ){
strTsv += response1Obj.processInstances[h].processModelInfoId;
}
}else if( arrDataitemIds[i] === "processModelInfoName" ){
if( response1Obj.processInstances[h].processModelInfoName !== null ){
strTsv += response1Obj.processInstances[h].processModelInfoName;
}
}else if( arrDataitemIds[i] === "processModelInfoCategory" ){
if( response1Obj.processInstances[h].processModelInfoCategory !== null ){
strTsv += response1Obj.processInstances[h].processModelInfoCategory;
}
}else if( arrDataitemIds[i] === "processInstanceInitQuserId" ){
if( response1Obj.processInstances[h].processInstanceInitQuserId !== null ){
strTsv += response1Obj.processInstances[h].processInstanceInitQuserId;
}
}else if( arrDataitemIds[i] === "processInstanceInitQuserName" ){
if( response1Obj.processInstances[h].processInstanceInitQuserName !== null ){
strTsv += response1Obj.processInstances[h].processInstanceInitQuserName;
}
}else if( arrDataitemIds[i] === "processInstanceInitQgroupId" ){
if( response1Obj.processInstances[h].processInstanceInitQgroupId !== null ){
strTsv += response1Obj.processInstances[h].processInstanceInitQgroupId;
}
}else if( arrDataitemIds[i] === "processInstanceInitQgroupName" ){
if( response1Obj.processInstances[h].processInstanceInitQgroupName !== null ){
strTsv += response1Obj.processInstances[h].processInstanceInitQgroupName;
}
}else if( arrDataitemIds[i] === "processModelVersion" ){
if( response1Obj.processInstances[h].processModelVersion !== null ){
strTsv += response1Obj.processInstances[h].processModelVersion;
}
}else if( arrDataitemIds[i] === "processInstanceDebug" ){
if( response1Obj.processInstances[h].processInstanceDebug !== null ){
strTsv += response1Obj.processInstances[h].processInstanceDebug;
}
}else if( arrDataitemIds[i] === "starred" ){
if( response1Obj.processInstances[h].starred !== null ){
strTsv += response1Obj.processInstances[h].starred;
}
}else if( regDataitemId.test(arrDataitemIds[i]) ){
const dataId = arrDataitemIds[i].replace( /(\w+):(\w+)/, '$2' );
if( response1Obj.processInstances[h].data[ dataId ] == undefined ){
strTsv += "#N/A";
}else if( response1Obj.processInstances[h].data[ dataId ].dataType === "STRING" ||
response1Obj.processInstances[h].data[ dataId ].dataType === "DECIMAL" ||
response1Obj.processInstances[h].data[ dataId ].dataType === "DATE" ||
response1Obj.processInstances[h].data[ dataId ].dataType === "DATETIME" ||
response1Obj.processInstances[h].data[ dataId ].dataType === "QUSER" ||
response1Obj.processInstances[h].data[ dataId ].dataType === "QGROUP" ||
response1Obj.processInstances[h].data[ dataId ].dataType === "DISCUSSION" ){
if( response1Obj.processInstances[h].data[ dataId ].value !== null ){
strTsv += response1Obj.processInstances[h].data[ dataId ].value
.replace( /\n/g, '' ).replace( /\t/g, '' );
}
}else if( response1Obj.processInstances[h].data[ dataId ].dataType === "SELECT" ){
if( response1Obj.processInstances[h].data[ dataId ].value !== null ){
for( let j = 0; j < response1Obj.processInstances[h].data[ dataId ].value.length; j++ ){
strTsv += response1Obj.processInstances[h].data[ dataId ].value[j].display
.replace( /\n/g, '' ).replace( /\t/g, '' );
if( j !== response1Obj.processInstances[h].data[ dataId ].value.length - 1 ){
strTsv += " "; // (Multiple: Space-separated)
}
}
}
}else if( response1Obj.processInstances[h].data[ dataId ].dataType === "FILE2" ){
if( response1Obj.processInstances[h].data[ dataId ].value !== null ){
for( let j = 0; j < response1Obj.processInstances[h].data[ dataId ].value.length; j++ ){
strTsv += response1Obj.processInstances[h].data[ dataId ].value[j].name
.replace( /\n/g, '' ).replace( /\t/g, '' );
if( j !== response1Obj.processInstances[h].data[ dataId ].value.length - 1 ){
strTsv += " "; // (Multiple: Space-separated)
}
}
}
}else{
strTsv += "#TYPE!";
}
}
if( i !== arrDataitemIds.length - 1 ){
strTsv += "\t";
}
}
if( h !== response1Obj.processInstances.length - 1 ){
strTsv += "\n";
}
}
//// == Data Updating / ワークフローデータへの代入 ==
if( strPocketTsv !== null ){ // STRING
engine.setData( strPocketTsv, strTsv );
}
if( numPocketExtracted !== null ){
engine.setData( numPocketExtracted,
new java.math.BigDecimal( response1Obj.processInstances.length ) );
}
if( numPocketRange !== null ){
engine.setData( numPocketRange,
new java.math.BigDecimal( response1Obj.count ) );
}
} //////// END "main()" /////////////////////////////////////////////////////////////////
/*
Notes:
- When a process reaches this automated task, a request is thrown to the target workflow platform.
- Business data accumulated in the workflow platform can be automatically extracted via API.
- With "Timer Start Event", you can automate weekly or monthly aggregation and reporting tasks.
- The target workflow platform is set by URL. (REST API Server)
- `https://example.questetra.net/`
- If the target is the same platform, setting by variables is convenient. (System variable)
- `${var[applicationRoot]}`
- The output TSV text will be generated as "the simplest tab-delimited string".
- TAB codes and line feed codes in each data will be converted to " " (half-width space).
- Double-quote characters are also retained in their unescaped state.
- The extraction range is specified by date.
- Process Start Date and Process End Date
- e.g.: `2021-12-15` - `2022-01-31`
- e.g.: `2021-12-15` - `2022-01-31 23:59`
- e.g.: `2021-12-15` - `#today
- e.g.: `#today.addDays(-7)` - `#today` (default)
- Any DATE type data.
- e.g.: `2021-12-15` - `2022-01-31` (default)
- e.g.: `2021-12-15` - `#today` (default) Any date type data.
- e.g.: `#today.addDays(-7)` - `#today` (default)
- Dynamic values will be set for each case (initial of process / automated task config)
- R2271: Output of Date and Datetime Data via EL syntax
- https://questetra.zendesk.com/hc/en-us/articles/360024292672-R2271
- The extraction items and their order are specified by CSV. (Extraction CSV)
- e.g.: `string:0,date:2,select:3`.
- e.g.: `processInstanceId,decimal:10,date:2,select:3,processInstanceTitle`.
- "Process ID" and "Title" can also be extracted.
APPENDIX:
- Extraction CSV (e.g.: `string:0,date:2,select:3`)
- How to specify the data type
- String: `string
- Numeric: `decimal`.
- Select: `select`.
- Date: `date`.
- Datetime: `datetime`.
- File: `file`.
- User: `quser`.
- Organization: `qgroup`.
- Table: `list`.
- Discussion: `discussion`.
- How to specify process title, etc. (process properties)
- Process ID: `processInstanceId`.
- Title: `processInstanceTitle`.
- State: `processInstanceState`.
- Start Time: `processInstanceStartDatetime`.
- End Time: `processInstanceEndDatetime`.
- App ID: `processModelInfoId`
- App Name: `processModelInfoName`
- Category: `processModelInfoCategory`
- Start User ID: `processInstanceInitQuserId`
- Start User: `processInstanceInitQuserName`.
- Start Organization ID: `processInstanceInitQgroupId`
- Start Organization: `processInstanceInitQgroupName`
- Version: `processModelVersion`
- Debug: `processInstanceDebug`
- Star: `starred`
- If a file type is specified, the file name will be extracted (multiple: space separated)
- If a select type is specified, the display text will be extracted (multiple: space separated)
- If an undefined data ID is specified, `#N/A` will be output.
- If an unsupported data type is specified, `#TYPE!` will be output.
- Authorization settings for automated communication
- Add the client on the target Workflow Platform (server side) in advance. (System Admin privilege required)
- "API Clients" > "OAuth2 Clients" > "Add OAuth2 Client"
- Redirect URL
- `https://s.questetra.net/oauth2callback`
- Add "HTTP Authorization Setting" for the Workflow app. (App Administrator privilege required)
- "App Settings" > (App Details) > "App" > "HTTP Authorization Setting > "Add"
- `OAuth2`
- Name: (Any name)
- e.g.: `For TSV extraction`
- Authorization Endpoint URL: (refer to the registration information on the server side)
- e.g.: `https://example.questetra.net/oauth2/authorize`
- Token Endpoint URL: (refer to the registration information on the server side)
- e.g.: `https://example.questetra.net/oauth2/token`
- Scope: `read`.
- Client ID: (refer to the server-side registration information)
- e.g.: `KXkYNxxxxXvJBmyyyyyIvEwuzzzzzli`.
- Client Secret: (refer to the server-side registration information)
- e.g.: `IHYWfxxxxxEZ1GuyyyyysdAM`.
- REST API Specification
- "Questetra Workflow API" (swagger)
- https://online-demo-en.questetra.net/s/swagger/index.html?urls.primaryName=Workflow%20API
- or "https://{YOUR_PlatformId}.questetra.net/s/swagger/index.html"
- There is another method for extracting business data via API: the ReportId method.
- Extraction conditions (Report) are saved in advance on the Workflow Platform where data is stored
- "Questetra BPMS: Process, Batch Extract by Filter as TSV"
- https://support.questetra.com/addons/questetra-bpms-process-batch-extract-by-filter-as-tsv-2021/
- Since you only need to specify Report Id, you can easily model aggregate operations.
- However, if an item is added, the number of columns in the extracted TSV will increase.
- Also, the display order of the extracted TSVs is not reproduced. (You will need to reorder them.)
Notes (ja):
- 案件が自動処理工程に到達した際、ターゲットワークフロー基盤に抽出リクエストが投げられます。
- ワークフロー基盤内に蓄積された業務データを自動抽出できます。(API経由抽出)
- "タイマー開始イベント" と併用すれば、週次や月次の集計業務・レポート業務を自動化できます。
- ターゲットとなるワークフロー基盤は URL で設定します。(REST API 接続先)
- `https://example.questetra.net/`
- ターゲットとなるワークフロー基盤が同一基盤の場合、変数による設定が便利です。(システム変数)
- `${var[applicationRoot]}`
- 出力TSVテキストは「もっともシンプルなタブ区切り文字列」として生成されます。
- 各データ内のTABコードや改行コードは " " (半角スペース)に変換されます。
- ダブルクオート文字も、エスケープされていない状態で保持されます。
- 抽出範囲は日付で指定します。
- プロセス開始日時・プロセス終了日時
- e.g.: `2021-12-15` - `2022-01-31`
- e.g.: `2021-12-15` - `2022-01-31 23:59`
- e.g.: `2021-12-15` - `#today`
- e.g.: `#today.addDays(-7)` - `#today` (default)
- 任意の日付型データ
- e.g.: `2021-12-15` - `2022-01-31`
- e.g.: `2021-12-15` - `#today`
- e.g.: `#today.addDays(-7)` - `#today` (default)
- 案件ごとに動的な値がセットされる設定(案件データ初期値/自動工程コンフィグ)
- R2271: EL式による日付日時としての出力(データ設定式)
- https://questetra.zendesk.com/hc/ja/articles/360024292672-R2271
- 抽出項目とその順序はCSVで指定します。(抽出CSV)
- e.g.: `string:0,date:2,select:3`
- e.g.: `processInstanceId,decimal:10,date:2,select:3,processInstanceTitle`
- 案件の「プロセスID」や「タイトル」も抽出可能です
APPENDIX (ja):
- 抽出CSV (e.g.: `string:0,date:2,select:3`)
- データ型の指定方法:
- 文字: `string`
- 数値: `decimal`
- 選択: `select`
- 日付: `date`
- 日時: `datetime`
- ファイル: `file`
- ユーザ: `quser`
- 組織: `qgroup`
- テーブル: `list`
- 掲示板: `discussion`
- 案件タイトル等(プロセスのプロパティ)の指定方法:
- プロセスID: `processInstanceId`
- 件名: `processInstanceTitle`
- 状態: `processInstanceState`
- 開始日時: `processInstanceStartDatetime`
- 終了日時: `processInstanceEndDatetime`
- アプリID: `processModelInfoId`
- アプリ名: `processModelInfoName`
- カテゴリ: `processModelInfoCategory`
- 開始ユーザID: `processInstanceInitQuserId`
- 開始ユーザ: `processInstanceInitQuserName`
- 開始組織ID: `processInstanceInitQgroupId`
- 開始組織: `processInstanceInitQgroupName`
- バージョン: `processModelVersion`
- デバッグ: `processInstanceDebug`
- スター☆: `starred`
- ファイル型を指定した場合、ファイル名が抽出されます(複数:スペース区切り)
- 選択型を指定した場合、表示テキストが抽出されます(複数:スペース区切り)
- 未定義のデータ項目IDが指定された場合は、`#N/A` が出力されます
- サポート外のデータ型が指定された場合は、`#TYPE!` が出力されます
- 自動通信の認可設定
- 接続先ワークフロー基盤側(サーバ側)で、予め接続元を登録します。(要システム管理権限)
- [APIクライアント]>[OAuth2クライアント]>[OAuth2クライアント追加]
- リダイレクトURL(Redirect URL)
- `https://s.questetra.net/oauth2callback`
- 接続元ワークフローアプリの[HTTP認証設定]を設定します。(アプリ管理権限)
- [アプリ設定]>(アプリ詳細)>[アプリ]>[HTTP認証設定]>[追加]
- `OAuth2`
- 名前: (任意の名前)
- e.g.: `案件データTSV抽出用`
- 認可エンドポイントURL: (サーバ側の登録情報を参照)
- e.g.: `https://example.questetra.net/oauth2/authorize`
- トークンエンドポイントURL: (サーバ側の登録情報を参照)
- e.g.: `https://example.questetra.net/oauth2/token`
- スコープ: `read`
- クライアントID: (サーバ側の登録情報を参照)
- e.g.: `KXkYNxxxxxXvJBmyyyyyIvEwuzzzzzli`
- クライアントシークレット: (サーバ側の登録情報を参照)
- e.g.: `IHYWfxxxxxEZ1GuyyyyysdAM`
- REST API 仕様
- "Questetra Workflow API" (swagger)
- https://online-demo-ja.questetra.net/s/swagger/index.html?urls.primaryName=Workflow%20API
- or "https://{YOUR_PlatformId}.questetra.net/s/swagger/index.html"
- 業務データのAPI経由抽出には、他に「ReportId 方式」があります。
- データが蓄積されているワークフロー基盤側で、あらかじめ抽出条件(Report)を保存しておく方式
- "Questetra BPMS: 案件, 保存済フィルタでTSV一括抽出"
- https://support.questetra.com/ja/addons/questetra-bpms-process-batch-extract-by-filter-as-tsv-2021/
- Report Id を指定するだけなので、集計業務を簡単にモデリングできます。
- しかし、たとえば抽出条件(保存済フィルタ)の項目が追加削除されると、抽出TSVの列数が増減します。
- また、抽出TSVの表示順が再現されません。(並べ替えが必要になります)
*/