Google Apps Script で注文メールを自動集計する方法

# Google Apps Script で注文メールを自動集計する方法

こんにちは！\
今回は、Google Apps Script (GAS) を使って、注文確認メールから必要な情報を自動で抽出し、Google スプレッドシートに記録する仕組みについてご紹介します。\
なお、対象となるメールの抽出条件や処理内容（本文の抜粋、スプレッドシートへの登録、ラベルの自動付与など）は、個人情報や固有の名称に依存しない汎用的な手法としてまとめています。

## 背景と目的

業務で注文確認メールなどの情報を自動で集計できると、後からデータの整理や分析が非常に楽になります。\
本記事では、以下のような処理を自動化する方法を解説します。

*   **対象メールの抽出**\
    Gmail 内で、特定の条件（例：件名や送信元）に合致するメールを検索し、対象メールを取得します。

*   **自動ラベル付与**\
    対象となるメールには、重複処理を防ぐために自動でラベルを付与します。\
    これにより、同じメールを再度処理することを防ぎ、後で簡単に管理できるようになります。

*   **メール本文から必要な情報の抜粋**\
    メール本文内から、あらかじめ設定したキーワード（例：「【ご注文商品】」）以降の情報を抜き出します。\
    この処理により、余計な部分（例：冒頭の装飾や不要なテキスト）を除外し、目的の情報だけを取得できます。

*   **スプレッドシートへの自動登録**\
    抽出したデータ（受信日時、件名、送信元、抜粋した本文、メールの一意なID）を、スプレッドシートに自動で記録します。\
    新しいデータは常にヘッダー直下に挿入され、最新の情報が上部に表示されるよう工夫しています。

*   **エラー対策**\
    ・メール本文中に数式と誤解釈される文字（たとえば「=」）がある場合に備え、対象セルの書式をプレーンテキストに設定しています。\
    ・処理中にエラーが発生した場合は、Logger.log() を使用してエラーメッセージを記録し、原因の特定を容易にしています。

## 実装内容の概要

### 1. メール本文からの抜粋

対象メールの本文から、あらかじめ指定したキーワード（例：「【ご注文商品】」）以降のテキストを抜き出すための関数を作成します。\
抜き出す行数は必要に応じて調整可能です。

```javascript
/**
 * 本文から指定キーワード以降のテキストを抜き出す関数
 * @param {string} body - メール本文（プレーンテキスト）
 * @param {number} numLines - 取得する行数
 * @return {string} 抜き出したテキスト
 */
function extractOrderSnippet(body, numLines) {
  var keyword = "【ご注文商品】";
  var index = body.indexOf(keyword);
  if (index >= 0) {
    var subBody = body.substring(index);
    // 改行コードで分割（Windows, Unix 両方に対応）
    var lines = subBody.split(/\r?\n/);
    return lines.slice(0, numLines).join("\n");
  } else {
    // キーワードが見つからなければ先頭100文字を返す
    return body.substring(0, 100);
  }
}
```

### 2. 対象メールの抽出とラベルの自動付与、スプレッドシートへの登録

次に、Gmail から対象メールを取得し、\
抽出した情報とともにスプレッドシートに記録する処理を行います。\
また、このコードでは対象メールに自動でラベルを付与する機能も搭載しています。\
これにより、同じメールを重複して処理することを防止できます。

```javascript
/**
 * 注文メールをすべて処理し、スプレッドシートに記録する関数
 * ※個人情報や具体的な件名、ラベル名は記載していません。
 */
function processOrderEmails() {
  try {
    // --- 設定値 ---
    // ※ここは各自の環境に合わせて、対象メールの検索条件を設定してください。
    var searchQuery = '検索条件をここに記入';  // 例: 件名や送信元で絞り込む
    var threads = GmailApp.search(searchQuery);
    
    // --- スプレッドシートの取得 ---
    // ※スプレッドシートIDとシート名は各自の環境に合わせてください。
    var spreadsheetId = "スプレッドシートIDをここに記入";
    var sheetName = "シート名をここに記入";
    var ss = SpreadsheetApp.openById(spreadsheetId);
    var sheet = ss.getSheetByName(sheetName) || ss.getSheets()[0];
    
    // ※本文スニペットを記録する列（例: D列）をプレーンテキストに設定
    try {
      sheet.getRange("D:D").setNumberFormat('@');
    } catch (err) {
      Logger.log("D列の書式設定エラー: " + err);
    }
    
    // --- ヘッダー行の確認 ---
    var data = sheet.getDataRange().getValues();
    if (data.length === 0) {
      sheet.appendRow(["日付", "件名", "送信元", "本文スニペット", "メッセージID"]);
      data = sheet.getDataRange().getValues();
    }
    
    // --- 処理済みメールのID一覧を取得 ---
    var processedIds = {};
    for (var i = 1; i < data.length; i++) {
      var msgId = data[i][4];
      if (msgId) processedIds[msgId] = true;
    }
    
    // --- 新規メールデータの格納 ---
    var newEmailRows = [];
    for (var i = 0; i < threads.length; i++) {
      var thread = threads[i];
      
      // 対象メールに自動でラベルを付与（既に付与済みでも問題ありません）
      thread.addLabel(/* ラベル名は各自の設定に合わせてください */);
      
      var messages = thread.getMessages();
      for (var j = 0; j < messages.length; j++) {
        var message = messages[j];
        var msgId = message.getId();
        if (processedIds[msgId]) continue;
        
        var date = message.getDate();
        var subject = message.getSubject();
        var sender = message.getFrom();
        
        // --- 本文の取得とキーワード確認 ---
        var plainBody = message.getPlainBody();
        var body = "";
        var keyword = "【ご注文商品】";
        if (plainBody && plainBody.indexOf(keyword) >= 0) {
          body = plainBody;
        } else {
          var htmlBody = message.getBody();
          var convertedBody = htmlBody.replace(/<br\s*\/?>/gi, "\n").replace(/<[^>]+>/g, "");
          body = (convertedBody.indexOf(keyword) >= 0) ? convertedBody : plainBody;
        }
        
        // --- キーワード以降のテキストを抜粋 ---
        var snippet = extractOrderSnippet(body, 10);
        
        newEmailRows.push([date, subject, sender, snippet, msgId]);
      }
    }
    
    // --- ソート（受信日時で降順：最新が先頭） ---
    newEmailRows.sort(function(a, b) { return b[0] - a[0]; });
    
    // --- 新規データをヘッダー直下に挿入 ---
    // ※複数件ある場合は、配列の末尾（＝最も古いメール）から順に挿入します。
    for (var k = newEmailRows.length - 1; k >= 0; k--) {
      try {
        sheet.insertRowAfter(1);
        sheet.getRange(2, 1, 1, 5).setValues([newEmailRows[k]]);
      } catch (err) {
        Logger.log("行挿入エラー（メッセージID " + newEmailRows[k][4] + "）: " + err);
      }
    }
    
  } catch (e) {
    Logger.log("processOrderEmails 内のエラー: " + e);
  }
}
```

## まとめ

*   **Google Apps Script を活用することで、注文メールから必要な情報を自動抽出しスプレッドシートに記録できます。**
*   **対象メールには自動でラベルが付与されるため、重複処理が防止され、管理も容易になります。**
*   **メール本文から特定のキーワード以降のテキストを抜き出す方法や、エラー対策（セルの書式設定、ロギング）を組み合わせることで、安定したデータ集計システムを構築可能です。**
*   **本記事は個人情報や固有の条件に依存しない汎用的なコード例としてまとめていますので、各自の環境に合わせたカスタマイズが可能です。**