TaxSysTaxSysヘルプページ
Google ミート

Googleミートの自動共有【Chatwork】

Google Meet の録画を自動で保存し、Chatwork に通知する GAS の実装ガイドです

「【MTG】の自動化」とは?

Google Meet の録画データを 自動で共有ドライブに保存 し、Chatwork に通知 する仕組みです。

  • Google Apps Script(GAS)で実装
  • 1 日 3 回(9:00 / 12:00 / 15:00)自動実行
  • 会議名に「【MTG】」を含む録画のみが対象
  • 実際に録画が行われた会議のみ処理
  • 直近 20 件のメールを検索対象とします

GAS のサンプルコード以外のカスタマイズについては、ご自身の責任でお願いします。

Tips1: Google ワークスペースの準備をする

共有ドライブを作成する

録画データの保存先となる共有ドライブ(例: 「MTG データ保管」)を作成してください。

共有ドライブの作成

GAS ファイルを準備する

  1. Google ドライブ(マイドライブ) を開く
  2. 右クリック → 「その他」 → 「Google Apps Script」を選択
右クリックメニューからGoogle Apps Scriptを選択
  1. 警告が表示された場合は「スクリプトを作成」を選択
スクリプトを作成画面
  1. プロジェクト名を「【MTG】MTGデータ保管/CW通知 自動化 GASコード」に変更
プロジェクト名の変更画面
変更後のプロジェクト名
  1. 以下のサンプルコードを貼り付けます(まだ実行しないでください
// ===== 設定 =====

// 修正1: Chatwork API トークン
const CHATWORK_API_TOKEN = '**********';

// 修正2: Chatwork ルームID
const CHATWORK_ROOM_ID = '**********';

// 修正3: Google ドライブ保存先フォルダID
const DRIVE_FOLDER_ID = '**********';

// ===== メイン処理 =====

/**
 * メイン関数: Gmail から【MTG】録画を検索し、共有ドライブに保存 → Chatwork通知
 */
function saveMeetAttachmentsIncremental() {
  const query = buildQuery();
  const threads = GmailApp.search(query, 0, 20);

  if (threads.length === 0) {
    Logger.log('対象のメールはありませんでした');
    return;
  }

  const folder = DriveApp.getFolderById(DRIVE_FOLDER_ID);

  for (const thread of threads) {
    const messages = thread.getMessages();
    for (const message of messages) {
      const subject = message.getSubject();
      if (!subject.includes('【MTG】')) continue;

      const savedFiles = saveDriveFilesFromMessage(message, folder);
      if (savedFiles.length > 0) {
        notifyChatwork(subject, savedFiles);
      }
    }
  }

  // 最終チェック時刻を更新
  PropertiesService.getScriptProperties().setProperty(
    'LAST_CHECK_TIME',
    new Date().toISOString()
  );
}

/**
 * テスト用: 最終チェック時刻をリセット
 */
function resetLastCheckTime() {
  PropertiesService.getScriptProperties().deleteProperty('LAST_CHECK_TIME');
  Logger.log('最終チェック時刻をリセットしました');
}

/**
 * 日次トリガーを作成(9:00, 12:00, 15:00)
 */
function createDailyFixedTriggers() {
  // 既存トリガーを削除
  const triggers = ScriptApp.getProjectTriggers();
  for (const trigger of triggers) {
    ScriptApp.deleteTrigger(trigger);
  }

  // 新規トリガーを作成
  const hours = [9, 12, 15];
  for (const hour of hours) {
    ScriptApp.newTrigger('saveMeetAttachmentsIncremental')
      .timeBased()
      .everyDays(1)
      .atHour(hour)
      .create();
  }

  Logger.log('トリガーを作成しました: 9:00, 12:00, 15:00');
}

// ===== ヘルパー関数 =====

/**
 * Chatwork にメッセージを送信
 */
function sendChatworkNotification(message) {
  const url = `https://api.chatwork.com/v2/rooms/${CHATWORK_ROOM_ID}/messages`;
  const options = {
    method: 'post',
    headers: { 'X-ChatWorkToken': CHATWORK_API_TOKEN },
    payload: { body: message },
  };
  UrlFetchApp.fetch(url, options);
}

/**
 * メールからドライブファイルのリンクを抽出し、指定フォルダにコピー
 */
function saveDriveFilesFromMessage(message, folder) {
  const body = message.getBody();
  const fileIds = extractDriveFileIds(body);
  const savedFiles = [];

  for (const fileId of fileIds) {
    try {
      const file = DriveApp.getFileById(fileId);
      const copy = file.makeCopy(file.getName(), folder);
      savedFiles.push({
        name: copy.getName(),
        url: copy.getUrl(),
      });
    } catch (e) {
      Logger.log(`ファイルのコピーに失敗: ${fileId} - ${e.message}`);
    }
  }

  return savedFiles;
}

/**
 * Chatwork に通知メッセージを組み立てて送信
 */
function notifyChatwork(subject, savedFiles) {
  let message = `[info][title]${subject} - 録画保存完了[/title]`;
  for (const file of savedFiles) {
    message += `${file.name}\n${file.url}\n`;
  }
  message += '[/info]';
  sendChatworkNotification(message);
}

/**
 * Gmail 検索クエリを生成
 */
function buildQuery() {
  const lastCheckTime =
    PropertiesService.getScriptProperties().getProperty('LAST_CHECK_TIME');
  let query = 'subject:【MTG】 has:attachment';
  if (lastCheckTime) {
    const date = new Date(lastCheckTime);
    const formatted = Utilities.formatDate(date, 'JST', 'yyyy/MM/dd');
    query += ` after:${formatted}`;
  }
  return query;
}

/**
 * HTML 本文から Google ドライブのファイル ID を抽出
 */
function extractDriveFileIds(html) {
  const regex = /drive\.google\.com\/file\/d\/([a-zA-Z0-9_-]+)/g;
  const ids = [];
  let match;
  while ((match = regex.exec(html)) !== null) {
    if (!ids.includes(match[1])) {
      ids.push(match[1]);
    }
  }
  return ids;
}

/**
 * 次のトリガー時刻を計算
 */
function nextTriggerTime(hour) {
  const now = new Date();
  const next = new Date(now);
  next.setHours(hour, 0, 0, 0);
  if (next <= now) {
    next.setDate(next.getDate() + 1);
  }
  return next;
}
保存アイコン

重要

コード内の 3 箇所(修正 1〜3)を実際の値に置き換えてから実行してください。

Tips2: Chatwork の準備をする

通知用アカウントを作成する

通知専用の Chatwork アカウントを作成します(無料プランでも可、既存アカウントの流用も可)。

通知用アカウントの作成

参考: Chatwork アカウント登録ガイド

通知先グループを作成する

通知を受け取るグループチャットを作成するか、既存のグループを使用します。

通知先グループチャットの作成
グループチャットの設定

参考: グループチャットの作成

通知用アカウントをグループに追加する

通知用アカウントをグループに追加
グループメンバーの追加画面

参考: メンバーの追加

API トークンを取得する

  1. 通知用アカウントでログイン → 「アカウント」 → 「サービス連携
サービス連携からAPIを選択
  1. API」を選択し、API 利用の申請を行う
API利用の申請画面
  1. Chatwork 管理者が承認する
管理者による承認
  1. API キーを生成してコピーする
APIトークンの生成
APIトークンのコピー

Chatwork ルーム ID を確認する

通知先グループチャットを開き、URL の /g/ の後ろにある数字がルーム ID です。

ChatworkルームIDの確認
URLからルームIDを確認

Google ドライブのフォルダ ID を確認する

共有ドライブの保存先フォルダを開き、URL の /folders/ の後ろにある文字列がフォルダ ID です。

GoogleドライブのフォルダIDの確認
URLからフォルダIDを確認

GAS コードの修正を完了する

サンプルコードの以下 3 箇所を実際の値に置き換えてください。

GASコードの修正箇所
修正箇所設定値
修正 1: CHATWORK_API_TOKEN取得した API トークン
修正 2: CHATWORK_ROOM_ID通知先のルーム ID
修正 3: DRIVE_FOLDER_ID保存先のフォルダ ID
修正後のGASコード
設定値の入力完了
コードの保存

初回実行

  1. GAS エディタで saveMeetAttachmentsIncremental を選択
関数の選択と実行
  1. (実行)ボタンをクリック
実行ボタンのクリック
  1. 初回実行時に権限の承認が求められるので「許可」を選択
権限の承認画面
  1. 続いて createDailyFixedTriggers を実行し、日次トリガーを作成
日次トリガーの作成

テスト方法

resetLastCheckTime 関数を実行すると、最終チェック時刻がリセットされ、過去のメールも再処理されます。テスト完了後は通常実行に戻ります。

resetLastCheckTime関数の実行
テスト実行の結果確認
テスト完了後の状態

商標について

  • GAS(Google Apps Script)は Google LLC の商標です
  • Chatwork は kubell 株式会社の登録商標です