スマホで簡易的に実績を知りたい～GASで毎朝メール通知するようにした～

こんにちはTOMです。
前回は下記の記事を書きました。

https://qiita.com/tom678174/items/85440861569a219d4b3e

こちらのスプレッドシートの情報を使って、
**・朝礼時の報告を想定して毎朝9時にメールを送るようにする**
**・数値分析をしてグラフ化する**
上記をGASで出来るようにしました。

# 1. 使用ツール
**●Make**
**●LINEBot**
**●Googleスプレッドシート**
**●Googleフォーム**
**<font color="Red">NEW</font color> ●Googleスプレッドシート（GAS）**

# 2. やりたかったこと
前回は知りたい場面でLINEを打つと件数が把握できる仕組みを作成しましたが、**今回は報告するタイミングが分かっているときはLINE打つまでもなく実績を知りたいシチュエーション**を想定して、自動的にメールを送るようにしました。

# 3. 朝礼時の報告を想定して毎朝9時にメールを送るようにする
今回については、**GASを使えば何となく出来るなー**とわかってはいたものの、コードなんて自分では書けないのでChatGPTを用いて対応しました。
<br>

<img src="https://camo.qiitausercontent.com/5b96b4d03915f35299f50f2c7a99d69ff0a3808e/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333831393436312f38356133383432332d616338372d393563612d313166302d6330633035336431643162642e706e67" width="75%">

<br>
コードをコピーしてGASに貼り付けすればいいので、とても簡単です。
<br>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819461/6880fd7c-086a-68a6-5602-4b2c19fa409c.png" width="75%">

<br>
あれ？エラーが出てしまいました。
メールの容量制限がエラーの元のようです。
<br>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819461/09de9f81-91e8-3670-d838-651f9a40f76c.png" width="75%">

<br>
恐らくですが、ARRAYFORMULA関数が入っていることでデータが入ってる判定になっていたようです。
<br>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819461/2de15a26-afcc-bf3a-a089-9181ec06460d.png" width="75%">

<br>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819461/b673f32f-70f8-4949-a25a-c3e3c13a4881.png" width="75%">

<br>
無事に実行完了できました。
メールも届きました。
<br>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819461/884f890b-b16b-9946-bba4-47bcb021abdf.jpeg" width="75%">

<br>
あとは、トリガー設定をして毎朝9時に届くように設定完了です。
<br>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819461/9a38213c-af62-b1ab-f7d6-090d76e548a1.png" width="75%">

# 4. 数値分析をしてグラフ化する
ChatGPTでスクリプト作成すれば数値分析も簡単にできそうなので、手始めに下記を追加してみます
<br>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819461/c238f1da-b459-5973-5f83-bc62014c8a02.png" width="75%">

<br>
無事最大獲得件数が表示されました。
<br>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819461/1c2e91c9-5c9e-2ead-0737-f99109f17914.png" width="75%">

<br>
次にグラフ作成してメールで送るようにします。
<br>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819461/9f97e9c2-4d43-7e12-6eee-c55c7c7a5ef9.png" width="75%">

<br>
添付されました。
<br>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819461/f3b151b7-4806-a3bb-5501-1f658b9219b9.png" width="75%">

<br>
添付内容
<br>

![件数獲得推移.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819461/cca32f33-c0e2-b823-b424-f105d35021f4.png)

<br>
最終的なスクリプトはこちらとなりました。
<br>

```言語:メール配信
function sendSheetDataAsEmail() {
  // スプレッドシートとシートを取得
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('BOT反映シート');
  
  // データ範囲を取得（B2からB32まで）
  const dataRange = sheet.getRange(2, 2, 31, 3); // 2行目から32行目までの範囲を指定
  const data = dataRange.getValues();
  
  // メールのタイトルと宛先を取得
  const emailSubject = sheet.getRange('F2').getValue();
  const emailRecipient = sheet.getRange('G2').getValue();
  
  // メール本文を構築
  let emailBody = '以下の情報をご確認ください：\n\n';

  // 最大件数を持つ月日を特定するための変数
  let maxCount = 0;
  let maxDate = '';
  
  data.forEach(row => {
    const date = row[0];
    const totalCount = row[1];
    const tenantCount = row[2];
    
    // メール本文の構築
    emailBody += `月日: ${date}, 獲得件数: ${totalCount}, テナント紹介: ${tenantCount}\n`;
    
    // 最大件数を持つ月日の判定
    if (totalCount > maxCount) {
      maxCount = totalCount;
      maxDate = date;
    }
  });
  
  // 最大件数を持つ月日の情報をメール本文に追加
  emailBody += `\n\n最大件数を記録した月日: ${maxDate}（件数: ${maxCount}）\n\n`;

  // グラフを作成
  const chart = createChart(sheet);

  // グラフを画像としてエクスポート
  const chartBlob = chart.getAs('image/png');
  const attachment = {
    fileName: '件数獲得推移.png',
    mimeType: 'image/png',
    content: chartBlob.getBytes()
  };
  
  // メール送信
  MailApp.sendEmail({
    to: emailRecipient,
    subject: emailSubject,
    body: emailBody,
    attachments: [attachment]
  });
}

// グラフを作成する関数
function createChart(sheet) {
  // データ範囲を設定
  const chartRange = sheet.getRange('B1:D32');
  
  // チャートオプションを設定
  const chart = sheet.newChart()
    .setChartType(Charts.ChartType.LINE)
    .addRange(chartRange)
    .setPosition(5, 5, 0, 0)
    .build();
  
  // チャートをシートに追加
  sheet.insertChart(chart);
  
  // グラフを画像としてエクスポート
  return chart;
}
```

# 5. ChatGPTを使ってみて
今回ChatGPTを使ってみて、一からGASを自分で書かかずに済みました。
**個人的に一番恩恵を感じたのは、修正や試行錯誤などの時間を多く取れたことでした。**
アイデア出しや翻訳などではお試し程度で、ChatGPTを使用したことはありました。
しかし、GASのようなコードに今回初めて使ったことで、ある程度やりたいことが決まっているときやゴールが想像できているときに、真価を発揮するのではないかなぁと感じました。
（あくまで個人的な意見ですが・・・）
これからも有用な使い方を見つけて、ChatGPTを使っていきたいと思います！


# 6. 最後に～実は失敗してます～
本当はLINE公式アカウントから配信できるようにしたかったです。
```言語:LINE配信（失敗）
function getSheetData() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheetName = "BOT配信シート";
  var sheet = spreadsheet.getSheetByName(sheetName);
  
  if (sheet === null) {
    throw new Error("シート名 '" + sheetName + "' が見つかりません。シート名を確認してください。");
  }
  
  // B列, C列, D列のデータを取得
  var dataRange = sheet.getRange("B2:D" + sheet.getLastRow());
  var data = dataRange.getValues();
  
  return data;
}

function sendLineBroadcastMessage(message) {
  var token = "YOUR_LINE_ACCESS_TOKEN";  // ここにあなたのLINEアクセストークンを入力してください
  
  // messageの内容を確認
  Logger.log("Message: " + message);
  
  var url = "https://api.line.me/v2/bot/message/broadcast";
  var payload = {
    messages: [{
      type: "text",
      text: message
    }]
  };
  
  var options = {
    "method": "post",
    "headers": {
      "Content-Type": "application/json; charset=UTF-8",
      "Authorization": "Bearer " + token
    },
    "payload": JSON.stringify(payload),
    "muteHttpExceptions": true
  };
  
  var response = UrlFetchApp.fetch(url, options);
  var responseCode = response.getResponseCode();
  var responseBody = response.getContentText();
  
  if (responseCode !== 200) {
    throw new Error("Request failed for " + url + " returned code " + responseCode + ". Response: " + responseBody);
  }
}

function sendSheetDataToLine() {
  try {
    var data = getSheetData();
    var message = "BOT配信シートのデータ:\n";
    
    data.forEach(function(row) {
      var date = row[0];
      var total = row[1];
      var tenant = row[2];
      message += "月日: " + date + ", 獲得件数: " + total + ", テナント紹介: " + tenant + "\n";
    });
    
    // メッセージが空でないかを確認し、空の場合はデフォルトのメッセージを設定
    if (message.trim() === "BOT配信シートのデータ:\n") {
      message = "データです";
    }
    
    sendLineBroadcastMessage(message);
  } catch (e) {
    Logger.log(e.toString());
    sendLineBroadcastMessage("エラーが発生しました: " + e.message);
  }
}

```
<br>
上記までは行き着いたが、「送信するメッセージが空の文字列または未定義になっている」というエラーが解消できずに一旦断念しました。<font color="Red">くやしい。。</font color>

ただ、実務的な部分を考えるとメール配信の方が良いのだが、せっかくの機会なので知識付けてリベンジしたいと思います！