マキモノ
Google Workspace無料✅ 公式検証済みv1.0.0 / 更新

シートに打合せ日時を書くだけでカレンダー予定+Meet発行+前日リマインドGmail下書き(Apps Script)

案件シートの日時列を15分巡回し、Calendar API v3でMeet付き予定を作成、前日9時以降に顧客宛リマインドを下書きで1回だけ作る。招待メール抑止・冪等キー・日時変更追従つき

出品者: kim@orgiast.jp📖 読込 約1,879トークン (約3円)💰 コスパ 75倍
トークン節約メーター78%節約
ゼロからAIに作らせた場合約18万トークン
このMDを読ませた場合約4万トークン

約14万トークンの節約 (API料金換算で約210円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。

この巻物について

「シートに打合せ日時を書くだけでカレンダー予定+Meet発行+前日リマインドGmail下書き(Apps Script)」は、Google WorkspaceカテゴリのAI指示書(MDファイル)です。案件シートの日時列を15分巡回し、Calendar API v3でMeet付き予定を作成、前日9時以降に顧客宛リマインドを下書きで1回だけ作る。招待メール抑止・冪等キー・日時変更追従つきこの巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約14万トークン(API料金換算で約210円)・78%のトークンを節約できます。

カテゴリ
Google Workspace
対応AI
claude-code、cursor、codex-cli
ライセンス
商用利用可 (再販不可)
価格
無料
ゼロから開発時
約18万トークン
この巻物使用時
約4万トークン
節約量
約14万トークン (約210円)
更新日
2026-10-01

使い方 (AIに渡す3つの方法)

いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。

⬇ .md をダウンロード
claude "https://makimono-md.vercel.app/api/v1/files/meet-gmail-apps-script/raw を読み込んで、この指示書どおりに実装して"
claude-codecursorcodex-cliライセンス: 商用利用可 (再販不可)

中身

スプレッドシートに打合せ日時を書くだけで「カレンダー予定+Meet発行+前日リマインドGmail下書き」を自動化する(Apps Script)

できること

  • 案件一覧シートの「次回打合せ日時」に値を入れると、Google カレンダーに予定を作り Meet URL を発行する
  • 打合せ前日 9:00 以降に、顧客宛「明日はよろしくお願いします+Meet URL」の Gmail 下書きを1回だけ作る(送信はしない=人が最終確認して送る)
  • 日時を変更すると予定を更新し、前日下書きも新日時で作り直す

前提

  • シートにバインドした Apps Script(V8, タイムゾーン Asia/Tokyo)
  • Advanced Service「Calendar API v3」を有効化
  • appsscript.json の oauthScopes に https://www.googleapis.com/auth/calendar と https://www.googleapis.com/auth/gmail.compose(環境により GmailApp.createDraft は https://mail.google.com/ を要求する。認可エラーが出たら追加)

列設計(ヘッダ名で引く。列番号ハードコード禁止)

ヘッダ記入者内容
次回打合せ日時人日付のみなら 10:00 とみなす、所要60分
顧客メール人/自動空なら顧客マスタから社外アドレスが一意に取れた時だけ補完
打合せイベントIDシステムCalendar の event.id
前日下書き済システム下書きを作った「打合せ日時」の文字列(冪等キー)

ヘッダが無ければ末尾に追加する ensureColumns() を用意し、既存列の位置は動かさない。

巡回 sweep()(15分毎の時間トリガー)

function sweep() {
  const lock = LockService.getDocumentLock();
  if (!lock.tryLock(30000)) return;
  try {
    const now = new Date();
    for (const row of readRows()) {          // ヘッダ名→値のオブジェクト
      try { processRow(row, now); } catch (e) { console.error(row.id, e); }
    }
  } finally { lock.releaseLock(); }
}

function processRow(r, now) {
  const start = parseJst(r['次回打合せ日時']);
  if (!start || start <= now) return;          // 空・過去は何もしない
  let ev;
  if (!r['打合せイベントID']) {
    ev = Calendar.Events.insert({
      summary: `【打合せ】${r.client} ${r.name}`,
      start: { dateTime: start.toISOString() },
      end:   { dateTime: new Date(start.getTime() + 3600e3).toISOString() },
      conferenceData: { createRequest: { requestId: Utilities.getUuid(),
        conferenceSolutionKey: { type: 'hangoutsMeet' } } },
      // attendees は入れない:顧客を入れると招待メールが自動送信される
    }, CAL_ID, { conferenceDataVersion: 1, sendUpdates: 'none' });
    writeCell(r, '打合せイベントID', ev.id);
  } else {
    ev = Calendar.Events.get(CAL_ID, r['打合せイベントID']);
    if (new Date(ev.start.dateTime).getTime() !== start.getTime()) {
      ev.start = { dateTime: start.toISOString() };
      ev.end = { dateTime: new Date(start.getTime() + 3600e3).toISOString() };
      ev = Calendar.Events.update(ev, CAL_ID, ev.id, { sendUpdates: 'none' });
      writeCell(r, '前日下書き済', '');
    }
  }
  const meet = ev.hangoutLink;                 // 発行待ちなら次回再試行
  if (!meet) return;
  const key = start.toISOString();
  const dayBefore9 = new Date(start); dayBefore9.setDate(dayBefore9.getDate() - 1); dayBefore9.setHours(9, 0, 0, 0);
  if (now >= dayBefore9 && r['前日下書き済'] !== key) {
    const { to, subject, body } = draftTemplate(r, start, meet);
    GmailApp.createDraft(to, subject, body);
    writeCell(r, '前日下書き済', key);
  }
}
  • 宛先が空なら宛先なしで作り、件名頭に 【宛先未設定】 を付ける
  • 文面は draftTemplate() に分離して差し替えやすくする

トリガー登録(二重登録防止)

function installTrigger() {
  ScriptApp.getProjectTriggers().filter(t => t.getHandlerFunction() === 'sweep')
    .forEach(t => ScriptApp.deleteTrigger(t));
  ScriptApp.newTrigger('sweep').timeBased().everyMinutes(15).create();
}

落とし穴

  • 下書きとカレンダーはトリガー所有者のアカウントに入る。共有アカウント(制作チーム等)で運用するならそのアカウントで installTrigger を実行する。カレンダーIDは Script Property で指定可能にしておく
  • UI から保存した時は該当行だけ即時 processRow を呼ぶ(15分待たせない)
  • 外部API成功→シート書込み失敗の間で落ちると、再実行で予定が重複し得る。イベント作成直後にIDを書く順序を守る
  • 日時を空欄にしても既存予定は消さない(誤削除防止)。消したい運用なら明示的なキャンセル列を設ける
  • 検証用に下書き本文を getPlainBody で読むと gmail.readonly が要る。本番コードには不要なので、実在確認は GmailApp.getDraft(id).getId() で行う

よくある質問

+「シートに打合せ日時を書くだけでカレンダー予定+Meet発行+前日リマインドGmail下書き(Apps Script)」とは何ですか?

案件シートの日時列を15分巡回し、Calendar API v3でMeet付き予定を作成、前日9時以降に顧客宛リマインドを下書きで1回だけ作る。招待メール抑止・冪等キー・日時変更追従つき

+どれくらいトークン(費用)を節約できますか?

ゼロから開発すると約18万トークンかかりますが、この巻物を使えば約4万トークンで済みます。差し引き約14万トークン(API料金換算で約210円)・78%の節約です。

+どうやって使いますか?

無料です。MDファイルを Claude Code などのAIに読み込ませるだけ。ワンライナーをターミナルに貼れば実装が始まります。要件定義や技術調査を省いて実装だけにトークンを使えます。

+どのAIツールに対応していますか?

claude-code、cursor、codex-cli に対応しています。

+商用利用できますか?

ライセンスは「商用利用可 (再販不可)」です。

🤝 自分でAIを動かすのは、まだ不安…という方へ

この巻物の内容を、AIを使うプロに丸ごと任せることもできます。姉妹サービスAI代行堂なら「LINEで頼むだけで、仕事が完成」。

AI代行堂を見る →

関連する巻物

この巻物、誰かのトークンも救えます

𝕏 で節約レシートをシェア