こんにちは、エクスチュアの權泳東(権泳東/コン・ヨンドン)です。
今回はSAINT分類データをAdobe I/OのAPIを使って取得する方法についてです。
AAのUIからもSAINT分類データをTSV形式でダウンロードする事が可能です。
しかし、ファイルサイズが1MBを超えてしまう場合、FTPというレガシーなプロトコルを使ってAdobe指定のFTPサーバーからファイルをダウンロードするという残念なエクスペリエンスを強いられます。
というわけで、もっとモダンなエクスペリンスを求めるためにAdobe I/OのAPIを使ってSAINT分類データを取得する処理を実装しました。
Adobe I/Oプロジェクトを作成する
Adobe I/Oコンソールを開いて、「Create new project」からプロジェクトを作成します。
作成したら、「Add API」で「Adobe Analytics」を選んで追加します。
必要な権限を追加してから、キーペアをzipファイルでダウンロードします。
認証の作成では「JWT」を選択してください。
JWT認証を実装する
ここからが本題。
JWT認証をしてAPI実行に必要なトークンを生成する処理をNode.jsで実装します。
まずは簡単なプログラムを書きました。
これ↓です。
/* token.js */ const jwt = require('jsonwebtoken'); const fs = require('fs'); const request = require('request'); const expire = Math.round((Date.now() + 86400000) / 1000); const payload = { "exp":expire, "iss":process.env.ADB_ORG_ID, "sub":process.env.ADB_TECH_ACC_ID, "https://ims-na1.adobelogin.com/s/ent_analytics_bulk_ingest_sdk":true, "aud":"https://ims-na1.adobelogin.com/c/"+process.env.ADB_CLIENT_ID }; const client_id = process.env.ADB_CLIENT_ID; const client_secret = process.env.ADB_CLIENT_SECRET; const secret = fs.readFileSync('private.key'); const options = { algorithm: 'RS256' }; const token = jwt.sign(payload, secret, options); const headers = { 'Content-Type' : 'application/x-www-form-urlencoded' }; let params = { url : 'https://ims-na1.adobelogin.com/ims/exchange/jwt', method : 'POST', headers : headers, form : { 'client_id' : client_id, 'client_secret' : client_secret, 'jwt_token' : token }, json : true }; request(params, function (error, response, body) { let res = body.access_token; console.log(res); });
JWTペイロードを生成して認証サーバーにPOST送信して24時間有効なトークンを取得する、という処理を実装しました。
このNode.jsプログラムの実行方法は後述します。
ClassificationsAPIを実装する
続いて、ClassificationsAPIを実装します。
これまたNode.jsでプログラムを作成しました。
これ↓です。
/* exec_saint_api.js */ const method = process.argv[2]; const token = process.env.TOKEN; const Client = require('node-rest-client').Client; const client = new Client(); const endpoint = 'https://api.omniture.com/admin/1.4/rest/'; const fs = require('fs'); let args = { headers: { 'Authorization' : 'Bearer ' + token, 'Content-Type' : 'application/json' }, parameters: { 'method' : 'Classifications.' + method } }; if (method == 'CreateExport') { args.data = { 'rsid_list' : [process.env.RSID], 'encoding' : 'UTF-8', 'all_rows' : true, 'element': process.env.VAR, 'email_address' : process.env.EMAIL, 'date_filter_start_date' : process.env.DATE_START, 'date_filter_end_date' : process.env.DATE_END }; client.post(endpoint, args, (data, response) => { console.log(data.job_id); }); } else if (method == 'GetStatus') { args.data = { 'job_id' : process.env.JOB_ID }; client.post(endpoint, args, (data, response) => { let timer = setInterval(() => { let job = data.find((x) => x.type == 'job_id'); if (job.status == 'Completed') { let file = data.find((y) => y.type == 'file_id'); let file_id = file.id; let page_num = file.viewable_pages; console.log(file_id + ',' + page_num); clearInterval(timer); } }, 60000); }); } else if (method == 'GetExport') { let file_id = process.env.FILE.split(',')[0]; let page_num = parseInt(process.env.FILE.split(',')[1]); let saint_json = process.env.SAINT_JSON; for (let i=0; i<page_num; i++) { args.data = { 'file_id' : file_id, 'page' : i+1 }; client.post(endpoint, args, (data, response) => { fs.appendFileSync(saint_json, JSON.stringify(data)); }); } }
SAINT分類データのエクスポートジョブを生成してからデータを取得するために、CreateExport, GetStatus, GetExportというメソッドを実行するための処理を実装しています。
このNode.jsプログラムの実行方法は以下で説明します。
プログラム実行のためのbashスクリプト
さて、ここまでに作成したtoken.jsとget_saint_api.jsを実行するためのbashスクリプトを書きます。
#!/bin/bash set -eu export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin ##設定ここから## # API認証情報 export ADB_ORG_ID="123456789@AdobeOrg" #OrgID export ADB_TECH_ACC_ID="abcdefg@techacct.adobe.com" #Tech Account ID export ADB_CLIENT_ID="0987654321" #client ID export ADB_CLIENT_SECRET="1234-5678-abcd-efgh" #client secret # エクスポート設定 export RSID="exturexturecom" export VAR="trackingcode" export EMAIL="exture@example.com" export DATE_START="2010-01-01" export DATE_END="2020-12-31" # ファイル名定義 export SAINT_JSON="saint.json" export SAINT_TXT="saint.txt" export LOAD_TXT="load.txt" ##設定ここまで## # 空ファイル作成 : > ${SAINT_JSON} : > ${SAINT_TXT} : > ${LOAD_TXT} export TOKEN=$(node token.js) # job作成 export JOB_ID=$(node exec_saint_api.js "CreateExport") echo "JOB_ID: ${JOB_ID}" # status確認 sleep 60 export FILE=$(node exec_saint_api.js "GetStatus") echo "FILE_ID: ${FILE%,*}" echo "PAGE_NUM: ${FILE#*,}" # download node exec_saint_api.js "GetExport" #jqでJSONをCSV変換 cat ${SAINT_JSON} |jq -r '.[]|.data[]|.row|@csv' > ${SAINT_TXT}
何をやってるかと言うと、まずAdobeI/Oのコンソールで作成したAPI実行に必要なJWT認証情報を環境変数として定義してます。
これらは全てAdobeI/Oコンソールから作成・取得出来ます。
続いて、SAINT分類データの取得に必要なAdobeAnalyticsのレポートスイートIDや変数名、通知先メアドなどを環境変数に持たせます。
出力するファイル名も環境変数で定義してあります。
そしてこのbashスクリプトを実行すると、まずはtoken.jsを使ってJWT認証を行ってトークンを取得します。
このトークンを使って、SAINT分類データのエクスポートジョブの作成から分類データの取得までをget_saint_api.jsが実行してます。
JSONファイルをCSV変換する
APIで取得した分類データはJSON形式になってます。
そのままではExcelやエディタで編集出来ないので、jqコマンドを使ってCSVに変換してます。
jqコマンドは以前↓の記事でも使いましたが、JSONを操作するためのLinuxコマンドです。
Linux Tips: コマンドラインでJSONをCSVに変換する
とても便利なので使い方を覚えると役に立ちます。
CSVに変換したSAINT分類データはExcelで編集したり、またはAdobeAnalyticsのDatafeedと一緒にBigQueryにロードしてBIツールで分析に使うのも良いでしょう。
もちろんBigQuery以外のデータウェアハウスに入れてもよいですし。
TL;DR
AdobeAnalyticsのSAINT分類データを取得するために、AdobeI/OのAPIを実装する方法について紹介しました。
AdobeI/OのAPIではJWT認証を使います。
また、APIで取得したJSONデータはCSVに変換すると扱いやすくなります。
あと、どうでも良いんですけど今はもう「SAINT」って言わずにただの「分類」って言うみたいですね。
どうでも良いです。
弊社では、Adobe Analytics認定エキスパート資格・Google Cloud認定プロフェショナルデータエンジニア資格・Linux Professional Institute認定資格を持ったエンジニア達が各種マーテックツールの導入実装コンサルティングサービスや、GCP/AWS/Azureなどのパブリッククラウドを使ったデータ分析基盤構築コンサルティングサービスを提供しております。
お問い合わせはこちらからどうぞ。