GASでメール自動化

GAS実践ガイド

GASでメール自動化【Gmail×スプレッドシート連携】

GASを使えば、Gmailの送信・管理を自動化できます。この記事では、メール自動化の実践的なテクニックを解説します。

メール自動化でできること

活用シーン

シーン 内容
一括送信 顧客リストへの案内メール
定期送信 日報・週報の自動配信
通知 フォーム回答時の自動通知
リマインダー 期限前の自動リマインド
受信処理 特定メールの自動振り分け

GmailAppでできること

JavaScript
// メール送信
GmailApp.sendEmail(to, subject, body);

// メール検索
GmailApp.search("from:example@gmail.com");

// ラベル操作
GmailApp.getUserLabelByName("ラベル名");

基本的なメール送信

シンプルな送信

JavaScript
function sendSimpleEmail() {
  GmailApp.sendEmail(
    "recipient@example.com",  // 宛先
    "件名です",                // 件名
    "本文です。"              // 本文
  );
}

オプション付き送信

JavaScript
function sendEmailWithOptions() {
  GmailApp.sendEmail(
    "recipient@example.com",
    "件名です",
    "本文です。",
    {
      name: "送信者名",
      cc: "cc@example.com",
      bcc: "bcc@example.com",
      replyTo: "reply@example.com",
      attachments: [file.getBlob()]
    }
  );
}

HTML形式のメール

JavaScript
function sendHtmlEmail() {
  const htmlBody = `
    <html>
      <body>
        <h1>お知らせ</h1>
        <p>これは<strong>HTML形式</strong>のメールです。</p>
        <ul>
          <li>項目1</li>
          <li>項目2</li>
        </ul>
      </body>
    </html>
  `;

  GmailApp.sendEmail(
    "recipient@example.com",
    "HTML形式のメール",
    "HTMLに対応していない場合のテキスト",
    {
      htmlBody: htmlBody
    }
  );
}

スプレッドシートからの一括送信

基本的な一括送信

JavaScript
function sendBulkEmails() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName("送信リスト");
  const data = sheet.getDataRange().getValues();

  // ヘッダー: 名前, メールアドレス, 送信済み
  for (let i = 1; i < data.length; i++) {
    const name = data[i][0];
    const email = data[i][1];
    const sent = data[i][2];

    // 未送信のみ処理
    if (sent !== "済") {
      const subject = "お知らせ";
      const body = `${name}様\n\nお知らせの内容です。`;

      GmailApp.sendEmail(email, subject, body);

      // 送信済みフラグを立てる
      sheet.getRange(i + 1, 3).setValue("済");

      // API制限回避のため少し待機
      Utilities.sleep(100);
    }
  }
}

差し込みメール

JavaScript
function sendMergeEmails() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName("送信リスト");
  const data = sheet.getDataRange().getValues();

  // テンプレートシートから本文を取得
  const template = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName("テンプレート")
    .getRange("A1").getValue();

  for (let i = 1; i < data.length; i++) {
    const row = data[i];
    const email = row[0];
    const name = row[1];
    const company = row[2];

    // テンプレートの置換
    let body = template
      .replace("{{name}}", name)
      .replace("{{company}}", company);

    GmailApp.sendEmail(email, "ご案内", body);
  }
}

テンプレートの活用

Gmailの下書きをテンプレートに

JavaScript
function sendFromDraft(draftSubject, recipients) {
  // 下書きを検索
  const drafts = GmailApp.getDrafts();
  let template = null;

  for (const draft of drafts) {
    if (draft.getMessage().getSubject() === draftSubject) {
      template = draft;
      break;
    }
  }

  if (!template) {
    Logger.log("テンプレートが見つかりません");
    return;
  }

  const message = template.getMessage();
  const subject = message.getSubject();
  const body = message.getPlainBody();
  const htmlBody = message.getBody();

  // 送信
  for (const recipient of recipients) {
    GmailApp.sendEmail(recipient, subject, body, {
      htmlBody: htmlBody
    });
  }
}

スプレッドシートでテンプレート管理

JavaScript
function getTemplate(templateName) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName("メールテンプレート");
  const data = sheet.getDataRange().getValues();

  for (let i = 1; i < data.length; i++) {
    if (data[i][0] === templateName) {
      return {
        subject: data[i][1],
        body: data[i][2]
      };
    }
  }
  return null;
}

function sendWithTemplate() {
  const template = getTemplate("月次報告");
  if (template) {
    GmailApp.sendEmail(
      "manager@example.com",
      template.subject,
      template.body
    );
  }
}

定期送信の設定

日次レポートの自動送信

JavaScript
function sendDailyReport() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName("日次データ");
  const data = sheet.getDataRange().getValues();

  // 今日のデータを集計
  const today = Utilities.formatDate(new Date(), "JST", "yyyy/MM/dd");
  let todayTotal = 0;

  for (let i = 1; i < data.length; i++) {
    const date = Utilities.formatDate(new Date(data[i][0]), "JST", "yyyy/MM/dd");
    if (date === today) {
      todayTotal += data[i][1];
    }
  }

  // レポートを送信
  const subject = `【日次レポート】${today}`;
  const body = `
本日の実績レポート

日付: ${today}
合計: ${todayTotal}

--
自動送信メール
  `;

  GmailApp.sendEmail("manager@example.com", subject, body);
}

// トリガー設定(毎日18時に実行)
function createDailyTrigger() {
  ScriptApp.newTrigger("sendDailyReport")
    .timeBased()
    .atHour(18)
    .everyDays(1)
    .create();
}

週次サマリーの送信

JavaScript
function sendWeeklySummary() {
  // 週の集計処理
  const summary = calculateWeeklySummary();

  const htmlBody = `
    <h2>週次サマリー</h2>
    <table border="1">
      <tr><th>項目</th><th>値</th></tr>
      <tr><td>売上合計</td><td>${summary.sales}</td></tr>
      <tr><td>件数</td><td>${summary.count}</td></tr>
    </table>
  `;

  GmailApp.sendEmail(
    "team@example.com",
    "週次サマリー",
    "HTMLメールに対応していない場合のテキスト",
    { htmlBody: htmlBody }
  );
}

受信メールの処理

特定メールの検索

JavaScript
function searchEmails() {
  // 検索クエリ
  const threads = GmailApp.search("from:important@example.com is:unread");

  for (const thread of threads) {
    const messages = thread.getMessages();
    for (const message of messages) {
      Logger.log("件名: " + message.getSubject());
      Logger.log("本文: " + message.getPlainBody());
    }
  }
}

自動ラベル付け

JavaScript
function autoLabelEmails() {
  const threads = GmailApp.search("from:client@example.com -label:クライアント");
  const label = GmailApp.getUserLabelByName("クライアント")
    || GmailApp.createLabel("クライアント");

  threads.forEach(thread => {
    thread.addLabel(label);
  });

  Logger.log(`${threads.length}件にラベルを付けました`);
}

受信メールをスプレッドシートに記録

JavaScript
function logIncomingEmails() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName("メールログ");

  // 過去1時間の未読メールを検索
  const threads = GmailApp.search("is:unread newer_than:1h");

  for (const thread of threads) {
    const messages = thread.getMessages();
    for (const message of messages) {
      if (!message.isUnread()) continue;

      sheet.appendRow([
        message.getDate(),
        message.getFrom(),
        message.getSubject(),
        message.getPlainBody().substring(0, 500)
      ]);

      // 既読にする
      message.markRead();
    }
  }
}

注意点

送信制限

アカウント種別 制限
無料アカウント 1日あたり100通、1通あたりの宛先50件
Google Workspace 1日あたり1,500〜2,000通

制限への対処

JavaScript
function sendWithLimit(emails, subject, body) {
  const DAILY_LIMIT = 100;
  const sent = parseInt(PropertiesService.getScriptProperties()
    .getProperty("sentToday") || "0");

  let count = 0;
  for (const email of emails) {
    if (sent + count >= DAILY_LIMIT) {
      Logger.log("制限に達しました。残りは明日送信されます。");
      break;
    }

    GmailApp.sendEmail(email, subject, body);
    count++;
    Utilities.sleep(100);
  }

  PropertiesService.getScriptProperties()
    .setProperty("sentToday", sent + count);
}

// 毎日0時にカウントをリセット
function resetDailyCount() {
  PropertiesService.getScriptProperties()
    .setProperty("sentToday", "0");
}

スパム対策

  • 個人情報の取り扱いに注意
  • オプトアウト(配信停止)機能を用意
  • 送信元の信頼性を確保
  • 大量送信は段階的に

まとめ

よく使うコード

JavaScript
// 基本送信
GmailApp.sendEmail(to, subject, body);

// オプション付き
GmailApp.sendEmail(to, subject, body, {
  htmlBody: htmlBody,
  cc: cc,
  attachments: attachments
});

// メール検索
GmailApp.search("検索クエリ");

活用のポイント

  1. テンプレートを活用して効率化
  2. スプレッドシートでリスト管理
  3. トリガーで定期送信
  4. 送信制限に注意

関連記事

お問い合わせ

GASでのメール自動化についてのご相談は、お気軽にお問い合わせください。

  • メール自動化設計
  • システム構築
  • 運用サポート

お問い合わせはこちら

最終更新: 2025年1月