在庫切れ予防！在庫管理くんの作成 #LINEBot #Integromat

#いつの間にか在庫がない
私は鼻炎持ちのため、ティッシュの使用頻度が高く、気付くと在庫切れになっています。
在庫切れになった！と気づいてすぐに買えば良いのですが、「今度買おう」と思って放置すると、使おうと思った時には0箱だったという事を何度も繰り返しています…。
ティッシュ以外にも洗剤やシャンプーなど色々と在庫を切らして頭を抱えること数知れず。

日用品類が目につきにくい場所での保管のため在庫切れに気付かないうえに、買いたい物を手書きのメモに残してもいつの間にか無くして買い忘れるズボラな私でも使えるように、ほぼ毎回持ち歩いているスマホに入っているLINEを活用した在庫管理を作りました！

#在庫管理くん紹介

■いつでも在庫管理ファイルを開けます。

https://twitter.com/momoiku3/status/1460532862462029830

■よく買い物に行く土曜日の朝には、こんなLINEを送ってくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122228/af0f8d54-ba59-d810-0872-b0e15ae08389.png)


#仕様
・GoogleAppsScript 
・LINEmessagingAPI
・integromat
・Googlスプレッドシート

#プログラム
■常時実行
<details><summary>全体プログラム</summary><div>

```javascript
var CHANNEL_ACCESS_TOKEN = "LINEアクセストークン";

function doPost(e) {

    handleMessage(e);
}

function handleMessage(e) {
  var replyToken = JSON.parse(e.postData.contents).events[0].replyToken;
  var lineType = JSON.parse(e.postData.contents).events[0].type
  if (typeof replyToken === "undefined" || lineType === "follow") {
    return;
  }
  var userMessage = JSON.parse(e.postData.contents).events[0].message.text;

    if (userMessage.match(/在庫/)) {
      reply(replyToken, "在庫ファイルを開きます。\n https://docs.google.com/spreadsheets/d/スプレッドシートのURL");

    }else{
      reply(replyToken, "「在庫」と入力してください。");
    }
  }
function reply(replyToken, message) {
  var url = "https://api.line.me/v2/bot/message/reply";
  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": message,
      }],
    }),
  });
  return ContentService.createTextOutput(JSON.stringify({"content": "post ok"})).setMimeType(ContentService.MimeType.JSON);
}

```
</div></details>
■指定タイミングで実行
<details><summary>全体プログラム</summary><div>

```javascript
function checkItem(){
 // Webhook URL
 //Integromatで作成したWebhookのURL(末尾にパラメータ用の「?text=」を付ける)
 const URL='WebhookのURL';

  //在庫取得
  const ss =SpreadsheetApp.getActiveSpreadsheet();
  const zaiko =ss.getSheetByName("在庫");
  const lastdate=zaiko.getLastRow();

  //登録データを取得
  const zaikoList = zaiko.getRange(2,1,lastdate-1,4).getValues();

  //登録データからメッセージを作成
  //取得した在庫リストのデータの最後まで繰り返すように設定

  let message = "今の在庫状況です。\n*+*+*+*+*+*+*+*+\n";

  for(let a=0;a<zaikoList.length;a++){
    let dSyohin = zaikoList[a][0];
    let dZaiko = zaikoList[a][3];
    //商品ごとの表示を作成
    let msg = dSyohin + "：" + dZaiko +"\n";
    message = message + msg;

  }

 //カンマを改行に置換しながらGETリクエストを投げる。
 UrlFetchApp.fetch(URL + encodeURIComponent(message));

 }

```
</div></details>

##プログラム解説

###在庫一覧の表示（指定タイミングで実行部分）
Googlスプレッドシート内の必要な部分のみを抜粋して通知しています。

**■データ最終行の取得**
`const lastdate=zaiko.getLastRow();`とすることで、スプレッドシート内に在庫管理したい品物の増減があっても対応できるようにしました。

**■一覧データの取得**
一度で一覧データが取得できるように、セル範囲を指定する二次元配列でデータを取得しています。

```javascript
const zaikoList = zaiko.getRange(2,1,lastdate-1,4).getValues();
```

※参考：二次元配列について

https://tonari-it.com/gas-spreadsheet-getvalues-array/

**■一覧データからメッセージ作成**
二次元配列で収録されているデータから、商品ごとのデータを取り出してLINEに送るメッセージを作成します。

```javascript
  let message = "今の在庫状況です。\n*+*+*+*+*+*+*+*+\n";

//解説
//forでループさせることで、配列内のデータを順番に取得してメッセージを作成
  for(let a=0;a<zaikoList.length;a++){
    let dSyohin = zaikoList[a][0];
    let dZaiko = zaikoList[a][3];
    //商品ごとの表示を作成
    let msg = dSyohin + "：" + dZaiko +"\n";
    message = message + msg;
  }
```
**■メッセージ送信タイミングの指定**
GoogleAppsScriptのトリガー実行でプログラムの実行タイミングを指定しました。
実行する関数は「checkItem()」です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122228/7dc0afea-06fd-92cc-d513-5df4d0f6a2ae.png)

**■Integromatの設定**
GASからWebhookを受け取りLINE Botに繋がるように設定しています。
Integromatの設定はこちらを参考に作成しました。

https://qiita.com/shoito66/items/2f67e4de549dd844c0f4

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122228/a030f716-73f3-de58-1d7e-419c7d9ec2dc.png)

Integromatにはいつでも実行しているようschedulingをONに設定しています。
実行のタイミングは「Immediately」を選択しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122228/880caafe-c933-25fe-3437-72545e0b7968.png)


###LINEメッセージによる応答（常時実行部分）
Integromatでうまく設定が出来なかったため、この部分はLINE Botで作成しました。
作成方法はこの記事を元に作っています。

https://qiita.com/ikumi623/items/81aa9bab12164e6540eb


#ものぐさには在庫管理くん
毎日使っているLINEに在庫管理くんのアイコンがあるので、LINEを使うついでに何となくスプレッドシートの内容を見れるので、在庫が足りなくなっていないか意識が向きやすくなりました。
また、テレビを見ながら「今ティッシュ1箱取り出したわー」と「ながら入力」ができるので、極力動きたくない私には最高です。
在庫がしばらくあるので買い物での活用はまだまだ先ですが、スマホをなくすリスクは低いので、今後の活用が楽しみです。


#最後に
・今まではGASからLINEへメッセージを送るのに細かくプログラムを組んでいましたが、Integromatを利用することで簡単に送信ができたので、今後も活用していきたいです。
・在庫情報の更新は直接スプレッドシートを触らないといけないため、今後は情報の登録・更新もLINEからできるようにバージョンアップができたら良いな、と思います。


#参考

https://qiita.com/kokano23/items/a6bbfe82653a9ea3a535