- クラウドサービス
GASでメール送信を自動化|トリガーの定期実行と一斉送信のコード
GAS(Google Apps Script)でメール送信を自動化するには、MailApp.sendEmail でメールを送る関数を書き、時間主導型のトリガーでその関数を定期実行します。 宛先をスプレッドシートに並べれば、氏名や部署を差し込んだ一斉送信も数十行で書けます。
この記事では、送信の基本から、二重送信を防ぐ「送信済み」列、1日の送信枠の残数確認、実行時間の上限に合わせた分割送信までを1本のコードにまとめました。トリガーは画面からの設定と、ScriptApp.newTrigger でコードから作る方法の両方を載せています。
確認環境:メソッド名・引数・上限値は Google Apps Script の公式リファレンス(2026年10月5日に閲覧)で確認。コードの構文と一斉送信の分岐(送信済みの行を飛ばす・送信枠で止まる・時間で区切って再開する)は、GAS のサービスを置き換えた簡易スタブを使い Node.js 22 で動かして確認しています。
GASメール送信の早見表
| やりたいこと | 書き方 |
|---|---|
| メールを1通送る | MailApp.sendEmail(宛先, 件名, 本文) |
| CC・BCC・差出人名を付ける | MailApp.sendEmail(宛先, 件名, 本文, { cc, bcc, name }) |
| HTMLメールを送る | オプションに htmlBody を渡す |
| ファイルを添付する | オプションに attachments: [Blob, ...] を渡す |
| 今日あと何宛先に送れるか調べる | MailApp.getRemainingDailyQuota() |
| 毎日9時台に実行する | ScriptApp.newTrigger('関数名').timeBased().everyDays(1).atHour(9).create() |
| 毎週月曜に実行する | .timeBased().onWeekDay(ScriptApp.WeekDay.MONDAY).atHour(9).create() |
| 毎月1日に実行する | .timeBased().onMonthDay(1).atHour(9).create() |
| 10分おきに実行する | .timeBased().everyMinutes(10).create() |
| 登録済みのトリガーを消す | ScriptApp.getProjectTriggers() で取り出して ScriptApp.deleteTrigger(trigger) |
主な上限(公式の Quotas ページの記載)は次のとおりです。
| 項目 | 個人アカウント(gmail.com) | Google Workspace |
|---|---|---|
| 1日に送れる宛先の数 | 100 / 日 | 1,500 / 日 |
| 1通あたりの宛先の数 | 50 / 通 | 50 / 通 |
| 本文のサイズ | 200 KB / 通 | 400 KB / 通 |
| 添付ファイルの数 | 250 / 通 | 250 / 通 |
| 添付ファイルの合計サイズ | 25 MB / 通 | 25 MB / 通 |
| スクリプトの実行時間 | 6 分 / 回 | 6 分 / 回 |
| トリガーの合計実行時間 | 90 分 / 日 | 6 時間 / 日 |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「GASでメール送信を自動化|トリガーの定期実行と一斉送信のコード」
上限はユーザーごとに数えられ、最初のリクエストから24時間後にリセットされます。また、公式ページには「上限は予告なく変わることがある」と書かれているため、大量に送る前に最新の値を確認しておくと安心です。
準備:スプレッドシートからスクリプトを開く
スプレッドシートのメニュー「拡張機能」から Apps Script を開くと、そのスプレッドシートに結び付いたスクリプト(コンテナバインド型)が作られます。この記事のコードは、この形で使う前提です。
初めて実行するときは、権限の確認画面が表示されます。内容を確認して許可すると、以降はその関数が自分のアカウントの権限で動きます。
メールを1通送る基本のコード
もっとも短い形は、宛先・件名・本文の3つを渡すだけです。
function sendSimpleMail() {
MailApp.sendEmail('taro@example.com', '備品予約の確認', '明日 10:00 から会議室Aの予約があります。');
}
エディタの上部で関数 sendSimpleMail を選び、実行ボタンを押すと送信されます。まずは自分のアドレスを宛先にして試すのがおすすめです。
CC・BCC・HTML本文を付ける
4つめの引数にオプションをまとめて渡します。
function sendHtmlMail() {
const text = '明日 10:00 から会議室Aの予約があります。';
MailApp.sendEmail('taro@example.com', '備品予約の確認', text, {
htmlBody: '<p>明日 <b>10:00</b> から会議室Aの予約があります。</p>',
cc: 'leader@example.com',
bcc: 'archive@example.com',
name: '備品予約システム',
replyTo: 'soumu@example.com',
});
}
htmlBody を渡すと、HTML を表示できる環境ではそちらが使われ、表示できない環境では3つめの引数の本文が使われます。 そのため、本文(テキスト)と htmlBody は同じ内容を両方用意しておくのが基本です。
ファイルを添付する
attachments には Blob(ファイルの中身を表すオブジェクト)の配列を渡します。Googleドライブのファイルは DriveApp.getFileById で取り出し、getAs でPDFに変換できます。
function sendMailWithAttachment() {
const file = DriveApp.getFileById('ここにファイルのID');
MailApp.sendEmail('taro@example.com', '月次レポート', 'レポートを添付します。', {
attachments: [file.getAs('application/pdf')],
name: '総務チーム',
});
}
変換せずにそのまま添付するときは、file.getBlob() を渡します。
sendEmailのオプション一覧
MailApp.sendEmail の4つめの引数(オプション)に指定できる項目です。
| オプション | 型 | 内容 |
|---|---|---|
cc |
String | CC のアドレス。複数はカンマ区切り |
bcc |
String | BCC のアドレス。複数はカンマ区切り |
htmlBody |
String | HTML の本文。指定すると、HTML を表示できる環境では本文の代わりに使われる |
inlineImages |
Object | 本文に埋め込む画像。キーと Blob の対応表を渡し、htmlBody 側では cid:キー名 で参照する |
attachments |
BlobSource の配列 | 添付するファイル |
name |
String | 差出人として表示する名前。省略時は送信者のユーザー名 |
replyTo |
String | 返信先のアドレス。省略時は送信者のアドレス |
noReply |
Boolean | true にすると、返信を受け付けない汎用の no-reply アドレスから送る。Google Workspace アカウントのみ |
補足として、次の3点を押さえておくと迷いません。
- noReply を true にすると、replyTo は無視されます。
- noReply は個人の Gmail アカウントでは使えません。
- 1つのオブジェクトにまとめて渡す書き方(to・subject・body もキーにする形)もあります。
function sendByObject() {
MailApp.sendEmail({
to: 'taro@example.com',
cc: 'leader@example.com',
subject: '備品予約の確認',
body: '明日 10:00 から会議室Aの予約があります。',
});
}
MailAppとGmailAppの違い
GAS にはメールを送れるサービスが2つあります。送るだけなら MailApp、受信メールの検索や下書き・ラベルも扱うなら GmailApp という使い分けです。
| 比べる点 | MailApp | GmailApp |
|---|---|---|
| 役割 | メールの送信専用 | Gmail のスレッド・メッセージ・ラベルの操作と送信 |
| 送信 | sendEmail(宛先, 件名, 本文) / sendEmail(宛先, 件名, 本文, オプション) |
sendEmail(宛先, 件名, 本文) / sendEmail(宛先, 件名, 本文, オプション) |
| そのほかの送信の形 | sendEmail(メッセージのオブジェクト) / sendEmail(to, replyTo, 件名, 本文) |
― |
| 送信枠の残数確認 | getRemainingDailyQuota() |
― |
| 下書きの作成 | ― | createDraft(宛先, 件名, 本文) |
| 受信メールの検索・取得 | ― | search(検索条件)、getInboxThreads() など |
| ラベルの作成・削除 | ― | createLabel(名前)、deleteLabel(ラベル) |
| エイリアスの一覧 | ― | getAliases() |
| 必要な権限(スコープ) | https://www.googleapis.com/auth/script.send_mail |
https://mail.google.com/ |
| 権限の意味 | メールを送る権限だけ | Gmail 全体の読み書き |
MailApp が求める権限は「送信」だけなので、権限の確認画面で伝える範囲が小さく済みます。通知メールや一斉送信のように送るだけの用途は、MailApp を選ぶと説明しやすくなります。
一方、「送る前に下書きとして保存して目で確認したい」「届いたメールを検索して返信の有無を調べたい」といった場面では GmailApp が合います。
スプレッドシートの宛先に一斉送信するコード
ここからが本題です。宛先リストの各行に、氏名や部署を差し込んで1通ずつ送ります。
シートの準備
シート名を「宛先」とし、1行目を見出しにします。
| メール | 氏名 | 部署 | 送信状況 | 送信日時 |
|---|---|---|---|---|
| sato@example.com | 佐藤 | 総務部 | ||
| suzuki@example.com | 鈴木 | 開発部 | 送信済み | 2026/10/01 9:12 |
| takahashi@example.com | 高橋 | 営業部 |
貼り付け用(タブ区切り):
メール 氏名 部署 送信状況 送信日時
sato@example.com 佐藤 総務部
suzuki@example.com 鈴木 開発部
takahashi@example.com 高橋 営業部
「送信状況」と「送信日時」は、この順で隣り合わせに置きます。列を増やせば、本文の中で {{列名}} として差し込めます。
コード全体
// ===== 設定 =====
const SHEET_NAME = '宛先';
const SENDER_NAME = '総務チーム';
const REPLY_TO = 'soumu@example.com';
const SUBJECT = '【お願い】{{部署}} 備品棚卸しのご協力';
const BODY = [
'{{氏名}} 様',
'',
'{{部署}}の備品棚卸しを 10月20日までにお願いします。',
'入力先:備品予約システムの「棚卸し」メニュー',
'',
'総務チーム',
].join('\n');
const SENT_MARK = '送信済み';
const MAX_RUNTIME_MS = 4 * 60 * 1000; // 1回の実行で使う時間(上限6分より短くする)
const RESERVE_QUOTA = 5; // ほかの用途のために残す通数
// {{列名}} を、その行の値に置き換える
function fillTemplate(template, record) {
return template.replace(/\{\{(.+?)\}\}/g, (match, key) =>
key in record ? String(record[key]) : match);
}
// HTML に埋め込む前に記号を置き換える
function escapeHtml(text) {
return String(text)
.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
.replace(/"/g, '"');
}
function toHtml(text) {
return '<div style="font-family:sans-serif;line-height:1.7">' +
escapeHtml(text).replace(/\n/g, '<br>') + '</div>';
}
// ===== 一斉送信の本体 =====
function sendBulkMail() {
const lock = LockService.getScriptLock();
if (!lock.tryLock(1000)) {
Logger.log('別の実行が動いているため、今回は何もしません');
return;
}
try {
const startedAt = Date.now();
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
const values = sheet.getDataRange().getValues();
const header = values[0];
const statusCol = header.indexOf('送信状況'); // 0始まり
const sentAtCol = header.indexOf('送信日時');
if (statusCol === -1 || sentAtCol !== statusCol + 1) {
throw new Error('「送信状況」「送信日時」の列を、この順で隣り合わせに用意してください');
}
let quota = MailApp.getRemainingDailyQuota() - RESERVE_QUOTA;
let sent = 0;
let stopReason = '';
for (let i = 1; i < values.length; i++) {
const record = {};
header.forEach((name, c) => { record[name] = values[i][c]; });
if (record['送信状況'] === SENT_MARK) continue; // 二重送信を防ぐ
if (!record['メール']) continue; // 宛先が空の行は飛ばす
if (quota <= 0) { stopReason = '送信枠'; break; }
if (Date.now() - startedAt > MAX_RUNTIME_MS) { stopReason = '実行時間'; break; }
const body = fillTemplate(BODY, record);
MailApp.sendEmail(record['メール'], fillTemplate(SUBJECT, record), body, {
htmlBody: toHtml(body),
name: SENDER_NAME,
replyTo: REPLY_TO,
});
// 1通送るたびに、その行へ記録する
sheet.getRange(i + 1, statusCol + 1, 1, 2).setValues([[SENT_MARK, new Date()]]);
quota--;
sent++;
}
Logger.log('今回の送信: ' + sent + '通 / 中断理由: ' + (stopReason || 'なし(最後まで完了)'));
clearContinueTriggers();
if (stopReason === '実行時間') {
// 続きを1分後に自動で再開する
ScriptApp.newTrigger('sendBulkMail').timeBased().after(60 * 1000).create();
}
} finally {
lock.releaseLock();
}
}
// 自分で作った「続き」用のトリガーを片づける
function clearContinueTriggers() {
ScriptApp.getProjectTriggers().forEach((trigger) => {
if (trigger.getHandlerFunction() === 'sendBulkMail') {
ScriptApp.deleteTrigger(trigger);
}
});
}
関数 sendBulkMail を実行すると送信が始まります。
このコードが守っている4つのこと
| 守りたいこと | 仕組み | コードの場所 |
|---|---|---|
| 同じ人に2回送らない | 送るたびに「送信状況」へ「送信済み」と書き、次回はその行を飛ばす | if (record['送信状況'] === SENT_MARK) continue; |
| 同時に2つ動かさない | LockService でロックを取り、取れなければ何もせず終わる | lock.tryLock(1000) |
| 1日の送信枠を超えない | 最初に getRemainingDailyQuota で残数を調べ、送るたびに1ずつ減らす | if (quota <= 0) |
| 実行時間の上限を超えない | 開始から4分を過ぎたら区切り、1分後に続きを動かすトリガーを作る | if (Date.now() - startedAt > MAX_RUNTIME_MS) |
ポイントは、送信と記録を1通ごとに対にしていることです。全員に送り終えてからまとめて記録する形だと、途中で止まったときにどこまで送ったかが分からなくなります。1通ごとに書いておけば、再実行しても続きから始まります。
分岐の動きをスタブで確かめた結果
GAS のサービス(MailApp・SpreadsheetApp・ScriptApp など)を、送信内容を配列に記録するだけの簡易スタブに置き換え、同じコードを Node.js 22 で動かしました。実際のメールは送っていません。
- 上の表の3人(鈴木さんは送信済み)で実行した場合
今回の送信: 2通 / 中断理由: なし(最後まで完了)
sato@example.com / 【お願い】総務部 備品棚卸しのご協力
takahashi@example.com / 【お願い】営業部 備品棚卸しのご協力
送信済みの鈴木さんは飛ばされ、件名に部署が差し込まれています。本文は次の形になりました。
佐藤 様
総務部の備品棚卸しを 10月20日までにお願いします。
入力先:備品予約システムの「棚卸し」メニュー
総務チーム
- 残りの送信枠が8、未送信が10件の場合(5通ぶんは残す設定)
今回の送信: 3通 / 中断理由: 送信枠
- 1通に30秒かかると仮定した20件の場合
実行1 今回の送信: 9通 / 中断理由: 実行時間 → 続き用のトリガー 1個
実行2 今回の送信: 9通 / 中断理由: 実行時間 → 続き用のトリガー 1個
実行3 今回の送信: 2通 / 中断理由: なし(最後まで完了) → 続き用のトリガー 0個
時間で区切られた回だけ続き用のトリガーが作られ、最後の回で片づけられています。送信枠で止まった場合はトリガーを作らないので、翌日以降にもう一度 sendBulkMail を実行すると、残りの行から再開します。
件数から送り方を決める目安
| 未送信の件数 | 個人アカウント(100 / 日) | Google Workspace(1,500 / 日) |
|---|---|---|
| 〜95件 | 1日で完了 | 1日で完了 |
| 96〜1,495件 | 複数日に分かれる(1日95件ずつ) | 1日で完了(時間で区切られたら自動で再開) |
| それ以上 | 日数がかかるため、配信用のサービスも選択肢 | 複数日に分かれる |
件数は、コードの RESERVE_QUOTA(残しておく通数)を5にした場合の数字です。上限は宛先の数で数えられるため、CC や BCC を付ける場合は、そのぶん余裕を見て見積もってください。
トリガーで定期実行する
トリガーは「いつ・どの関数を動かすか」の予約です。時間を条件にするものを、時間主導型(Time-driven)トリガーと呼びます。
画面から設定する手順
公式ドキュメント(英語)の手順は次のとおりです。かっこ内は日本語に訳したものです。
- Apps Script のプロジェクトを開く
- 左側の Triggers(トリガー。目覚まし時計のアイコン)をクリックする
- 右下の Add Trigger(トリガーを追加)をクリックする
- 動かす関数と、トリガーの種類(時間主導型)・間隔・時刻を選ぶ
- Save(保存)をクリックする
コードから作る早見表
同じ設定は、ScriptApp.newTrigger でコードからも作れます。設定をコードに残せるので、別のスプレッドシートへ同じ仕組みを移すときに手順書が要りません。
| 実行のタイミング | timeBased() に続けて書くメソッド |
|---|---|
| 毎日 9時台 | .everyDays(1).atHour(9) |
| 3日おき | .everyDays(3) |
| 毎週月曜の 9時台 | .onWeekDay(ScriptApp.WeekDay.MONDAY).atHour(9) |
| 毎月1日の 9時台 | .onMonthDay(1).atHour(9) |
| N分おき(N は 1・5・10・15・30) | .everyMinutes(10) |
| N時間おき | .everyHours(2) |
| 今から N ミリ秒後に1回 | .after(10 * 60 * 1000) |
| 指定した日時に1回 | .at(new Date(2026, 10, 2, 9, 0)) |
| 指定した日に1回(0時ごろ) | .atDate(2026, 11, 2) |
at に渡す Date は JavaScript の仕様で月が0始まり(10 が11月)、atDate は月を 1〜12 で指定します。同じ「11月2日」でも書き方が変わるので、表の2行を見比べてください。
// 毎日 9時台に実行
function createDailyTrigger() {
ScriptApp.newTrigger('sendDailyReport')
.timeBased()
.everyDays(1)
.atHour(9)
.create();
}
// 毎週月曜の 9時台に実行
function createWeeklyTrigger() {
ScriptApp.newTrigger('sendWeeklyReport')
.timeBased()
.onWeekDay(ScriptApp.WeekDay.MONDAY)
.atHour(9)
.create();
}
// 毎月1日の 9時台に実行
function createMonthlyTrigger() {
ScriptApp.newTrigger('sendMonthlyReport')
.timeBased()
.onMonthDay(1)
.atHour(9)
.create();
}
// 10分おきに実行(指定できるのは 1・5・10・15・30)
function createEvery10MinutesTrigger() {
ScriptApp.newTrigger('checkAndNotify')
.timeBased()
.everyMinutes(10)
.create();
}
// 2時間おきに実行
function createEvery2HoursTrigger() {
ScriptApp.newTrigger('checkAndNotify')
.timeBased()
.everyHours(2)
.create();
}
// 10分後に1回だけ実行
function createOneTimeTrigger() {
ScriptApp.newTrigger('sendBulkMail')
.timeBased()
.after(10 * 60 * 1000)
.create();
}
// 関数名を指定してトリガーを作り直す(同じものを増やさない)
function resetTrigger(functionName, build) {
ScriptApp.getProjectTriggers().forEach((trigger) => {
if (trigger.getHandlerFunction() === functionName) {
ScriptApp.deleteTrigger(trigger);
}
});
build(ScriptApp.newTrigger(functionName).timeBased()).create();
}
function setupDailyTrigger() {
resetTrigger('sendDailyReport', (builder) => builder.everyDays(1).atHour(9));
}
// いま登録されているトリガーをログに出す
function listTriggers() {
ScriptApp.getProjectTriggers().forEach((trigger) => {
Logger.log(trigger.getHandlerFunction() + ' / ' + trigger.getEventType() + ' / ' + trigger.getUniqueId());
});
}
createDailyTrigger などの関数は、エディタから1回だけ手で実行します。実行するたびにトリガーが1つ増えるため、作り直すときは resetTrigger のように「同じ関数のトリガーを消してから作る」形にしておくと、重複を防げます。
定期実行で送るメールの例
毎朝、その日の予約があるときだけ一覧を送る関数です。setupDailyTrigger を1回実行しておけば、毎日9時台に動きます。
function sendDailyReport() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('予約');
const rows = sheet.getDataRange().getValues().slice(1);
const today = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd');
const lines = rows
.filter((row) => Utilities.formatDate(new Date(row[0]), 'Asia/Tokyo', 'yyyy/MM/dd') === today)
.map((row) => '・' + row[1] + '(' + row[2] + ')');
if (lines.length === 0) return; // 予約が無い日は送らない
if (MailApp.getRemainingDailyQuota() < 1) {
Logger.log('今日の送信枠が残っていないため、送信を見送りました');
return;
}
MailApp.sendEmail('team@example.com', '本日の備品予約 ' + today, lines.join('\n'));
}
「予約」シートは、A列に日付、B列に備品名、C列に予約者が入っている想定です。
トリガーの時刻について知っておきたいこと
| 項目 | 内容 |
|---|---|
| 実行される時刻 | 指定した時刻ぴったりではなく、少し幅がある。公式の例では、9時の定期トリガーは 9時〜10時の間のどこかで動き、以降は同じ時刻で24時間ごとに繰り返す |
| 分の指定 | nearMinute(分) で指定できるが、前後15分の幅がある |
| everyMinutes の値 | 1・5・10・15・30 のいずれか |
| 誰の権限で動くか | トリガーを作った人のアカウント。メールもその人のアドレスから送られる |
| 上限 | トリガーで動いた時間の合計が、個人アカウントは 90分 / 日、Google Workspace は 6時間 / 日 |
「9時ちょうどに届けたい」という用途には向きません。「9時台に届けばよい」という通知に使うと、仕組みと要件が合います。
送る前に確認したいチェックリスト
| 確認すること | 見るところ |
|---|---|
| 自分宛てで試したか | 宛先シートを自分のアドレス1行だけにして実行 |
| 差し込みの列名が合っているか | 本文の {{列名}} と、シート1行目の見出し。合わないものは {{列名}} のまま残る |
| 送信枠は足りるか | MailApp.getRemainingDailyQuota() の値と未送信の件数 |
| 「送信状況」列が空か | 再送したい行だけ「送信済み」を消す |
| トリガーが重複していないか | 左側の Triggers の一覧、または listTriggers のログ |
| 宛先に送ってよいか | 受け取る人が了承している連絡か |
送信枠の残りは、次の関数でいつでも確認できます。
function checkQuota() {
Logger.log('あと ' + MailApp.getRemainingDailyQuota() + ' 宛先に送れます');
}
よくある質問
Q. MailApp と GmailApp のどちらを使えばよいですか? A. 送るだけなら MailApp が向いています。必要な権限が送信だけで済み、getRemainingDailyQuota で残数も調べられます。下書きの作成、受信メールの検索、ラベルの操作が必要なときは GmailApp を選びます。
Q. 一斉送信が途中で止まりました。もう一度実行してもよいですか? A. この記事のコードは、送った行に「送信済み」と書いてから次へ進むので、再実行すると未送信の行だけが対象になります。止まった理由は実行ログの「中断理由」で確認できます。
Q. 1通のメールに宛先を50件まとめれば、1日の上限は増えますか? A. 増えません。1日の上限はメールの通数ではなく宛先の数で数えられます。差し込みをする場合は、1行につき1通で送る形が扱いやすくなります。
Q. 5分おきより細かい間隔や、20分おきにしたいときは? A. everyMinutes に指定できるのは 1・5・10・15・30 です。20分おきにしたいときは、10分おきのトリガーで動かし、関数の中で時刻を見て1回おきに処理する方法があります。
まとめ
- 送信は MailApp.sendEmail(宛先, 件名, 本文, オプション)。cc・bcc・htmlBody・attachments・name・replyTo・noReply はオプションで指定する
- 送るだけなら MailApp、下書き・検索・ラベルも扱うなら GmailApp。必要な権限の広さが違う
- 一斉送信は「1通送る → その行に送信済みと書く」を対にすると、再実行しても二重送信にならない
- 送信枠は getRemainingDailyQuota で事前に確認する。個人アカウントは100宛先 / 日、Google Workspace は1,500宛先 / 日
- 実行時間は1回6分まで。時間で区切り、after で続き用のトリガーを作ると自動で再開できる
- トリガーは画面でもコードでも作れる。毎日は everyDays と atHour、毎週は onWeekDay、毎月は onMonthDay、N分おきは everyMinutes
- トリガーの時刻には幅があるため、「9時台に届けばよい」通知に向いている
参考・出典
- Google Apps Script リファレンス「Class MailApp」 https://developers.google.com/apps-script/reference/mail/mail-app
- Google Apps Script リファレンス「Class GmailApp」 https://developers.google.com/apps-script/reference/gmail/gmail-app
- Google Apps Script「Quotas for Google Services」 https://developers.google.com/apps-script/guides/services/quotas
- Google Apps Script リファレンス「Class ClockTriggerBuilder」 https://developers.google.com/apps-script/reference/script/clock-trigger-builder
- Google Apps Script リファレンス「Class ScriptApp」「Class Trigger」 https://developers.google.com/apps-script/reference/script/script-app
- Google Apps Script「Installable Triggers」 https://developers.google.com/apps-script/guides/triggers/installable
- Google Apps Script リファレンス「Class LockService」 https://developers.google.com/apps-script/reference/lock/lock-service
- Google Apps Script「Extending Google Sheets」 https://developers.google.com/apps-script/guides/sheets
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「GASでメール送信を自動化|トリガーの定期実行と一斉送信のコード」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。