Titanium+ACSの組み合わせで、社内向けに位置情報活用したアプリを何故か作ってます^^;
データの集計処理のような機能はACS標準には無く、例えば
「会社別に毎週何回チェックインされたか」
というような集計処理は自作する必要があります。
幸いと言っていいのかわかりませんが、ACSには、REST APIがあるので、それをうまく使うことで簡単に処理が出来そうです。
事前準備
HTTP Client的なモジュールを使って、REST APIを叩く・・・のはちょっと面倒な感じがしたのでちょっと調べた所、開発元のAppceleratorがacs-nodeというNode.jsからACSを利用しやすくするモジュールを開発されていました。
これを使うことで、TitaniumでACSを利用する時と同じようなコードで、Node.jsからもACSにアクセス出来るようになります。
acs-nodeは、npm 経由でインストール可能です。
グローバルな領域にインストールするのがちょっと嫌なので、現在開発中のプロジェクトのルートディレクトリ上で
npm init
を実行して、package.jsonを作成して、このプロジェクト内で必要なモジュールを適宜導入するようにしてます。詳しくはnpmでnode.jsのpackageを管理するあたりが参考になるかと重います。
package.jsonを作成した後にacs-nodeをインストールします。あと、データの抽出処理をする際に、今週の月曜日から金曜日までみたいな感じの日付処理をやるケースが多く、日付処理は面倒なので、moment.jsも利用したいのでついでにそれもインストールします
npm install acs-node --save-dev npm install moment --save-dev
Noe.jsからacs-node使う
使い方はとても簡単で、
- acs-nodeを読み込む
- ACS利用時のDevelopmentKey、もしくはProductionKeyを指定して初期化する
これだけです。
ACS利用時のDevelopmentKey、もしくはProductionKey、ユーザID,パスワードをソースコード内に埋め込みたくなかったので、それら設定情報は、apiKey.jsonにすべてまとめてるので少しコードが長いですが、CoffeeScriptのサンプルコードはこんな感じになります
ACS = require('acs-node') fs = require('fs') path = require("path") file = fs.readFileSync(path.resolve(__dirname, "apiKey.json")) json = JSON.parse(file.toString()) apiKey = json.apiKey.development loginID = json.login loginPasswd = json.password ACS.init(apiKey);
apiKey.jsonはこんな感じです
{ "apiKey":{ "development":"KEY", "production":"KEY" }, "login":"username", "password":"password" }
ACSにアクセスしてデータ抽出する
TitaniumでACSを利用したことがある人だと、acs-nodeにある以下のJavaScriptのサンプルコードは、違和感ないかと思います
var ACS = require('acs-node'); ACS.initACS('<App Key>'); function login(req, res) { var data = { login: req.body.username, password: req.body.password }; ACS.Users.login(data, function(data){ if(data.success) { console.log("Successful to login."); console.log("UserInfo: " + JSON.stringify(data.users[0], null, 2)) } else { console.log("Error to login: " + data.message); } }, req, res); }
これを応用して、「今週月曜日から金曜日までのチェックイン情報を抽出する」みたいなコードを考えてみました。
今週月曜日とか、今週金曜日とかは、素のJavaScriptでどうにかするのがつらいですが、前述のmoment.jsを使うことで
thisMonday = moment().day(1).hours(0).minutes(0).seconds(0).milliseconds(0) thisFriday = moment().day(5).hours(23).minutes(59).seconds(59).milliseconds(0)
という形で書けます。この状態ですと、出力される形式が日本時間にならないので、format()にて、出力形式を指定することでより見やすくなります。
具体的には
thisMonday = moment().day(1).hours(0).minutes(0).seconds(0).milliseconds(0).format("YYYY-MM-DDTHH:mm:ssZ") thisFriday = moment().day(5).hours(23).minutes(59).seconds(59).milliseconds(0).format("YYYY-MM-DDTHH:mm:ssZ")
という感じです。詳しいことは、JavaScriptで日付を扱うならこれ!「moment.js」がとても参考になると思います。
最終的には、このようなコードになります。
moment = require("moment") ACS = require('acs-node') fs = require('fs') _ = require("underscore") path = require("path") file = fs.readFileSync(path.resolve(__dirname, "apiKey.json")) json = JSON.parse(file.toString()) apiKey = json.apiKey.development loginID = json.login loginPasswd = json.password ACS.init(apiKey); thisMonday = moment().day(1).hours(0).minutes(0).seconds(0).milliseconds(0).format("YYYY-MM-DDTHH:mm:ssZ") thisFriday = moment().day(5).hours(23).minutes(59).seconds(59).milliseconds(0).format("YYYY-MM-DDTHH:mm:ssZ") data = login: loginID password: loginPasswd ACS.Users.login data, (response) -> console.log response result = [] if response.success ACS.Checkins.query page: 1 per_page: 50 where: updated_at: "$gt":thisMonday "$lt":thisFriday , (e) -> if e.success for checkin in e.checkins console.log("id:#{checkin.id} name: #{checkin.place.name} date: #{moment(checkin.updated_at).format('YYYY-MM-DD HH:mm:ss')}") else console.log "Error:\n" + ((e.error and e.message) or JSON.stringify(e)) else console.log "Error to login: " + response.message