GASでLINE Botの応答を改善する（エラー処理＆リッチメニュー）

# GASでLINE Botの応答を改善する（エラー処理＆リッチメニュー）

前回の記事「[Googleスプレッドシートの予定をLINE Botで取得する](https://qiita.com/rohtxe/items/eede989e6fb5b16e39f5)」では、スプレッドシートと連携してLINE Botがスケジュールを取得できるようにしました。  
今回は、**エラー処理の強化**と**リッチメニューの設定**を行い、より実用的なLINE Botに改善していきます。

---

## 1. エラー処理の改善

現在のBotは、エラーが発生した場合、`Logger.log` に記録するだけですが、ユーザーに適切なエラーメッセージを返すことで、より親切なBotにできます。

### **エラー処理のポイント**
- **ユーザーに適切なエラーメッセージを返す**
- **スプレッドシートが見つからない場合の対処**
- **LINE APIエラーのハンドリング**
- **予期しないエラーの対応**

### **改善後の `doPost` 関数**
```javascript
function doPost(e) {
  try {
    var json = JSON.parse(e.postData.contents);
    Logger.log("受信データ: " + JSON.stringify(json));

    var events = json.events;
    if (!events || events.length === 0) {
      return createResponse("イベントがありません");
    }

    var event = events[0];
    var replyToken = event.replyToken;
    var userMessage = event.message.text.trim();
    var userId = event.source && event.source.userId ? event.source.userId : null;

    if (!userId) {
      return sendErrorResponse(replyToken, "ユーザーIDが取得できませんでした。");
    }

    var replyMessage = handleUserMessage(userMessage);
    sendLineReply(replyToken, replyMessage);
    
    return createResponse("success");

  } catch (error) {
    Logger.log("エラー: " + error.toString());
    return createResponse("error", error.toString());
  }
}

function createResponse(status, message = "") {
  return ContentService.createTextOutput(JSON.stringify({ "status": status, "message": message }))
    .setMimeType(ContentService.MimeType.JSON);
}

function sendErrorResponse(replyToken, errorMessage) {
  Logger.log("エラー: " + errorMessage);
  sendLineReply(replyToken, "⚠️ エラーが発生しました: " + errorMessage);
  return createResponse("error", errorMessage);
}
```
## 2. リッチメニューを設定する
LINEのリッチメニューを設定することで、ユーザーが直感的に操作できるようになります。
例えば、以下のようなメニューを作成できます。
### リッチメニューの構成

|ボタン	|機能|
|-------|------|
|📅 予定確認	|予定を確認|
|🆕 最新情報	|最新ニュース表示|
|📖 ヘルプ	|使い方の説明|

### リッチメニューの作成手順
1.リッチメニュー画像を用意（サイズ：2500px × 1686px）
2.LINE Developers コンソールでリッチメニューを作成
3.GASでリッチメニューを登録
### GASでリッチメニューを設定
```javascript
function setRichMenu() {
  var channelAccessToken = "YOUR_CHANNEL_ACCESS_TOKEN";
  var url = "https://api.line.me/v2/bot/richmenu";

  var payload = {
    "size": { "width": 2500, "height": 1686 },
    "selected": true,
    "name": "MainMenu",
    "chatBarText": "メニューを開く",
    "areas": [
      {
        "bounds": { "x": 0, "y": 0, "width": 1250, "height": 843 },
        "action": { "type": "message", "text": "予定確認" }
      },
      {
        "bounds": { "x": 1250, "y": 0, "width": 1250, "height": 843 },
        "action": { "type": "message", "text": "最新情報" }
      },
      {
        "bounds": { "x": 0, "y": 843, "width": 2500, "height": 843 },
        "action": { "type": "message", "text": "ヘルプ" }
      }
    ]
  };

  var options = {
    "method": "post",
    "headers": {
      "Content-Type": "application/json",
      "Authorization": "Bearer " + channelAccessToken
    },
    "payload": JSON.stringify(payload)
  };

  var response = UrlFetchApp.fetch(url, options);
  Logger.log(response.getContentText());
}
```
---
## 3. メニュー画像をアップロード
リッチメニューを作成した後、画像をアップロードして適用します。
### GASでリッチメニュー画像をアップロード
```javascript
function uploadRichMenuImage(richMenuId) {
  var channelAccessToken = "YOUR_CHANNEL_ACCESS_TOKEN";
  var imageUrl = "YOUR_IMAGE_URL";

  var url = "https://api.line.me/v2/bot/richmenu/" + richMenuId + "/content";
  var image = UrlFetchApp.fetch(imageUrl).getBlob();
  var options = {
    "method": "post",
    "headers": {
      "Authorization": "Bearer " + channelAccessToken,
      "Content-Type": "image/jpeg"
    },
    "payload": image
  };

  var response = UrlFetchApp.fetch(url, options);
  Logger.log(response.getContentText());
}
```
---
## 4. 動作確認
リッチメニューを適用し、Botに「メニュー」と送信して確認してみましょう。
```javascript
function handleUserMessage(message) {
  if (message === "メニュー") {
    return "📌 メニューの使い方\n\n📅 予定確認 → 今日の予定を表示\n🆕 最新情報 → 最新ニュースを取得\n📖 ヘルプ → 使い方を表示";
  } else if (message === "予定確認") {
    var today = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyy/MM/dd");
    return getSchedule(today);
  } else if (message === "最新情報") {
    return "📢 最新情報はこちら: https://your-news-url.com";
  } else if (message === "ヘルプ") {
    return "🔹 LINE Botの使い方 🔹\n\n1. 日付を入力 → 予定確認\n2. 「メニュー」と送信 → メニュー表示";
  } else {
    return "🤖 すみません、理解できませんでした。メニューから選んでください！";
  }
}
```
---
# 5. まとめ
今回の記事では、エラー処理の強化とリッチメニューの設定を行いました。
これにより、LINE Botがより使いやすくなり、直感的な操作が可能になります。

✅ エラー処理の強化 → ユーザーに適切なエラーメッセージを返す
✅ リッチメニューの作成 → 予定確認や最新情報の取得が簡単に
✅ Botの応答改善 → ユーザーが使いやすい設計に

---
# 次の記事
### 👉 「GASでLINE Botにプッシュ通知を実装する」