【GAS】Zaimのデータを取得してまとめたい！

## なぜGASとZaimを連携するか

筆者は基本スマホのウィジェットを使ってぱっと見で「今これぐらい使ってるからもう少し節約しよう」とか考えたいなと思ってます。そこで何個か家計簿アプリを入れて個人的に一番見やすかったのがZaimでした。

日々Zaimに記録したデータをウィジェットだけで使うのも勿体無いと思ったので、スプレッドシートと連携してグラフ化して見やすくしたいなと考え、今回ZaimとGASを連携しようと思いました。

## 事前準備

### 1, GASでライブラリを入れる

1. 以下URLのREADME、Setupにあるトークンをコピー
    
https://github.com/googleworkspace/apps-script-oauth1

2. スプレッドシートからApps Scriptを開く
3. 左のバーにあるライブラリの右側にある「＋」ボタンを押下
4. コピーしたトークンを「スクリプトID」にペーストして検索ボタンを押下
5. 「追加」ボタンを押下

### 2, GASでデプロイする

1. Apps Scriptを開く
2. 右上の青い「デプロイ」ボタンを押下
3. 以下該当箇所を入力する
    - 説明：なんでもOKです。（わかりやすいものがいいと思います。今回は「Zaim連携用」とします。）
    - ウェブアプリ：自分（メールアドレス）
    - アクセスできるユーザー：今回は「自分のみ」にします。
4. デプロイを押下して、デプロイIDとウェブアプリのURLを取得します。

### 3, Zaim APIの取得

1. 以下URLからZaim Developerにログイン
    
https://dev.zaim.net/
    
2. マイページの「新しいアプリケーションを追加」を押下
3. 以下該当箇所を入力する
    - 名称：なんでもOKです。（今回は「GAS連携」とします。）
    - サービス種：ブラウザアプリ
    - 概要：こちらもなんでもOK（今回は「GAS用API」とします。）
    - 組織：個人
    - サービスのURL：「1, GASでデプロイする」で取得したウェブアプリのURL
    - アクセスレベル：今回は「家計簿の記録を読み込む」「家計簿へのアクセスを永続的に許可する」にチェックを入れます
    - アイコン画像：今回は設定しません

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2918071/54226d94-bb8c-70e4-bec3-ab6717e0fffe.png)

4. 保存ボタンを押下する
5. 以下の値をこの後使用します
    - コンシューマID
    - コンシューマシークレット
    - リクエストトークン取得URL
    - 認証URL
    - アクセストークン取得URL

## GASでのスクリプト作成手順

:::note info
以下のコードは今月のデータの日付、カテゴリID、金額を取得するコードとなります。
都度取得したいデータに合わせて変更してください。
:::

```javascript
var CONSUMER_KEY = ''; // ''間にコンシューマーIDを追記
var CONSUMER_SECRET = ''; // ''間にコンシューマーシークレットを追記

/**
 * Authorizes and makes a request to the Twitter API.
 */
function run() {
  var service = getService_();
  if (service.hasAccess()) {
    var url = 'https://api.zaim.net/v2/home/money';
    var response = service.fetch(url, {
      method: 'get'
    });
    var result = JSON.parse(response.getContentText());
    if (result && result.money) {
      clear(); // 一旦シート値を削除
      writeToSpreadsheet(result.money); // JSONデータをスプレッドシートに書き込む関数を呼び出す
    }
  } else {
    var authorizationUrl = service.authorize();
    Logger.log('Open the following URL and re-run the script: %s',
        authorizationUrl);
  }
} 

function clear() {
  var sheet = SpreadsheetApp.getActiveSheet(); // 現在のシートを取得
  var range = sheet.getRange("A2:C100");
  range.clearContent();
}

// JSONデータをスプレッドシートに書き込む関数
function writeToSpreadsheet(datas) {
  var sheet = SpreadsheetApp.getActiveSheet(); // 現在のシートを取得
  var headers = ['date','category_id','amount']; // ヘッダー行（ここは取得したいデータに合わせて変更してください）
  var today = new Date(); // 今日の日付を取得
  var b_month = new Date(today.getFullYear(), today.getMonth(), 1); // 月初を取得
  var b_month_str = Utilities.formatDate(b_month, 'JST', 'yyyy-MM-dd'); // フォーマット整形
  for(let data of datas) {
    var row = [];
    if(data['date'] < b_month_str) break; // 今月のデータのみ入力
    for(let header of headers) {
      row.push(data[header]);
    }
    sheet.appendRow(row); // データ行を追加
  }
}

/**
 * Reset the authorization state, so that it can be re-tested.
 */
function reset() {
  var service = getService_();
  service.reset();
}

/**
 * Configures the service.
 */
function getService_() {
  return OAuth1.createService('Zaim')
      // Set the endpoint URLs.
      .setAccessTokenUrl('') // ''間にアクセストークン取得URLを追記
      .setRequestTokenUrl('') // ''間にリクエストトークン取得URLを追記
      .setAuthorizationUrl('') // ''間に認証URLを追記

      // Set the consumer key and secret.
      .setConsumerKey(CONSUMER_KEY)
      .setConsumerSecret(CONSUMER_SECRET)

      // Set the name of the callback function in the script referenced
      // above that should be invoked to complete the OAuth flow.
      .setCallbackFunction('authCallback')
  
      // Using a cache will reduce the need to read from 
      // the property store and may increase performance.
      .setCache(CacheService.getUserCache())

      // Set the property store where authorized tokens should be persisted.
      .setPropertyStore(PropertiesService.getUserProperties());
}

/**
 * Handles the OAuth callback.
 */
function authCallback(request) {
  var service = getService_();
  var authorized = service.handleCallback(request);
  if (authorized) {
    return HtmlService.createHtmlOutput('Success!');
  } else {
    return HtmlService.createHtmlOutput('Denied');
  }
}
```

### 挙動確認
1. Apps Scriptの実行ボタンを押下。
2. 実行すると「Open the following URL and re-run the script: https://~」とメッセージ表示されるので、URLをコピー。
3. 新しくブラウザを開いて、URLを打ち込む。
4. 「ログインして許可する」ボタンを押下する。
5. 「Success!」と表示されればOKです。
6. GASの戻って再度実行すると取得できると思います。

## 活用アイディア

- 定期的なレポートをメールに送信する
    - 今は1週間ごとにスプシを確認していますが、それをメールで確認できたらもっと楽なのでは、、？
- 家族やパートナーと共有する
- 今回はZaimからデータを取得するのみでしたが、前回（[記事はこちら](https://qiita.com/minori_no_gallery/items/ac5458a0e368aa189fb2)）みたいにメールから取得したクレカの金額データをGAS経由でZaimに送信して、自動で登録するとかもいいかもしれません。（Zaimのウィジェットは個人的に使いやすいので）

## 最後に
今回はZaimとの連携が少し難しかったなと感じました。
接続できればもうボタンひとつで取得できるので、家計簿管理がとても楽になりました！
もっとシンプルにできるとか、こういう時はどうすればいい？等ございましたら、コメントお願いします！
良ければいいねもお願いします！

## 参考文献
以下サイトを参考にしました。ありがとうございます。

https://zenn.dev/kabupen/articles/26e3d6b2ae897e

https://note.com/shibainu00007_/n/n0864fcb465f2