TreasureData + JavaScript SDK

## はじめに
TreausureDataにTreasureData社が提供している`JavaScript SDK`を用いてデータをアップロードする方法を記載します。

基本的な部分は既にTreasureData社のCTOの太田さんが[Qiita](http://qiita.com/kzk9/items/15f4e01cafa30fb8e7a5 Qiita)に書いてくれているのでこちらでは実際に動かしてデータの確認までを記載します。

## 環境
以下環境情報になります。

* HTTP Client OS: Mac OS X 10.9.5
* HTTP Client ブラウザ: Chrome 38.0.2125.101
* HTTP Server OS: Ubunt 12.04
* HTTP Server: nginx/1.1.19
* TreasureData JavaScript SDK: 1.2.0(2014/10/16時点最新)

## 前提条件
以下前提条件となります。

* Nginxがインストール済みであること。
* ブラウザ経由でアクセスできる何かしらのページ(HTMLファイル)があること。
* TreasureDataアカウントを持っていること。

注：今回は・・・改め今回も・・・日本版TreasureDataである`Yahoo!ビッグデータインサイト`に対して実施しました。AWS版のTreasureDataを利用の方はEndpointを読み替えて実施してください。

## Step:1 サンプルページの作成
`TreasureData JavaScript SDK`を埋め込むサンプルページを準備します。
今回は以下のような単純なサンプルページを用意しました。

```file:td_sample.html
<!doctype html>
<!--[if lt IE 9]><html class="ie8" lang="ja"><![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--><html lang="ja"><!--<![endif]-->
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="format-detection" content="telephone=no">
  <meta name="description" content="TD JS SDK Test">
  <title>TD Javascript Sample</title>
</head>
<body data-category="top">
  <div id="user_info">
    <div id="user_mail">
    hogehoge@example.com
    </div>
    <div id="user_name">
    hogehoge
    </div>
  </div>
</body>
</html>
```

ブラウザからアクセスすると以下のように表示されます。

![js_chrome_org_page.png](https://qiita-image-store.s3.amazonaws.com/0/46472/e70a3fa1-9748-80eb-f958-b0dbe2756a36.png "js_chrome_org_page.png")

id="user_mail", id="user_name"にそれぞれhogehoge@example.com, hogehogeが紐づいているページだけとなります。

## Step2: WriteOnly API-Keyの取得
こちら[前回の記事](http://qiita.com/akito1986/items/6794b75c3b3825cf2c7e 前回の記事)のまるパクリです。

TreasureDataには以下二つの`API Key`が存在します。

* フルアクセス権限API-Key: DB作成、削除、テーブル作成、削除、クエリ、データアップロードを行うことができるAPI-Key
* WriteOnly API-Key: データアップロードのみを行うことが出来るAPI-Key

ここではデータアップロードのみ可能なWriteOnly API-Keyの取得方法を記載します。

### Step2-1: WebConsoleにログイン
[WebConsole](https://console-ybi.idcfcloud.com/users/sign_in WebConsole)にアクセスしてLog inします。

![signin_1.png](https://qiita-image-store.s3.amazonaws.com/0/46472/37e7420e-2402-301d-77fc-8bf1c124c478.png "signin_1.png")

### Step2-2: My Profile画面の表示
ヘッダメニュ > Account名 > My Profile
でMy Profile画面を表示させます。
![console_myprofile.png](https://qiita-image-store.s3.amazonaws.com/0/46472/f0650e34-4675-4325-cac5-d9e48d2c4c1c.png "console_myprofile.png")

### Step2-3: Show Keys

`API Keys`パネルでアカウントのパスワード入力後に`Show Keys`ボタンを押下します。

![console_getapi1.png](https://qiita-image-store.s3.amazonaws.com/0/46472/df64ea9a-2824-f999-9c2a-61780e1b84f7.png "console_getapi1.png")


### Step2-4: WriteOnly API-Keyの取得
これでWriteOnly API-Keyが表示されるはずです。
まだ取得していいなければ、`Generate New`ボタンを押下して取得してください。

![console_getapi2.png](https://qiita-image-store.s3.amazonaws.com/0/46472/38a4515a-c814-0343-dd73-56f2e5596596.png "console_getapi2.png")

## Step3: アップロード先DB/TABLE作成
### Step3-1: WebConsoleにログイン
アップロード先となるDB/TABLEを作成します。
[WebConsole](https://console-ybi.idcfcloud.com/users/sign_in WebConsole)にアクセスしてLog inします。

![signin_1.png](https://qiita-image-store.s3.amazonaws.com/0/46472/37e7420e-2402-301d-77fc-8bf1c124c478.png "signin_1.png")

### Step3-2: DB作成
サイドメニュのDatabaseタブをクリックします。
![console_db_create_1_no_name.png](https://qiita-image-store.s3.amazonaws.com/0/46472/0eac0b61-7bc8-c0eb-e1b5-ede67102108d.png "console_db_create_1_no_name.png")

Database名を入力してCreateボタンを押下します。
ここでは、`js_sdk_db`と入力します。
![console_db_create_2_no_name.png](https://qiita-image-store.s3.amazonaws.com/0/46472/f410c51c-8f45-6fba-607a-a1e4eda70f10.png "console_db_create_2_no_name.png")

### Step3-3: Table作成
続けて`js_sdk_db`DB画面で`Create Table`ボタンを押下します。

![js_console_table_create1.png](https://qiita-image-store.s3.amazonaws.com/0/46472/cb39f522-e449-5f87-b643-dfbcc3854b02.png "js_console_table_create1.png")

そしてテーブル名を入力して`Create Table`ボタンを押下してテーブルを作成します。
ここでは`js_sdk_table`としています。

![js_console_table_create2.png](https://qiita-image-store.s3.amazonaws.com/0/46472/91b219b9-6ef1-2873-e481-5c26fec5bae4.png "js_console_table_create2.png")

## Step4: JavaScript SDKの埋め込み
Step1で作成したサンプルページに`TreasureData JavaScript SDK`を埋め込んでみます。
ここでは以下3Caseについて記載します。

* Case-1: ユーザ定義の情報のみの送付
* Case-2: SDKが自動で取得する情報のみ送付
* Case-3: Case1 + Case2の情報の送付

### Step4-Case-1: ユーザ定義の情報のみの送付

以下ソースとなります。

```file:td_sample_case1.html
<!doctype html>
<!--[if lt IE 9]><html class="ie8" lang="ja"><![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--><html lang="ja"><!--<![endif]-->
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="format-detection" content="telephone=no">
  <meta name="description" content="TD JS SDK Test">
  <title>TD Javascript Sample</title>
  <script type="text/javascript">
    !function(t,e){if(void 0===e[t]){e[t]=function(){e[t].clients.push(this),this._init=[Array.prototype.slice.call(arguments)]},e[t].clients=[];for(var r=function(t){return function(){return this["_"+t]=this["_"+t]||[],this["_"+t].push(Array.prototype.slice.call(arguments)),this}},s=["addRecord","set","trackEvent","trackPageview","ready"],n=0;n<s.length;n++){var i=s[n];e[t].prototype[i]=r(i)}var a=document.createElement("script");a.type="text/javascript",a.async=!0,a.src=("https:"===document.location.protocol?"https:":"http:")+"//s3.amazonaws.com/td-cdn/sdk/td-1.2.0.js";var c=document.getElementsByTagName("script")[0];c.parentNode.insertBefore(a,c)}}("Treasure",this); /* JavaScript SDK の読み込み*/
  </script>
</head>
<body data-category="top">
  <div id="user_info">
    <div id="user_mail">
    hogehoge@example.com
    </div>
    <div id="user_name">
    hogehoge
    </div>
  </div>
<!-- TD JS SDK Start -->
<script type="text/javascript">
  /* TreasureData Instance 作成 */
  var td = new Treasure({
    host: 'mobile-ybi.jp-east.idcfcloud.com', /* エンドポイントの指定 */
    database: 'js_sdk_db', /* データベースの指定 */
    writeKey: 'xxxxxxx09d147de381c3fd23c47035132dxxxxxxx' /* WriteOnly API-Keyの指定 */
  });
  /* Get Data */
  var user_mail = document.getElementById('user_mail');
  var user_name = document.getElementById('user_name');
  var user = {
    id: user_mail.innerText,
    name: user_name.innerText,
  } /* データの設定 */
  td.addRecord('js_sdk_table', user); /* データの送信 */
  console.log(user)
</script> 
<!-- TD JS SDK End -->
</body>
</html>
```

`JavaScript SDK の読み込み`で`TreasureData JavaScript SDK`をローカルに読み込んでいます。

`Get Data`部分でDOMを読み込んでid=user_mail, id= user_nameが指定されているタグの値をそれぞれuser_mail, user_nameに設定して、その後id, nameというkeyを持つuserオブジェクトに格納しています。
その後td.addRecordでデータをTreasureData上にアップロードしています。

この例ではイベントの設定もしていませんので、ページがロードされる度にデータがアップロードされます。

### Step4-Case-2: SDKが自動で取得する情報のみ送付

以下ソースとなります。

```file:td_sample_case2.html
<!doctype html>
<!--[if lt IE 9]><html class="ie8" lang="ja"><![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--><html lang="ja"><!--<![endif]-->
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="format-detection" content="telephone=no">
  <meta name="description" content="TD JS SDK Test">
  <title>TD Javascript Sample</title>
  <script type="text/javascript">
    !function(t,e){if(void 0===e[t]){e[t]=function(){e[t].clients.push(this),this._init=[Array.prototype.slice.call(arguments)]},e[t].clients=[];for(var r=function(t){return function(){return this["_"+t]=this["_"+t]||[],this["_"+t].push(Array.prototype.slice.call(arguments)),this}},s=["addRecord","set","trackEvent","trackPageview","ready"],n=0;n<s.length;n++){var i=s[n];e[t].prototype[i]=r(i)}var a=document.createElement("script");a.type="text/javascript",a.async=!0,a.src=("https:"===document.location.protocol?"https:":"http:")+"//s3.amazonaws.com/td-cdn/sdk/td-1.2.0.js";var c=document.getElementsByTagName("script")[0];c.parentNode.insertBefore(a,c)}}("Treasure",this); /* JavaScript SDK の読み込み*/
  </script>
</head>
<body data-category="top">
  <div id="user_info">
    <div id="user_mail">
    hogehoge@example.com
    </div>
    <div id="user_name">
    hogehoge
    </div>
  </div>
<!-- TD JS SDK Start -->
<script type="text/javascript">
  /* TreasureData Instance 作成 */
  var td = new Treasure({
    host: 'mobile-ybi.jp-east.idcfcloud.com', /* エンドポイントの指定 */
    database: 'js_sdk_db', /* データベースの指定 */
    writeKey: 'xxxxxxx09d147de381c3fd23c47035132dxxxxxxx' /* WriteOnly API-Keyの指定 */
  });
  td.trackPageview('js_sdk_table'); /* データの送信 */
  console.log(user)
</script> 
<!-- TD JS SDK End -->
</body>
</html>
```

Case-1からの差分のみ説明すると、データ取得部分とデータ送信部分が`td.trackPageview('js_sdk_table')`のみとなりました。
これが秀逸で以下の情報を自動で取得して送ってくれます。

* td_version - td-js-sdk's version
* td_client_id - client's uuid
* td_charset - character set
* td_language - browser language
* td_color - screen color depth
* td_screen - screen resolution
* td_viewport - viewport size
* td_title - document title
* td_url - document url
* td_host - document host
* td_path - document pathname
* td_referrer - document referrer
* td_ip - request IP (server)
* td_browser - client browser (server)
* td_browser_version - client browser version(server)
* td_os - client operating system (server)
* td_os_version - client operating system version(server)

`td_client_id`は`TreasureData JavaScript SDK`がCookie上で管理するIDでCookieが有効な限り一意にユーザーが使用しているクライアントツールを識別可能となります。

### Step4-Case-3: Case1 + Case2の情報の送付
以下ソースとなります。

```file:td_sample_case3.html
<!doctype html>
<!--[if lt IE 9]><html class="ie8" lang="ja"><![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--><html lang="ja"><!--<![endif]-->
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="format-detection" content="telephone=no">
  <meta name="description" content="TD JS SDK Test">
  <title>TD Javascript Sample</title>
  <script type="text/javascript">
    !function(t,e){if(void 0===e[t]){e[t]=function(){e[t].clients.push(this),this._init=[Array.prototype.slice.call(arguments)]},e[t].clients=[];for(var r=function(t){return function(){return this["_"+t]=this["_"+t]||[],this["_"+t].push(Array.prototype.slice.call(arguments)),this}},s=["addRecord","set","trackEvent","trackPageview","ready"],n=0;n<s.length;n++){var i=s[n];e[t].prototype[i]=r(i)}var a=document.createElement("script");a.type="text/javascript",a.async=!0,a.src=("https:"===document.location.protocol?"https:":"http:")+"//s3.amazonaws.com/td-cdn/sdk/td-1.2.0.js";var c=document.getElementsByTagName("script")[0];c.parentNode.insertBefore(a,c)}}("Treasure",this); /* JavaScript SDK の読み込み*/
  </script>
</head>
<body data-category="top">
  <div id="user_info">
    <div id="user_mail">
    hogehoge@example.com
    </div>
    <div id="user_name">
    hogehoge
    </div>
  </div>
<!-- TD JS SDK Start -->
<script type="text/javascript">
  /* TreasureData Instance 作成 */
  var td = new Treasure({
    host: 'mobile-ybi.jp-east.idcfcloud.com', /* エンドポイントの指定 */
    database: 'js_sdk_db', /* データベースの指定 */
    writeKey: 'xxxxxxx09d147de381c3fd23c47035132dxxxxxxx' /* WriteOnly API-Keyの指定 */
  });
  /* Get Data */
  var user_mail = document.getElementById('user_mail');
  var user_name = document.getElementById('user_name');
  var user = {
    id: user_mail.innerText,
    name: user_name.innerText,
  } /* データの設定 */
  td.trackEvent('js_sdk_table', user); /* データの送信 */
  console.log(user)
</script> 
<!-- TD JS SDK End -->
</body>
</html>
```

## Step5: ページロード
Step4で作成したHTMLファイルにブラウザ経由でそれぞれアクセスしてみます。

![js_td_sample_case1.png](https://qiita-image-store.s3.amazonaws.com/0/46472/15d8d052-c474-054c-edd7-4d5e8fab1fc7.png "js_td_sample_case1.png")

![js_td_sample_case2.png](https://qiita-image-store.s3.amazonaws.com/0/46472/cca532ee-080d-95d2-9772-8575c9c7d198.png "js_td_sample_case2.png")

![js_td_sample_case3.png](https://qiita-image-store.s3.amazonaws.com/0/46472/3306c40d-9895-651f-11ae-830a7060eac3.png "js_td_sample_case3.png")


## Step6: データアップロードの確認
以下ページロード後のjs_sdk_db.js_sdk_tableの全件検索結果となります。
TreasureData社が提供するCLIで取得しております。

3件データが入っていて、addRecordについてはidとnameカラムしかなくtrackPageviewについては、idとname以外のカラムがあり、trackEventは全カラムのデータが入っていることがわかります。

td_client_idにUUIDが格納されており、trackPageviewとtrackEventで値が変わらないこと、各項目を自動でデータ取得していることがわかります。

そして3Caseでカラムが全て異なるデータをアップロードさせたのですが、同じテーブルに自動的に値が補完されてデータが格納されています。
ここもTreasureDataの素晴らしい点です。

```output:query_result
$ td query -w -t presto -d js_sdk_db "SELECT * FROM js_sdk_table"
...省略...
+----------------------+------------+----------+-----------------------+----------------+------------+--------------------------------------+---------------+--------------------+-------------+------------+----------+-----------+-------------+----------------------------------------------+-----------------+-------------+----------------------+----------+------------+
| td_title             | td_browser | td_color | td_path               | td_ip          | td_version | td_client_id                         | td_os_version | td_browser_version | td_viewport | td_charset | td_os    | td_screen | td_referrer | td_url                                       | td_host         | td_language | id                   | name     | time       |
+----------------------+------------+----------+-----------------------+----------------+------------+--------------------------------------+---------------+--------------------+-------------+------------+----------+-----------+-------------+----------------------------------------------+-----------------+-------------+----------------------+----------+------------+
| null                 | null       | null     | null                  | null           | null       | null                                 | null          | null               | null        | null       | null     | null      | null        | null                                         | null            | null        | hogehoge@example.com | hogehoge | 1413427101 |
| TD Javascript Sample | Chrome     | 24-bit   | /td_sample_case3.html | xxx.xxx.xxx.xxx | null       | c19af39f-9823-4f4f-8ff9-58f1fd3d42b1 | 10.9.5        | 38.0.2125          | 1293x401    | utf-8      | Mac OS X | 1366x768  |             | https://xxxx:40443/td_sample_case3.html | xxxx:40443 | ja          | hogehoge@example.com | hogehoge | 1413427112 |
| TD Javascript Sample | Chrome     | 24-bit   | /td_sample_case2.html | xxx.xxx.xxx.xxx | 1.2.0      | c19af39f-9823-4f4f-8ff9-58f1fd3d42b1 | 10.9.5        | 38.0.2125          | 1293x401    | utf-8      | Mac OS X | 1366x768  |             | https://xxxx:40443/td_sample_case2.html | xxxx:40443 | ja          | null                 | null     | 1413426996 |
+----------------------+------------+----------+-----------------------+----------------+------------+--------------------------------------+---------------+--------------------+-------------+------------+----------+-----------+-------------+----------------------------------------------+-----------------+-------------+----------------------+----------+------------+
3 rows in set
$
```


## おわりに
ソース自体は
[GitHub](https://github.com/treasure-data/td-js-sdk GitHub)にありますので、より詳細な内容を知りたい場合は参照してください。