Google Apps ScriptでLINE Botを作成！Webhook処理の解説

# 1. doPost関数の役割
この関数は、LINEプラットフォームから送信されたメッセージを受け取り、適切な返信をする処理を行います。

# 2. 処理の流れ（コード解説）
### (1) 受信データの解析

```javascript:javascript
var json = JSON.parse(e.postData.contents);
Logger.log("受信データ: " + JSON.stringify(json));
```
* `e.postData.contents` にはLINEから送られてきたデータが格納されている
* そのデータを `JSON.parse` でオブジェクトに変換
* 受信したデータを `Logger.log()` で記録（デバッグ用）

---

### (2) イベントデータのチェック

```javascript:javascript
var events = json.events;
if (!events || events.length === 0) {
  return ContentService.createTextOutput(JSON.stringify({ "status": "no event" }))
    .setMimeType(ContentService.MimeType.JSON);
}
```
* LINEからのイベント（メッセージ）が存在するか確認
* イベントが空（`events.length === 0`）の場合は、処理を終了
---
### (3) `replyToken`と`userId`の取得
```javascript:javascript
var replyToken = events[0].replyToken;
var userMessage = events[0].message.text.trim();
var userId = events[0].source && events[0].source.userId ? events[0].source.userId : null;
```
* `replyToken`: LINE Botが返信するときに必要なトークン（この値を使って返信を送る）
* `userMessage`: ユーザーが送信したメッセージ（前後の空白を削除）
* `userId`: ユーザーのLINE ID（存在しない場合はnull）

---
### (4) `userId`のチェック（エラー処理）

```javascript:javascript
if (!userId) {
  Logger.log("エラー: userIdが取得できませんでした。");
  sendLineReply(replyToken, "エラー: ユーザーIDが取得できませんでした。");
  return ContentService.createTextOutput(JSON.stringify({ "status": "error", "message": "userId not found" }))
    .setMimeType(ContentService.MimeType.JSON);
}
```
* `userId`が取得できない場合（例えば、LINE公式アカウントのシステムメッセージなど）
  * `Logger.log()`でエラーログを記録
  * ユーザーにエラーメッセージを返信
  * `return`で処理を終了
---

### (5) 返信メッセージの決定

```javascript:javascript
var replyMessage = "すみません、理解できませんでした。";
if (userMessage.includes("こんにちは")) {
  replyMessage = "こんにちは！";
} else if (userMessage.includes("天気")) {
  replyMessage = "今日の天気は晴れです！";
}
```
*` userMessage `の内容によって返信を変える
    * `「こんにちは」`を含む → `「こんにちは！」`と返信
    * `「天気」を含む ` → `「今日の天気は晴れです！」`と返信
    * どちらでもない場合は `「すみません、理解できませんでした。」`と返信

### (6) LINEへ返信を送信

```javascript:javascript
Logger.log("返信メッセージ: " + replyMessage);
sendLineReply(replyToken, replyMessage);
```
* ` Logger.log() `で送信するメッセージを記録（デバッグ用）
* ` sendLineReply() `関数を呼び出し、LINEに返信を送る

---

### (7) 正常終了レスポンスの返却
```javascript:javascript
return ContentService.createTextOutput(JSON.stringify({ "status": "success" }))
  .setMimeType(ContentService.MimeType.JSON);
```
* `ContentService.createTextOutput()` を使ってLINEにレスポンスを返す
* `{"status": "success"}` というJSONデータを返す

---

### (8) エラー処理

``` javascript:javascript
catch (error) {
  Logger.log("エラー: " + error.toString());
  return ContentService.createTextOutput(JSON.stringify({ "status": "error", "message": error.toString() }))
    .setMimeType(ContentService.MimeType.JSON);
}
```
* 何らかのエラーが発生した場合にキャッチ
* `Logger.log()` でエラーメッセージを記録
* JSON形式でエラー情報を返す

# 3. `doPost` のまとめ
| 処理内容       | 説明      |
|:----------------:|:----------------:|
|受信データ解析|LINE からのメッセージをJSON形式に変換|
|イベントデータのチェック|イベントが存在するか確認|
|`replyToken`と`userId`取得|`LINE`メッセージの識別情報を取得|
|`userId`エラーチェック|`userId` がない場合はエラーレスポンスを返す|
|返信メッセージを決定|ユーザーのメッセージ内容によって返信内容を選択|
|返信を送信|sendLineReply() を使って返信を送信|
|正常終了のレスポンス|`{ "status": "success" }`を返す|
|例外処理|エラーが発生した場合は { "status": "error" } を返す|

# 4. `sendLineReply()` 関数の解説（補助関数）
この関数は、LINE APIを使ってメッセージを返信する役割を持ちます。

```javascript:javascript
function sendLineReply(replyToken, message) {
  var channelAccessToken = "YOUR_CHANNEL_ACCESS_TOKEN";

  var url = "https://api.line.me/v2/bot/message/reply";
  var payload = {
    "replyToken": replyToken,
    "messages": [{ "type": "text", "text": message }]
  };

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

  try {
    var response = UrlFetchApp.fetch(url, options);
    Logger.log("LINE返信レスポンス: " + response.getContentText());
  } catch (error) {
    Logger.log("LINE API送信エラー: " + error.toString());
  }
}
```
## 役割
* LINE API (`https://api.line.me/v2/bot/message/reply`) に `replyToken` を使ってメッセージを送信
* `vAuthorization` ヘッダーに `Bearer YOUR_CHANNEL_ACCESS_TOKEN` を設定
* `payload` にメッセージをJSON形式で送る
* `UrlFetchApp.fetch()` を使ってリクエストを送信
* レスポンスを `Logger.log()` で記録
* エラーが発生した場合は `Logger.log()` でエラーメッセージを記録
# 5. まとめ
この`doPost`関数は、LINEからのメッセージを受け取り、内容に応じた返信を行う基本的なWebhook処理です。
この仕組みを拡張して、スプレッドシート連携やAPI連携を追加することで、さらに高度なLINE Botを作ることができます！ 🚀