search
LoginSignup
8
Help us understand the problem. What are the problem?

posted at

updated at

Organization

抑えられない二郎欲求のためにGASを使ってLINE Botを作りたかった記録

余裕がない日ほど二郎が食べたくなる

大学生のころに初めてラーメン二郎を食べてから、二郎系ラーメンが大好きです。
ジャンクな味付けの分厚い豚と太い麺を食べる背徳感がたまりません。
体調を考えて節制したいなと思いつつ、忙しくて余裕がないと感じている時ほど二郎を食べたくなることが多く、最近は毎週のように近くにできた二郎系インスパイアのラーメンをUber Eatsで頼んでしまっています。
このままではすぐにおデブな体になってしまいそうな予感がしており、最近学んだGoogle Apps Script(GAS)を用いてこの二郎欲を止めてくれるストッパーになるものを作成しようと思いました。

必要な機能の検討とやりたい流れ

まず手軽に記録ができることが大事だなと思ったのでLINEと連携し記録ができるようにしようと思います。
また記録と同時に二郎が食べたい時に過去の最新の二郎を食べた履歴を確認できると 「まだ1週間も経ってないから我慢しよう」と思うことが多い ので、過去の履歴を参照し、最新の二郎を食べた日付を教えてくれる機能も作りたいなと思います。
やりたいことを整理して図解すると以下のようになります。
プレゼンテーション1.png

使用した技術や用意したもの、事前準備等

  • Google Apps Script(GAS)
  • LINE Messaging API
  • Google Sheets(Google スプレッドシート)
    Google SheetsについてはGoogle Drive上に作成し、あらかじめ以下のように項目を設定しました。
    image.png
    欲求を抑えることを出発点にこのLINE Botを作成し始めましたが、後からこのシートを見て楽しめるように日付以外にも行ったお店・コール・一言感想の3つを追加項目として加えました。
    前提となるLINE Botの立上げ方やGASの使い方については5分でつくるLINE Botの記事がとてもよくまとまっているので、こちらをご参考に進めてください。

実装結果

LINEにメッセージを送ることで記録をするところまでは機能を作ることができました。
新規-Microsoft-PowerPoint-プレゼンテーション.gif

コード全量はこちらになります。長いので折りたたんでいます。

コードはこちらからご覧ください。
const CHANNEL_ACCESS_TOKEN = 'アクセストークンを記入して下さい'; 
const SPREADSHEET_ID = 'Google SheetsのシートIDを記入してください';

//ポストで送られてくるので、送られてきたJSONをパース
function doPost(e) {
  let json = JSON.parse(e.postData.contents);

  //返信するためのトークン取得
  let reply_token= json.events[0].replyToken;
  if (typeof reply_token === 'undefined') {
    return;
  }

  //送られたメッセージ内容を取得
  let message = json.events[0].message.text;  
  //LINEメッセージを「改行」で分割
  let messageParameter = message.split(/\r\n|\n/);

  //対象のスプレッドシートを取得して更新する
  let targetSs = SpreadsheetApp.openById(SPREADSHEET_ID);
  let targetSht = targetSs.getSheetByName('log');
  let lastRow = targetSht.getLastRow();
  //タイムスタンプ
  let date = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd');

  //各セルに書き込み
  targetSht.getRange('A' + (lastRow + 1)).setValue(date);
  targetSht.getRange('B' + (lastRow + 1)).setValue(messageParameter[0]);
  targetSht.getRange('C' + (lastRow + 1)).setValue(messageParameter[1]);
  targetSht.getRange('D' + (lastRow + 1)).setValue(messageParameter[2]);

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

ここからはうまくいかなかったパート

もう一つの機能として、キーワードを送った際には最新の二郎を食べた日付をスプレッドシートから探してメッセージで教えてくれる状態にしたかったのですが、GASでデバックを行うのが難しく実装できないまま時間切れとなりました。
作成したコードも載せておきますので修正点を見つけた方がいらっしゃればコメントいただけると幸いです。

コードはこちらからご覧ください。(うまくいかなかったバージョン)
const CHANNEL_ACCESS_TOKEN = 'アクセストークンを記入して下さい'; 
const SPREADSHEET_ID = 'Google SheetsのシートIDを記入してください';
const url = 'https://api.line.me/v2/bot/message/reply';

//ポストで送られてくるので、送られてきたJSONをパース
function doPost(e) {
  let json = JSON.parse(e.postData.contents);

  //返信するためのトークン取得
  let reply_token = json.events[0].replyToken;
  if (typeof reply_token === 'undefined') {
    return;
  }

  if (message == "いつ食べたっけ") { //「いつ食べたっけ」と送信された時
    sheet.getRange(lastRow, 1, 1, 2)
    UrlFetchApp.fetch(url, {
      'headers': {
        'Content-Type': 'application/json; charset=UTF-8',
        'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
      },
      'method': 'post',
      'payload': JSON.stringify({
        'replyToken': replyToken,
        'messages': [{
          'type': 'text',
          'text': "最新の日付は" + (lastRow, 1) + "です!",
        }],
      }),
    });
  } else {
    //送られたメッセージ内容を取得
    var message = json.events[0].message.text;
//LINEメッセージを「改行」で分割
let messageParameter = message.split(/\r\n|\n/);

//対象のスプレッドシートを取得して更新する
let targetSs = SpreadsheetApp.openById(SPREADSHEET_ID);
let targetSht = targetSs.getSheetByName('log');
let lastRow = targetSht.getLastRow();
//タイムスタンプ
let date = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd');

    //各セルに書き込み
    targetSht.getRange('A' + (lastRow + 1)).setValue(date);
    targetSht.getRange('B' + (lastRow + 1)).setValue(messageParameter[0]);
    targetSht.getRange('C' + (lastRow + 1)).setValue(messageParameter[1]);
    targetSht.getRange('D' + (lastRow + 1)).setValue(messageParameter[2]);

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

試しに使ってもらった

うまくいかなかった部分はあるものの、記録はLINEでできるようになったので同じく二郎好きで目下ダイエットに一緒に取り組んでいる友人にフィードバックをもらってみることにしました。

感想

  • 手軽に記録できるのは面白い!
  • 送っても返信がないと記録されたか不安。
  • 記録をしたら、おおよそのカロリーが返信されると罪悪感が増してよりダイエットに意識が出そう。
  • いつもは写真を撮ってるので、文字よりも写真で記録してくれる方がいい。
  • Twitterに一緒にアップしてくれたら 人に見せる用のラーメンBotになっていい。

様々な意見をもらいましたが、「返信がないと不安」 という観点は、作成している時はPCでLINEを立ち上げて試すことが多くあまり不便に感じていませんでしたがその通りだなと思いました。また確かに二郎系の写真は私もよく撮影するので、文字で記録よりも写真とアップした日の日付だけが記録されるシンプルな内容でも良かったかもしれないなと思いました。
「返信としておおよそのカロリーが出てくる」 というのは、ダイエットや二郎食べたい欲を抑制するという本来の目的に即していて良いアイディアだなと感じました。
今回うまくいかなかった部分と併せて実装ができるようにしてみたいなと思います。

ここまで読んでくださりありがとうございました!
もしよかったらコメントお待ちしてます!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
8
Help us understand the problem. What are the problem?