ゆとりSEは副業がしたい

ゆとりSE

RPAやPythonをはじめとした情報系の発信やガジェットの紹介などがメインです

【LINE・GAS】LINEでGoogle Spread Sheetsの家計簿を更新!

f:id:oichiki:20210301222601p:plain

この記事を見ると分かる・できる事

この記事では以下の手順を記載しています。

・LINE Messaging APIの設定
Google Apps Script(GAS)でLINEのメッセージを処理
API経由でGoogle Spread Sheets(GSS)にデータの追加


LINEからの入力形式やGSSの登録は個人差があると思いますので、自分用にするためにはカスタマイズが必要であることをご承知おきください。

LINEからGoogle Spread Sheetsの家計簿を更新する

今月から同居者と家計簿をつけることになり、ツールとしてGSSを利用する運びとなりました。約一ヶ月くらい家に帰ってからPC上で入力していたのですが、これがなかなか面倒に感じました。

PCからは面倒なので、スマホから移動中に更新してしまおうと思いましたが、スマホからGSSの操作はやりにくい。そこでAPIを駆使すればどうにかなるのではと思い至りました。

LINEのMessaging APIとGASを利用することで、無料で実装できてしまったので、今回はその手順をまとめたいと思います。

構成のざっくりしたイメージは以下の通りです。

f:id:oichiki:20210301230053p:plain
構成イメージ

px.a8.net

準備

実装にあたって、API等を利用するための設定作業が必要になります。登録が必要なサービスは以下になります。

・LINE Messaging API
Google Cloud Platform


LINE Messaging APIでは新規チャネルを作成しMessaging APIを選択します。Google Cloud Platformでは新規プロジェクトを作成し、Spread Sheets APIのサービスアカウントキー発行を行います。

この辺は検索すれば詳しい記事が多数ありますので。詳細な登録手順の説明は省略します。持っていない方はいないと思いますが、Googleアカウント必須です。

以下より実際にそれぞれのツールを連携させていきます。

Googe Apps Scriptでプロジェクト作成

まずはGAS上に新しいプロジェクトを作成します。

script.google.com
最初は関数が1つあるのみですが、以降の作業のために一度デプロイします。デプロイは右上のボタンからできます。デプロイタイプはウェブアプリ、アクセスできるユーザは一応全員にしてください。

次にこのウェブアプリにアクセスするためのURLを取得します。URLはGAS右上のデプロイのプルダウンからデプロイ管理を選択すると表示されます。これをコピーして控えておきます。(これがWebhook送信先

f:id:oichiki:20210301231410p:plain
Webhook送信先

Messaging APIGoogle Apps Scriptの連携

LINEでメッセージを送ったときにGAS上のスクリプトを動かすためには、そのメッセージが来たタイミングでGAS上に内容を送信する必要があります。これを可能にするのがWebhookになります。

Messaging APIはWebhookに対応しており、設定はチャネルにあるMessaging API設定>Webhook設定の部分を編集します。

f:id:oichiki:20210301232303p:plain
Webhook設定
今回はGAS宛に送りたいのでWebhook設定の箇所にGASでデプロイしたウェブアプリのURLを記載します。ここに記載するURLが先ほど控えたURLになります。

張り付けたら検証を押して成功が表示されれば設定完了です。これでこのチャネルのボットが参加しているトークにメッセージが来るたびに、GASへと情報が送信されるようになりました。

GASでLINEからの情報を受け取る

Webhookで情報は送られてくるようになりましたが、そのままでは家計簿に登録することができません。家計簿に登録するにはGAS上で以下の作業が必要になります。

・doPost関数を作成
JSONから必要なデータを抽出
・入力値チェックとエラー処理
Google Spread Sheetsに書き込み
・Messaging APIに完了通知を返す

doPost関数の作成

この関数はPOSTリクエストに対しての処理を記載する関数になります。今回のWebhookはPOSTで送られてくるので、この関数に処理を記載する必要があります。

まずは関数を作ります。引数はeventの頭文字でeとしていますが、何でも結構です。

function doPost(e) {
    //ここに処理を書いていく
}


JSONからデータの抽出

次はWebhookで送られてきたリクエストをJSONにパースして、JSONから必要な情報を取得します。

今回はLINEから家計簿を登録する際に以下のような形式でLINEを送るようにしました。

食費
1000


一行目は使用用途、改行を挟んで2行目に金額を入力し送信しています。

メッセージは以下のように取得しています。

//JSONにパースする
var json = JSON.parse(e.postData.contents);

//送られたLINEメッセージを取得
var message = json.events[0].message.text;

//メッセージの配列化
var array = message.split(/\n/);


今回は項目を改行して分けているので、改行で分割して配列化しています。つぎはこれに対し入力チェックを行いますが、その前に返信用にMessaging APIのエンドポイントとヘッダーを設定します。

//返信用のエンドポイント
var url = "https://api.line.me/v2/bot/message/reply";

var headers = {
  "Content-Type" : "application/json; charset=UTF-8",
  "Authorization": "トークンを記載",
  };


トークンはMessaging API設定のチャネルアクセストークン(長期)をコピーして貼り付けます。

今回は入力形式が正しいか、金額が数値で入力されているか、金額が1以上の整数かどうかの3つをチェックしています。チェック用のコードは以下になります。

//項目数チェック
if ( array.length != 2 ) {

  var reply = {
    "replyToken" : json.events[0].replyToken,
      "messages" : [
        {
          'type':'text',
          'text':"項目数が誤っています"
        }
      ]
  };
    
  var options = {
    "method" : "post",
    "headers" : headers,
    "payload" : JSON.stringify(reply)
  };
    
  return UrlFetchApp.fetch(url, options);
} 

//数値チェック
try {
  if (!Number.isInteger(Number(array[1])) || !Number(array[1]) > 0 ) {
    var reply = {
    "replyToken" : json.events[0].replyToken,
      "messages" : [
        {
          'type':'text',
          'text':"金額は1以上の整数で入力して下さい"
        }
      ]
    };
    
    var options = {
      "method" : "post",
      "headers" : headers,
      "payload" : JSON.stringify(reply)
    };
      
    return UrlFetchApp.fetch(url, options);
  
} }catch(e){
  if (!Number.isInteger(Number(array[1])) || !Number(array[1]) > 0 ) {
    var reply = {
    "replyToken" : json.events[0].replyToken,
      "messages" : [
        {
          'type':'text',
          'text':"入力値が不正です"
        }
      ]
    };

    var options = {
      "method" : "post",
      "headers" : headers,
      "payload" : JSON.stringify(reply)
    };
      
    return UrlFetchApp.fetch(url, options);
  }
}


エラーになった場合は UrlFetchApp.fetch(url, options) によって先ほど指定した返信用のエンドポイントにreplyを送るようになっています。

replyの中には実際にLINE上に表示させるメッセージとreplyTokenを設定します。replyTokenを指定しないと返信するトークが分からないため忘れないようにしてください。

これでJSONからのデータ抽出とチェック・エラー処理は完了です。

Google Spread Sheetsに書きこみ

家計簿は以下のようにしてあります。

f:id:oichiki:20210302011306p:plain
家計簿

画像の通り、日付・用途・金額を入力する形になっています。そのため日付を取得後、C列の最終行の1つ下にデータを追加します。シートの名前は年/月になっています。

//日付取得しシート名の取得
var date = new Date();
var sendDate = Utilities.formatDate(date, 'Asia/Tokyo', 'M/dd');
var sheetName = String(Utilities.formatDate(date, 'Asia/Tokyo', 'yyyy/M'));

//エラーがない場合は登録情報の設定
var spreadsheet = SpreadsheetApp.openById('シートのID');
var sheet = spreadsheet.getSheetByName(sheetName);
var lastRow = sheet.getRange(3, 3).getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();

sheet.getRange(lastRow+1, 3).setValue(sendDate);
sheet.getRange(lastRow+1, 4).setValue(array[0]);
sheet.getRange(lastRow+1, 5).setValue(array[1]);


入力するシートを特定するためにシートIDを指定します。シートIDは該当シートを開いた際のURLから取得できます。

https://docs.google.com/spreadsheets/d/シートID/edit#...


これで家計簿シートの更新は完了です。

登録完了メッセージの送信

登録完了メッセージはエラー処理の時と同じ方法で行います。返信用のメッセージは入力内容をStringにして連結させています。ヘッダーは先ほどのものをそのまま使用しています。

//登録完了メッセージの返信
var text = '日付:'+String(sendDate)+'\n用途:'+String(array[0])+'\n金額:'+String(array[1])+'\n\n上記内容で登録しました。'
var reply = {
  "replyToken" : json.events[0].replyToken,
      "messages" : [
        {
          'type':'text',
          'text':text
        }
      ]
};
var options = {
    "method" : "post",
    "headers" : headers,
    "payload" : JSON.stringify(reply)
};

UrlFetchApp.fetch(url, options);

return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);


動作確認

最後に実際にLINEから入力して動作確認をします。

成功時の動作確認

LINEからは以下のように入力しました。

f:id:oichiki:20210302014223p:plain
LINE動作確認

送信するとすぐに返信が返ってきます。まずは正常に入力した場合の結果は以下のようになります。

f:id:oichiki:20210302014423p:plain
動作確認:成功

実際にGSSを確認すると以下のようにしっかり登録されていました。1・2行目は予め手入力してあったものです。

f:id:oichiki:20210302014707p:plain
Google Spread Sheets更新結果

エラー処理の動作確認

エラーの処理も以下のように問題なく動作することが確認できました。

f:id:oichiki:20210302015222p:plain
動作確認:エラー

エラーメッセージの返信が行われ、シートの更新もされませんでした。これで動作確認は完了です。

まとめ

今回はLINEからGSSに情報を登録するために様々なツールを活用しました。今日ではAPIを使うことで様々なことが実現できるため、無料で実用的なツールが作成できます。

これからも実際に生活で利用できるツールを作ってまとめていきたいと思います。