// 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 strPropertyId = configs.get ( "StrConfA1" ); /// REQUIRED
if( strPropertyId === "" ){
throw new Error( "\n AutomatedTask ConfigError:" +
" Config {A1: PropertyId} must be non-empty \n" );
}
const strMetric = configs.get ( "StrConfA2" ); /// REQUIRED
if( strMetric === "" ){
throw new Error( "\n AutomatedTask ConfigError:" +
" Config {A2: Metric} must be non-empty \n" );
}
const strDimension = configs.get ( "StrConfA3" ); /// REQUIRED
if( strDimension === "" ){
throw new Error( "\n AutomatedTask ConfigError:" +
" Config {A3: Dimension} must be non-empty \n" );
}
let strDimFilter = configs.get ( "StrConfB3" ); // NotRequired
let strDimFilterValues = configs.get ( "StrConfB4" ); // NotRequired
if( strDimFilter === "" && strDimFilterValues === "" ){
engine.log( " AutomatedTask Config:" +
" DimensionFilter not applied" );
}else if( strDimFilter !== "" && strDimFilterValues !== "" ){
engine.log( " AutomatedTask Config:" +
" DimensionFilter: " + strDimFilter + " " + strDimFilterValues );
}else if( strDimFilter === "" ){
engine.log( " AutomatedTask ConfigWarning:" +
" DimensionFilter ignored, Config {B3: DimensionName} required" );
}else if( strDimFilterValues === "" ){
engine.log( " AutomatedTask ConfigWarning:" +
" DimensionFilter ignored, Config {B4: MatchList} required" );
}else{
throw new Error( "\n AutomatedTask Unexpected Error \n" );
}
const numPocketTotal = configs.getObject( "SelectConfC1" ); // NotRequired
let strRankSize = configs.get ( "StrConfD1" ); // NotRequired
if( strRankSize === "" ){
strRankSize = "20";
}
let numRankSize = strRankSize - 0;
const strPocketRankTsv = configs.getObject( "SelectConfD2" ); // NotRequired
////// == Data Retrieving / ワークフローデータの参照 ==
// (Nothing. Retrieved via Expression Language in Config Retrieving)
////// == Calculating / 演算 ==
/// request1, prepare body
// Google Analytics > Reporting > Google Analytics Data API (GA4) > runRealtimeReport
// https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runRealtimeReport
let request1Obj = {};
request1Obj.dimensions = [];
request1Obj.dimensions[0] = {};
request1Obj.dimensions[0].name = strDimension;
request1Obj.metrics = [];
request1Obj.metrics[0] = {};
request1Obj.metrics[0].name = strMetric;
request1Obj.limit = numRankSize;
if( strDimFilter !== "" && strDimFilterValues !== "" ){
request1Obj.dimensionFilter = {};
request1Obj.dimensionFilter.filter = {};
request1Obj.dimensionFilter.filter.fieldName = strDimFilter;
request1Obj.dimensionFilter.filter.inListFilter = {};
request1Obj.dimensionFilter.filter.inListFilter.caseSensitive = true;
request1Obj.dimensionFilter.filter.inListFilter.values =
strDimFilterValues.split(",");
}
request1Obj.orderBys = [];
request1Obj.orderBys[0] = {};
request1Obj.orderBys[0].metric = {};
request1Obj.orderBys[0].metric.metricName = strMetric;
request1Obj.orderBys[0].desc = true;
request1Obj.metricAggregations = [];
request1Obj.metricAggregations[0] = "TOTAL";
/// request1, prepare header
let request1Uri = "https://analyticsdata.googleapis.com/v1beta/properties/" +
strPropertyId + ":runRealtimeReport";
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.body( JSON.stringify( request1Obj ), "application/json" );
/// request1, try
const response1 = request1.post( 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( response1Body ); // debug
{
"dimensionHeaders": [
{
"name": "city"
}
],
"metricHeaders": [
{
"name": "screenPageViews",
"type": "TYPE_INTEGER"
}
],
"rows": [
{
"dimensionValues": [
{
"value": "Chiyoda City"
}
],
"metricValues": [
{
"value": "3532"
}
]
},
{ ... },
{
"dimensionValues": [
{
"value": ""
}
],
"metricValues": [
{
"value": "378"
}
]
},
{ ... },
{
"dimensionValues": [
{
"value": "(not set)"
}
],
"metricValues": [
{
"value": "115"
}
]
}
],
"totals": [
{
"dimensionValues": [
{
"value": "RESERVED_TOTAL"
}
],
"metricValues": [
{
"value": "12221"
}
]
}
],
"rowCount": 94,
"kind": "analyticsData#runRealtimeReport"
}
*/
let strRankTsv = "";
let numTotal = 0;
if( response1Obj.hasOwnProperty("rows") ){
/// Create TSV by rows
strRankTsv += strMetric + "\t" + strDimension + "\n";
for( let i = 0; i < response1Obj.rows.length; i++ ){
strRankTsv += response1Obj.rows[i].metricValues[0].value + "\t";
strRankTsv += response1Obj.rows[i].dimensionValues[0].value;
if( i !== response1Obj.rows.length - 1 ){
strRankTsv += "\n";
}
}
/// Get TOTAL
numTotal = response1Obj.totals[0].metricValues[0].value;
}
////// == Data Updating / ワークフローデータへの代入 ==
if( numPocketTotal !== null ){
engine.setData( numPocketTotal, new java.math.BigDecimal( numTotal ) );
}
if( strPocketRankTsv !== null ){
engine.setData( strPocketRankTsv, strRankTsv );
}
} //////// END "main()" /////////////////////////////////////////////////////////////////
/*
Notes:
- Requests to the property (data storage) of Google Analytics when the process reaches the Automated Step.
- You can automate the extraction work of Google Analytics Data. Analytics Reports
- Extracts via "Google Analytics Data API" for GA4 properties.
- Data API can only be used to access GA4 properties and is not compatible with Universal Analytics.
- As of 202204, it is a "Beta version", although "no breaking changes are expected".
- https://developers.google.com/analytics/devguides/reporting/data/v1
- Make sure that the Mesurement ID to be extracted is `G-XXXXXXXXXX` (GA4 property).
- GA4 Properties is the latest version of Google Analytics released in October 2020.
- The Mesurement ID of the UA property is `UA-XXXXXXXX-X`.
- https://support.google.com/analytics/answer/10089681
- The following four values can be specified as the Realtime Metric. (As of 202206)
- "`activeUsers`": Active users (the number of distinct users who visited your site or app).
- "`conversions`": The count of conversion events.
- "`eventCount`": The count of events.
- "`screenPageViews`": Views
- Official Document: "Realtime Dimensions & Metrics"
- https://developers.google.com/analytics/devguides/reporting/data/v1/realtime-api-schema
- The following 16 values can be specified for the Realtime dimension. (as of 202206)
- "`appVersion`": App version (versionName (Android) or short bundle version (iOS))
- "`audienceId`": Audience ID
- "`audienceName`": The given name of an Audience.
- "`city`": The city from which the user activity originated.
- "`cityId`": The geographic ID of the city from which the user activity originated, derived from their IP address.
- "`country`": The country from which the user activity originated.
- "`countryId`": The geographic ID of the country from which the user activity originated. (ISO 3166-1 alpha-2 standard)
- "`deviceCategory`": The type of device: Desktop, Tablet, or Mobile.
- "`eventName`": The name of the event.
- "`minutesAgo`": The number of minutes ago that an event was collected. 00 is the current minute.
- "`platform`": The platform on which your app or website ran; for example, web, iOS, or Android.
- "`streamId`": The numeric data stream identifier for your app or website.
- "`streamName`": The data stream name for your app or website.
- "`unifiedScreenName`": The page title (web) or screen name (app) on which the even
- {User-scoped Custom Dimension}
- Event-scoped custom dimensions are not currently supported in the Realtime API.
- Refer to the official document for "API Name" (latest information) of metrics and dimensions.
- Official Document: "Realtime Dimensions & Metrics"
- https://developers.google.com/analytics/devguides/reporting/data/v1/realtime-api-schema
- Examples
- e.g., Number of views (`screenPageViews`) for each device (`deviceCategory`)
- e.g., Number of conversions (`conversions`) for each country (`country`)
- e.g., Number of active users (`activeUsers`) for each city (`city`)
APPENDIX
- To place this "Add-on Automated Step" on the design screen of the workflow diagram
- Import Addon-XML (definition file of this automated step) to Workflow App in advance.
- The system admins can also make it available in all Workflow Apps. (App-shared Add-on)
- Manual M415: Adding an Auto-Step to be Used in a Business Process Definition
- https://questetra.zendesk.com/hc/en-us/articles/360002247792-M415
- To activate the Workflow App including this "Add-on automated Step"
- Authorize API communications by an authorized user in advance.
- Enable "Google Analytics Data API" on the Google Cloud Platform
- APIs and Services: `Google Analytics Data API`
- https://console.cloud.google.com/project/_/apis/library
- OFFICIAL DOCUMENT
- https://cloud.google.com/service-usage/docs/enable-disable
- Create an "OAuth2.0 client ID" on the Google Cloud Platform
- Creating credentials:
- `OAuth Client ID`
- Application type:
- `Web application`
- Name:
- `Questetra to GA4`
- Authorized JavaScript origins:
- `https://your-subdomain.questetra.net`
- Authorized redirect URI:
- `https://s.questetra.net/oauth2callback`
- OFFICIAL DOCUMENT
- https://cloud.google.com/endpoints/docs/frameworks/java/javascript-client
- Set "HTTP authentication (OAuth2)" on the Questetra Workflow-App
- Name:
- `Questetra-GA4`
- Authorization Endpoint URL:
- `https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&prompt=consent`
- Token Endpoint URL:
- `https://oauth2.googleapis.com/token`
- Scope:
- `https://www.googleapis.com/auth/analytics.readonly`
- Client ID / Consumer Secret:
- (see above "OAuth 2.0 client ID")
- OFFICIAL DOCUMENT
- https://developers.google.com/identity/protocols/oauth2/web-server#httprest
- In this Add-on Automated Step, "Data API (GA4)" is used to acquire data from Google Analytics.
- Not "Reporting API V4".
- Not "Core Reporting API V3".
- Requests with a response longer than 30 seconds may result in an error.
- Can also filter the ranking list by Dimension Filter (inListFilter).
- Only data which dimension valuesexactly match any of the values will be extracted. (Case Sensitive)
- `country`: `Canada,Japan`
Notes-ja:
- 案件が自動工程に到達した際、Google アナリティクスのプロパティ(データ格納庫)にリクエストします。
- GoogleアナリティクスDataの抽出業務を自動化できます。 AnalyticsReports
- GA4プロパティ用の "Google Analytics Data API" を経由して抽出します。
- GA4プロパティへのアクセスにのみ使用でき、UniversalAnalyticsとは互換性がありません。
- また、202204時点において、「重大な変更は予想されていない」ものの、"Beta version" です。
- https://developers.google.com/analytics/devguides/reporting/data/v1
- GA4の計測IDは `G-XXXXXXXXXX` の書式になります。
- GA4プロパティは、2020年10月にリリースされた最新版の Google アナリティクスプロパティです。
- UAプロパティの計測IDは `UA-XXXXXXXX-X` となります。
- https://support.google.com/analytics/answer/10089681
- Realtime 指標としては指定できる値は以下の4つです。(202206現在)
- "`activeUsers`": アクティブユーザー数 (サイトやアプリの訪問者数)
- "`conversions`": コンバージョンイベントの数
- "`eventCount`": イベントの数
- "`screenPageViews`": 表示回数
- Realtime ディメンションとしては指定できる値は以下の16種です。(202206現在)
- "`appVersion`": Android の versionName もしくは iOS の Short Bundle Version
- "`audienceId`": オーディエンスID
- "`audienceName`": オーディエンス名
- "`city`": ユーザーアクティビティが発生した都市の名前
- "`cityId`": ユーザーアクティビティが発生した都市ID(IPアドレスから)
- "`country`": ユーザーアクティビティが発生した国地域の名前
- "`countryId`": ユーザーアクティビティが発生した国コード(ISO 3166-1 alpha-2 standard)
- "`deviceCategory`": デバイス(Desktop, Tablet, or Mobile)
- "`eventName`": イベント名
- "`minutesAgo`": イベントの収集時刻(分)[00は現在]
- "`platform`": プラットフォーム(Web、iOS、Android)
- "`streamId`": ストリームID
- "`streamName`": ストリーム名
- "`unifiedScreenName`": ページタイトル(ウェブ)またはスクリーンネーム(アプリ)
- (および User-scoped なカスタムディメンション)
- Event-scoped なカスタムディメンションはサポートされていません。(202206現在)
- 指標やディメンジョンの "API Name"(最新情報)は、公式マニュアルを参照します。
- 公式マニュアル: "Realtime Dimensions & Metrics"
- https://developers.google.com/analytics/devguides/reporting/data/v1/realtime-api-schema
- 組み合わせサンプル
- 例. デバイス (`deviceCategory`) ごとの表示回数 (`screenPageViews`)
- 例. 国地域 (`country`) ごとのコンバージョン数 (`conversions`)
- 例. 都市 (`city`) ごとのアクティブユーザー数 (`activeUsers`)
APPENDIX-ja
- この[アドオン自動工程]を、ワークフロー図の設計画面で配置(利用)できるようにするには
- 予めアドオンXML(この自動工程の定義ファイル)を、[Workflowアプリ]に追加(アドオン)します。
- システム管理者は、Workflow基盤の全アプリで配置できるようにすることも可能です。(アプリ共有アドオン)
- マニュアル M415: 業務プロセス定義で利用可能な自動工程を追加する (Professional edition)
- https://questetra.zendesk.com/hc/ja/articles/360002247792-M415
- この[アドオン自動工程]を含むワークフローアプリを、運用できるようにするには
- あらかじめ、権限ユーザによる認可(API通信の許可)が必要です。
- Google Cloud Platform 側で『Google Analytics Data API』を有効化する
- APIとサービスの有効化: `Google Analytics Data API`
- https://console.cloud.google.com/project/_/apis/library
- 公式マニュアル: サービスの有効化と無効化
- https://cloud.google.com/service-usage/docs/enable-disable
- Google Cloud Platform 側で『OAuth2.0クライアントID』を作成する
- 認証情報の作成:
- `OAuthクライアントID`
- アプリケーションの種類:
- `ウェブ アプリケーション`
- 名前:
- `Questetra to GA4`
- 承認済みのJavaScript生成元:
- `https://your-subdomain.questetra.net`
- 承認済みのリダイレクト URI:
- `https://s.questetra.net/oauth2callback`
- 公式マニュアル: https://cloud.google.com/endpoints/docs/frameworks/java/javascript-client
- Questetra 側で『"HTTP認証"(OAuth2)』を設定する
- 名前:
- `Questetra-GA4`
- 認可エンドポイントURL:
- `https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&prompt=consent`
- トークンエンドポイントURL:
- `https://oauth2.googleapis.com/token`
- スコープ:
- `https://www.googleapis.com/auth/analytics.readonly`
- クライアントID / クライアントシークレット:
- ( see above "OAuth 2.0 client ID" )
- 公式マニュアル: https://developers.google.com/identity/protocols/oauth2/web-server#httprest
- この[アドオン自動工程]では、Googleアナリティクスからのデータ取得に "Data API" が利用されています。
- "Reporting API V4" ではありません。
- "Core Reporting API V3" ではありません。
- レスポンスが30秒を超えるようなリクエストは、エラーになる場合があります。
- 完全一致リスト(inListFilter)を設定すれば、ランキングリストの絞り込みが可能です。
- ディメンションの値がいずれかの値と完全一致するデータだけが抽出されます。(Case Sensitive)
- `country`: `Canada,Japan`
*/