概要
- LINE Developersに登録してBotを作成
- Google spread sheetを作ってGASでコーディング
→毎月計算していた共用分の家計計算を楽にしてみた
最後にGitHub Gistのリンクを添付しています。
はじめに
もともと共用の食費や日用品の支払いを、家計管理せめて残しておこうという意図で、それ用に作ったLINEグループにアルバムとして追加し、毎月月末に締めて精算を行っていました。
ある日仕事終わりに上司と話しているときにGASの話になり、そういえばGAS使ってなんかできないかなあと思って調べてみたところ、お手軽にできそうだったのでやってみたメモになります。(Qiita投稿していなかったのでそれも兼ねて...)
実現したいこと
毎月の共用支払いを以下のようにアナログ管理していました。
①支払いのレシートや明細ページを、LINEアルバムを毎月作成して追加する
②月末に電卓を使って合計金額を算出して、多い方から少ない方へ振込
...アナログです
実際のお金のやり取りはしょうがないとして、精算を毎月時間をとってやることをなくせれば、という感じです。
そこで
- 現在使っているLINEグループをそのまま使う
- 金額を自動で計算したい
を主軸に進めました。
レシートをアルバムに添付するのは、証拠を残すために継続するようにし、ミニマムな機能が一旦作れればよいかなという考えです。
機能
- 金額の登録
- 合計金額の表示
LINE BOTの準備
LINE Developersに登録します。
登録からBot準備は非常に簡単でした。参考にさせていただいたサイトは1番最後にまとめて載せさせていただいています。
今回ポイントとしてはLINEグループに追加したかったので、下記部分の変更が必要でした。
Messaging API設定からBotの「グループ・複数人チャットへの参加を許可する」という項目があるので、右側の編集をクリック。
LINE Official Account Managerのアカウント設定が開くので、
機能の利用>チャットへの参加の部分で「グループ・複数人チャットへの参加を許可する」を選択。
これでグループ追加が可能になります。
GASで実装
メインの処理: doPost()
spreadsheetへの登録: record()
メッセージ返却: doReply()
の3つで分けました。
(分岐部分とかきれいに分けたいところでしたが、GASのあるべき書き方が分かっておらず...)
メインの処理
const ACCESS_TOKEN = ''; // LINE botのチャネルアクセストークンを設定
const URL = 'https://api.line.me/v2/bot/message/reply'; // 応答メッセージ用のAPI URL
const DATA_SHEET = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('foo'); // 保存sheetのID
const SUM_SHEET = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('bar'); // サマリsheetのID
const USER = {'id1': 'なまえ1', 'id2': 'なまえ2'};
function doPost(e) {
const json = JSON.parse(e.postData.contents);
const replyToken = json.events[0].replyToken;
if (typeof replyToken === 'undefined') {
return;
}
// ユーザID取得
const userId = json.events[0].source.userId;
// ここで特定ユーザでなければ登録せずに返却する
let postMessage = '';
if (USER[userId] === undefined) {
postMessage = 'このユーザからの登録はできません。';
return doReply(postMessage, replyToken);
}
// メッセージ取得
const userMessage = json.events[0].message.text;
// 内容を各変数に保持
const messages = userMessage.split(/\r\n|\n/);
const param = messages[0];
/**
* 以下パラメータによって各種処理に分岐
* ・へるぷ || help || ヘルプ
* ・yyyy/MM
* ・金額(+備考)
*/
if (param.match(/[help|へるぷ|ヘルプ]/)) {
// ヘルプ表示
postMessage = '以下が実行できます。\n==========\n';
postMessage += '①登録:1行目に金額を入力します。改行して備考を併せて登録可能です。\n{金額}\n{備考}\n----------\n';
postMessage += '②金額確認:1行目に金額を確認したい年月をyyyy/MMで入力します。\n(例)2021/04\n==========';
} else if (param.match(/[0-9]{4}\/[0-2]{2}/)) {
// 合計額の取得
postMessage = getAmount(param);
} else if (param.match(/[0-9]+/)) {
// 登録
const cost = parseInt(param);
const etc = messages[1];
const date = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd');
if (Number.isNaN(cost) === false) {
postMessage = record(userId, cost, etc, date);
} else {
postMessage = `金額\n備考(任意)\nで入力してください。`;
}
} else {
postMessage = '入力が正しくありません。\n「help」や「へるぷ」、「ヘルプ」を送ることで、何ができるか確認できます。'
}
return doReply(postMessage, replyToken);
}
メッセージ送信者を判断するために、json.events[0].source.userId
でpostDataからuserIdを取得しています。
予めこれを持っておいて、spreadsheet入力の名前として利用しています。
spreadsheetへの登録
function record(userId, cost, etc, date)
{
const newRow = DATA_SHEET.getLastRow() + 1;
let etcMessage = !etc === false ? etc : 'なし';
let replyMessage = `日付: ${date}\n金額: ${cost}円\n備考: ${etcMessage}\nを登録しました`;
let targetUser = USER[userId];
if (targetUser === undefined) {
targetUser = userId;
}
DATA_SHEET.getRange(`A${newRow}`).setValue(targetUser);
DATA_SHEET.getRange(`B${newRow}`).setValue(date);
DATA_SHEET.getRange(`C${newRow}`).setValue(cost);
DATA_SHEET.getRange(`D${newRow}`).setValue(etc);
return replyMessage;
}
データの最下行から次に入力する行を取得し、決めておいた列に受け取った入力データを書き込んでいきます。
DB的にspreadsheetを使っている感じです。
メッセージ返却
function doReply(postMessage, replyToken)
{
UrlFetchApp.fetch(URL, {
'headers': {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ' + ACCESS_TOKEN,
},
'method': 'post',
'payload': JSON.stringify({
'replyToken': replyToken,
'messages': [{
'type': 'text',
'text': postMessage,
}],
}),
});
return ContentService.createTextOutput(JSON.stringify({ 'content': 'post ok' })).setMimeType(ContentService.MimeType.JSON);
}
デプロイ
コードを書き終えたらデプロイします。
右上にあるデプロイボタンから新しいデプロイを選択し、説明文を入力します。
アクセスできるユーザを「全員」に設定。
変更して更新する場合は、デプロイボタンからデプロイ管理を選択し、編集ボタンを押した後にバージョンから「新しいバージョン」を選択すればOKです。
デプロイ後に表示されるウェブアプリのURLをコピーし、Messaging APIのWebhook URLに設定すれば完了です。
使ってみた
おわりに
今回思い立ってやってみましたが、簡易的にやりたいことが実現できました。
コードの中身とかを良い書き方にするとかは飛ばしてしまいましたが、普段使うツールの延長として簡単なアプリケーション的に作るには非常によかったです。(何よりお金がかからない範囲でできる)
受け取ったメッセージを分岐するような形である意味CLIベースのような形ですが、今度はリッチメニューを使う形にしたり、
必要な機能を追加していけたらよいかなと思います。
ソースコード
参考
LINEのBot開発 超入門(前編) ゼロから応答ができるまで
[LINE BOT]GASで家計簿BOT作ってみた
グループでも動作するLINE BOTを作る!