はじめに
詳細な家計簿をつけるのは億劫だけど、資産の増減くらいは最低限把握しておきたいところ。
そこで大まかな資産推移を捕捉するために、勉強がてら LINE Messaging API と GoogleAppsScript、
Google ドキュメントのOCR機能を使用して家計のスナップショットを可視化してみました。
愛用しているマネーフォワードMEの資産残高画面のスクリーンショットを撮影・bot に投稿することで
以下のような資産推移グラフを自動で作成します。
処理の流れ
- マネーフォワードMEの資産残高のスクリーンショットを撮影し、LINE botに投稿
- GAS を hook し、投稿画像を Drive に保存
- Google ドキュメント の OCR 機能を使用し、画像から残高部分を抜粋
- 加工して Spreadsheet に転記
- グラフを作成、その画像URLを LINE bot にて返信
という感じです。2.〜 5. の部分を GAS で自動化しています。
Google ドキュメントの OCR の精度がかなり良いため、特に苦労なく求めていた機能を実現できました。
事前準備
LINEデベロッパーへの登録やGoogle アカウントでの認証が必要になります。以下の記事などを参考にしました。
GASのなかで Drive API を呼び出す必要があるので、有効化しておきましょう。
また投稿した画像やグラフ画像の保存用にDrive上に専用フォルダを作成しておくと便利です。
このとき作成したフォルダのURL末尾の部分がコード中で使用するフォルダのIDとなります。
なお作成した画像などは都度削除しているので、このフォルダにデータが蓄積されることはありません。
コード
var CHANNEL_ACCESS_TOKEN = "YOUR_ACCESS_TOKEN";
var spreadsheet = SpreadsheetApp.openById("YOUR_SPREADSHEET_ID");
var sheet = spreadsheet.getActiveSheet();
function doPost(e) {
var events = JSON.parse(e.postData.contents).events;
var url =
"https://api.line.me/v2/bot/message/" + events[0].message.id + "/content/";
var image = getImage(url).getBlob();
var fileName = Utilities.formatDate(new Date(), "Asia/Tokyo", "YYYY-MM-dd");
var requestBody = {
title: fileName,
mimeType: "image/jpeg",
parents: [{ id: "YOUR_FOLDER_ID" }]
};
// 投稿画像をもとにOCRにかけたドキュメントファイルを作成
Drive.Files.insert(requestBody, image, { ocr: true });
var folder = DriveApp.getFolderById("YOUR_FOLDER_ID");
var doc = folder.getFilesByType("application/vnd.google-apps.document").next();
var docId = doc.getId();
var lines = DocumentApp.openById(docId).getBody().getText().split("\n");
// 残高部分のみ抜粋
var text = [];
lines.forEach(function(l) {
if (l.match(/¥[1-9]/)) text.push([l.slice(1)]);
});
folder.removeFile(doc);
// 既に記録がある列の隣に記録
for (var i = 1; ; i++) {
if (sheet.getRange(1, i).getValue() != "") continue;
sheet.getRange(1, i, 1, 1).setValue(fileName);
sheet.getRange(2, i, text.length, 1).setValues(text);
break;
}
// グラフ部分の画像URLを取得
var graphImg = sheet.getCharts()[0].getBlob();
folder.createFile(graphImg).setName(fileName);
var img = folder.getFiles().next();
var imgUrl = img.getUrl();
folder.removeFile(img);
reply(events[0], imgUrl);
}
function getImage(url) {
return UrlFetchApp.fetch(url, {
headers: {
"Content-Type": "application/json; charset=UTF-8",
Authorization: "Bearer " + CHANNEL_ACCESS_TOKEN
},
method: "GET"
});
}
function reply(e, url) {
var message = {
replyToken: e.replyToken,
messages: [
{
type: "text",
text: url
}
]
};
var replyData = {
method: "post",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + CHANNEL_ACCESS_TOKEN
},
payload: JSON.stringify(message)
};
UrlFetchApp.fetch("https://api.line.me/v2/bot/message/reply", replyData);
}
まとめ
LINE bot + GAS の組み合わせはちょっとしたツールを作るのに最高ですね。
今回初めて使用した OCR もかなりの精度で、発想次第でもっといろいろ面白いことできそう。
スクショの撮影・投稿も毎月○日に自動実行、できれば理想なんだけど、いい方法ないかなぁ。