Zaim」タグアーカイブ

Zaim.jsをAPI ver2.xが使えるように改良してみた

前提

  • NodeによるZaimAPIの利用 の続き
  • 内部を書き換えるだけなので、基本的な使い方は上記記事と同様
  • 元のモジュール(Zaim.js)がMITライセンスなのでそれに準ずる

概要

npmでインストールできる、zaim.jsは、Zaim API ver1を前提としているため、ver2の機能を利用することができない。
そこで、zaim.jsのソースコードをベースに、API ver2を利用できるように改変する。

OAuth用URLの差し替え

OAuthで認証してzaimオブジェクトを作成する部分の、認証用URLをver2のURLに差し替え

変更前

this.client = new oauth.OAuth(
  'https://api.zaim.net/v1/auth/request',
  'https://api.zaim.net/v1/auth/access',
  this.consumerKey,
  this.consumerSecret,
  '1.0',
  this.callback,
  "HMAC-SHA1"
);

変更後

this.client = new oauth.OAuth(
  'https://api.zaim.net/v2/auth/request',
  'https://api.zaim.net/v2/auth/access',
  this.consumerKey,
  this.consumerSecret,
  '1.0',
  this.callback,
  "HMAC-SHA1"
);

リクエストトークン取得用のURLを差し替える

変更前

this.client.getOAuthRequestToken(function(err, token, secret) {
  that.token = token;
  that.secret = secret;
  callback('https://www.zaim.net/users/auth?oauth_token=' + that.token);
});

変更後

this.client.getOAuthRequestToken(function(err, token, secret) {
  that.token = token;
  that.secret = secret;
  callback('https://auth.zaim.net/users/auth?oauth_token=' + that.token);
});

入力データ取得用APIのURLを差し替える

ver1ではPOSTだったが、ver2ではGETになるため、それについても書き換える
変更前

Zaim.prototype.getMoney = function(params, callback) {
  var url = "https://api.zaim.net/v1/money/index.json";
  if (arguments.length === 1) {
    callback = params;
    params = {};
  }
  this._httpPost(url, params, callback);
};

変更後

Zaim.prototype.getMoney = function(params, callback) {
  var url = "https://api.zaim.net/v2/home/money";
  if (arguments.length === 1) {
    callback = params;
    params = {};
  }
  this._httpGet(url, params, callback);
};

httpGetメソッドで、パラメータを付与できるように改変する

オリジナルのhttpGetメソッドは、パラメータの付与に対応していなかったので、対応できるように修正する
変更前

Zaim.prototype._httpGet = function(url, callback) {
  if (!this.token || !this.secret) {
    throw new Error("accessToken and tokenSecret must be configured.");
  }
  this.client.get(url, this.token, this.secret, function(err, data) {
    if (err) {
      throw err;
    } else {
      callback(typeof data === 'string' ? JSON.parse(data) : data);
    }
  });
};

変更後

Zaim.prototype._httpGet = function(url, params , callback) {
  url += '?';
  Object.keys(params).forEach(function(key) {
    url += key + '=' + params[key] + '&';
  });
  if (!this.token || !this.secret) {
    throw new Error("accessToken and tokenSecret must be configured.");
  }
  this.client.get(url, this.token, this.secret, function(err, data) {
    if (err) {
      throw err;
    } else {
      callback(typeof data === 'string' ? JSON.parse(data) : data);
    }
  });
};

Zaim API ver2特有の機能を使ってみる

ここまでで、getMoneyメソッドに関してはver2のAPIを呼び出せるようになったので、ver2でしか利用できない機能を使ってみる。
下記コードは、2017年にAmazonで購入した商品の一覧を取得する。

ソースコード

zaim.getMoney({
  place: 'Amazon',
  start_date: '2017-01-01'
} , function(data) {
  console.log(data.money.map(function(m) {
    return [m.date , m.place , m.amount , m.comment];
  }));
});

実行結果

$ node zaim.js
[ [ '2017-02-12', 'Amazon', 1976, 'コーディングを支える技術' ],
  [ '2017-02-04', 'amazon', 2597, 'かじり木、チモシー、ペレット、消臭、砂' ],
  [ '2017-02-04', 'Amazon', 702, 'リンゴ酢' ],
  [ '2017-02-01', 'Amazon', 980, 'Kindle Unlimited 201702' ],
  [ '2017-01-14', 'Amazon', 1734, '野菜ジュース12本セット' ],
  [ '2017-01-09', 'Amazon', 258, '応用情報技術者の本中古' ],
  [ '2017-01-04', 'Amazon', 2880, 'データベーススペシャリスト教科書' ],
  [ '2017-01-01', 'Amazon', 18820, 'FIRE HDとそのカバーとその保証' ],
  [ '2017-01-01', 'Amazon', 980, 'Kindle Unlimited 201701' ] ]
$

購入店舗に関する情報はver2から追加された機能で、ver1ではできなかった、店舗によるフィルタリングができたことがわかる。また、ver1では支出額は負数だったが、ver2では収支に関わらず正数となっている。

また、上記実行結果には関係ないが、ver1では最大取得件数が100件だったのに対し、ver2では無制限となっており汎用性も高まっている。

他のメソッドについて

同様に他のメソッドについても、APIのURLをver1のURLからver2のURLに差し替えることで使用可能となるが、
個人的にgetMoneyメソッドさえ使えれば今は困らないのでコレ以上の改変は必要に応じて行うことにする。

参考

NodeによるZaimAPIの利用 と同様

NodeによるZaimAPIの利用

本記事で使用したZaim.jsは、最終更新が2013年で、最新のAPIを利用することができません。そのため、Zaim.jsのソースコードを直接編集し、最新のAPIを利用できるように書き換えたものを利用しています。

書き換えについては、Zaim.jsをAPI ver2.xが使えるように改良してみたをご参考ください

前提

  • node/npmが使える状態
  • Zaimのアカウントを保有しており、最低限の利用記録がある状態
  • Zaim API用のカスタマーキー、アクセストークンを何らかの手段(OAuth)で取得している状態

かなり限定的な状態が対象なので限りなく個人備忘録用

概要

クラウド型の家計簿サービスであるZaimを、Node上でAPI経由で読み書きする。
本記事ではZaim API用のカスタマーキー及びアクセストークンを取得済みで、APIを利用できる状態にあることを前提とする

Zaimとは

Zaimは、おそらく国内シェアナンバー1のクラウド型家計簿サービスであり、Web/iOS/Androidそれぞれから利用することができる。他の家計簿ソフトと同様に、会計簿の記入、集計、検索、予算管理など、家計簿サービスとしての基本的な機能を備えている他、以下の特徴的な機能を持っている。

  • レシートを撮影することで全自動で入力が行われる。精度はお察し
  • 各金融機関と連携し、入出金を自動入力。金融機関の認証情報を民間企業に渡すとかどうなんだろ
  • 年末調整とかそれなりに自動でやってくれる。正確に家計簿を記入していないと無意味

などと特徴的な機能はあんまり使いものにならないので、私は普通に家計簿の入出力にしか使っていない。(※上記は私的意見です)

Zaim API とは

OAuthにてZaimのアカウントの認証を受け、API経由で家計簿のCRUDを行うことができる。

Zaim APIはRESTFULLに実装されているので、そのまま利用することも簡単であるが、今回はZaim APIをラッピングしたNodeモジュールであるZaim.jsを利用する。

Zaim.jsのインストール

Nodeモジュールなのでnpmを用いてインストール

npm install zaim -D

Zaimオブジェクトの作成

なんらかの手段で取得したカスタマーキーとアクセスキーを指定して、Zaimオブジェクトを作成する

var Zaim = require('zaim');

var zaim = new Zaim({
  consumerKey: 'hogehoge',
  consumerSecret: 'fugafuga',
  accessToken: 'foofoo',
  accessTokenSecret: 'barbar',
});

とりあえず入力履歴を取得

getMoneyメソッドで入力履歴を取得。デフォルトでは最新20件を取得するので、とりあえず2/17の記録を全て取得する。
ちょっと恥ずかしいが、実行結果は生データ。

ソースコード

zaim.getMoney({
  start_date: '2017-02-17',
  end_date: '2017-02-17'
} , function(data , err) {
  console.log(data.money);
});

実行結果

$ node zaim.js
[ { id: 1581817347,
    user_id: 3061609,
    date: '2017-02-17',
    category_id: '101',
    genre_id: '10105',
    comment: 'サラダ、ドレッシング、卵とじ丼',
    name: '',
    active: 1,
    created: '2017-02-17 19:43:22',
    currency_code: 'JPY',
    type: 'pay',
    price: '-341' },
  { id: 1581291695,
    user_id: 3061609,
    date: '2017-02-17',
    category_id: '101',
    genre_id: '10104',
    comment: '月見大盛り',
    name: '',
    active: 1,
    created: '2017-02-17 14:06:50',
    currency_code: 'JPY',
    type: 'pay',
    price: '-350' } ]

入力データの構成

前項では、2/17の記録2件の入力データを取得した。入力データはオブジェクト形式で取得でき、以下の構成になっている。

キー 内容
id 入力ID(ユニーク)
user_id ユーザID(ユニーク)
date 記録日時
category_id カテゴリ(食費/日用雑貨などの大分類)のID
genre_id ジャンル(朝食/昼食/夕食などの小分類)のID
comment 記録に対する自由記入欄(購入したモノなどを記入する)
name 不明(外部連携とかで使う??)
active 多分論理削除すると0になる
created データの登録日
currency_code お金の種類
type 支出(pay) or 収入(income)
price 金額(支出の場合負数)

特定の入力データを取得する

ここでは、2016年に「ゲーム」で使った金額の一覧を取得する

ジャンル一覧を取得

Zaimでは、「ゲーム」は、「エンターテイメント」カテゴリに属するジャンルとしてデフォルトで登録されている。
Zaim.jsでは、genre_idで指定する必要があるので、「ゲーム」のジャンルIDがいくつなのかを調べるために、以下のコードで支出のジャンル一覧を取得する。

ソースコード

zaim.getPayGenres({
  lang: 'ja',
} , function(data) {
  console.log(data);

実行結果

$ node zaim.js
{ genres:
   [ { id: 10101, category_id: 101, title: '食料品' },
     { id: 10102, category_id: 101, title: 'カフェ' },
     { id: 10103, category_id: 101, title: '朝ご飯' },
     { id: 10104, category_id: 101, title: '昼ご飯' },
     { id: 10105, category_id: 101, title: '晩ご飯' },
     { id: 10199, category_id: 101, title: 'その他' },
(中略)
     { id: 9047786, category_id: 108, title: 'ゲーム' },
(以下省略)

ゲームの支出履歴を取得

「ゲーム」のジャンルIDが9047786であることがわかったので、これを指定して2016年のゲームの支出一覧を取得する。
全部出力してしまうと長いので、価格とコメントのみmapして出力する。

ソースコード

zaim.getMoney({
  start_date: '2016-01-01',
  end_date: '2016-12-31',
  genre_id: '9047786',
} , function(data , err) {
  console.log(data.money.map(function(m) { return [m.price , m.comment]}));
});

実行結果

$ node zaim.js
[ [ '-1080', '桃鉄' ],
  [ '-1200', 'ポケモンGO' ],
  [ '-1200', 'ポケモンGO' ],
  [ '-1200', 'ポケモンGO' ],
  [ '-600', 'ポケモンGO' ],
  [ '-600', 'ポケモンGO' ],
  [ '-600', 'ポケモンGO' ],
  [ '-950', 'ポケモン空の探検隊' ],
  [ '-706', 'マジカルバケーション' ] ]

ポケモンGOにほどよく課金していたのがわかる。

参考