8
6

More than 1 year has passed since last update.

#GoogleAppsScript で自分好みの買い物メモを作ってみた #リテールテックハッカソン

Posted at

買い物メモアプリ、使いにくい!

ご丁寧にカテゴリ分け機能レシピ連携機能などを付けてくれているものがありますが、使いません!!機能が多いと使いたい機能がわかりにくかったり、アプリが重くなったりするので不便です:no_good:

そもそもあまりいろいろアプリをインストールしたくないので、私たち夫婦はいつもLINEで買い物メモを作っています。買うものを思いついたときにLINEで送りあうスタイルです。

しかし、トークをさかのぼって買い物メモを見つけるのが面倒なのが難点:no_good:

そこで!

思いついたときすぐに買うものをメモでき、あとで見やすいLINE Bot「思いつき買い物メモ」を作りました:information_desk_person:

思いつき買い物メモ

買い物メモとして必要最低限の機能のみ搭載したシンプルかつ軽量な買い物メモLINE Botです!
  • メモを登録
  • メモを見る
  • メモを削除

使った技術

  • LINE Messaging API
  • Google Apps Script(GAS)
  • Googleスプレッドシート

つくりかた

①事前準備

まずは以下の記事を参考に、オウム返しBotが完成するところ(「AIの設定」の前)まで実施します!手順通りに進めればOKなのでとっても簡単です!

②GASのコードを以下のものにまるっと差し替える

CHANNEL_ACCESS_TOKENは自分のものに書き換えます。

GASのコード
思いつき買い物メモ
// ↓↓↓↓↓ 自分で書き換えるところ ↓↓↓↓↓ =========================================================================================================
// LINE Bot 設定
const CHANNEL_ACCESS_TOKEN = '[自分のCHANNEL_ACCESS_TOKEN]';

// ↑↑↑↑↑ 自分で書き換えるところ ↑↑↑↑↑ =========================================================================================================

// その他設定
const logSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('log');
var replyToken, json

//ポストで送られてくるので、ポストデータ取得
function doPost(e) {
  // 動作確認用のログ出力
  // log_to_sheet("A", "doPost")

  // LINEBotから送られてきたデータを、プログラムで利用しやすいようにJSON形式に変換する
  json = JSON.parse(e.postData.contents);

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

  // 返信するメッセージを作成
  if (json.events[0].message.text == 'メモを見る') {
    const data = getColData();
    messages = reply_message(data);
  } else if (json.events[0].message.text == '買えた') {
    deleteColData();
    messages = reply_message('メモを消したよー!');
  } else {
    writeLogToSheet(json.events[0].message.text);
    messages = reply_message('買うものをおぼえたよー!');
  }

  // line-bot-sdk-gas のライブラリを利用しています ( https://github.com/kobanyan/line-bot-sdk-gas )
  const linebotClient = new LineBotSDK.Client({ channelAccessToken: CHANNEL_ACCESS_TOKEN });

  // メッセージを返信
  try {
    linebotClient.replyMessage(replyToken, messages);
  } catch (e) {
    // うまく動作しない場合は、エラーが発生していないか確認してみましょう
    // log_to_sheet("A", e)
  }

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

// 動作確認用のオウム返しのメッセージを作成する関数
function test_message() {
  //送られたLINEメッセージを取得
  var user_message = json.events[0].message.text;

  //送られたメッセージをそのままオウム返し
  var reply_messages = [user_message];

  // メッセージを返信
  var messages = reply_messages.map(function (v) {
    return { 'type': 'text', 'text': v };
  });

  return messages
}

function reply_message(message) {
  var user_message = message;

  // 引数で渡されたメッセージを返す
  var reply_messages = [user_message];

  // メッセージを返信
  var messages = reply_messages.map(function (v) {
    return { 'type': 'text', 'text': v };
  });

  return messages
}

function writeLogToSheet(message = 'x') {
  // シート取得
  const sheet = SpreadsheetApp.getActiveSheet();
  // ループを回して1行ずつすでに記録されていないか確認していく
  let currentRow = 1;
  while (true) {
    // 記録されていない行が見つかったとき:
    if (!sheet.getRange(currentRow, 1).getValue()) {
      // 1列目に日付時刻を記録
      sheet.getRange(currentRow, 1).setValue(Utilities.formatDate((new Date()), 'Asia/Tokyo', 'yyyy/MM/dd hh:mm:ss'));
      // 2列目にメッセージ(引数値)を記録
      sheet.getRange(currentRow, 2).setValue(message);
      // ループ中断
      break;
    }
    // 次の行へ
    currentRow++;
  }
}

// 買い物メモを取得する
function getColData() {
  let colData = '買うものはこれだよー!';
  // シート取得
  const sheet = SpreadsheetApp.getActiveSheet();
  //シート最終行の値を取得する
  const lastRow = sheet.getLastRow();
  //指定したセル範囲を取得する
  try {
    const range = sheet.getRange(2, 2, lastRow - 1);
    //セル範囲の値を取得する
    const values = range.getValues();
    for (let value in values) {
      colData = colData + '\n' + values[value];
    }
  // メモが登録されていない場合
  } catch (e) {
    colData = 'メモはないよー!';
  }

  return colData;
}

// 買い物メモを削除する
function deleteColData() {
  // シート取得
  const sheet = SpreadsheetApp.getActiveSheet();
  //シート最終行の値を取得する
  const lastRow = sheet.getLastRow();
  sheet.deleteRows(2, lastRow);
}

// 処理の確認用にログを出力する関数
function log_to_sheet(column, text) {
  if (logSheet.getRange(column + "1").getValue() == "") {
    lastRow = 0
  } else if (logSheet.getRange(column + "2").getValue() == "") {
    lastRow = 1
  } else {
    var lastRow = logSheet.getRange(column + "1").getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();
    // 無限に増えるので1000以上書き込んだらリセット
    console.log("lastRow", lastRow)
    if (lastRow >= 1000) {
      logSheet.getRange(column + "1:" + column + "10").clearContent()
      lastRow = 0
    }
  }
  var putRange = column + String(lastRow + 1)
  logSheet.getRange(putRange).setValue(text);
}

③Googleスプレッドシートに以下のようなヘッダを付ける

以上!完成です:clap:

使ってみた

  • メモを登録:買う予定の商品を投稿
  • メモを見る:「メモを見る」ボタンを押下
  • メモを消す:「買えた」ボタンを押下

すごい!想像以上に欲しかったものそのものができてうれしい:raised_hands:
こういう余計な機能がなくてわかりやすく、LINEで使える買い物メモを求めてたんですよ!!!
自分が欲しいものは自分で作る、まさに自給自足の時代ですね:fist:

夫と一緒に使うこともできて便利!

今のままでも十分満足ですが、今後は「買えた」ボタンでメモを一括削除する機能だけでなく、商品ごとにメモを削除する機能を作ってもいいかも~!と思いました:grin:

ちなみに

ChatGPTとつなげて、買い物メモなのに何も覚えてくれない「偏差値3の買い物メモ」を作っていますので、そちらもぜひご覧ください:information_desk_person:
S__389530192.jpg

8
6
0

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
  3. You can use dark theme
What you can do with signing up
8
6