【無料】チャットワークで複数ルームに一括送信をスプレッドシートのGAS連携で作成!

こんにちは!
ラーメン大好きナカジマです。
麵かためで注文が鉄板です。

chatworkで複数ルームに同じ内容を一括で送信したいときありますよね?

1つ1つコピペして、送信するだけだから負担ではないけど、毎回ポチポチするのはめんどくさいな~、と思った人たちへ
スプレッドシートのマクロ的なGAS(Google Apps Script)を使って、簡単に送信できるシステムを、
非エンジニアの素人なわたしでも作成できたので、同じ想いの人の参考になればと思います!!

素人目線でわかりやすいように説明していきますので、最後までご覧ください!


■新規スプレッドシートを作成

スプレッドシート名は任意で問題ないですが、今回は「チャットワーク一括送信」にします。


■拡張機能

スプレッドシート上部のメニュー → 拡張機能 → Apps Script を選択

下記コードをコピペします。

■コード全文

// Chatworkトークン
const CHATWORK_TOKEN = "ここにチャットワークAPIを貼る";
// メッセージ入力とルーム設定用シートのシート名
const MAIN_SHEET = "シート1";
// ルーム一覧の開始列(E列)
const ROOM_LIST_START_COLUMN = 5;

// 管理用メニューを追加する関数
function onOpen() {
 SpreadsheetApp.getUi()
     .createMenu('GAS')
     .addItem('最新のルーム一覧を読込む', 'getRooms')
     .addItem('メッセージを一斉送信', 'sendBulkMessage')
     .addToUi();
}

// メッセージを一斉送信する関数
function sendBulkMessage() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(MAIN_SHEET);
  const messageCell = sheet.getRange("B2");
  const message = messageCell.getValue();

  if (!message) {
    SpreadsheetApp.getUi().alert('メッセージが入力されていません。B2セルにメッセージを入力してください。');
    return;
  }

  const rooms = getTargetRooms(sheet);
  if (rooms.length === 0) {
    SpreadsheetApp.getUi().alert('送信対象のルームがありません。ルーム一覧で送信対象のルームを設定してください。');
    return;
  }

  const ui = SpreadsheetApp.getUi();
  const roomList = rooms.map(room => `- ${room.name} (ID: ${room.room_id})`).join('\n');
  const confirmMessage = `以下のメッセージを${rooms.length}個のルームに送信しますか?\n\nメッセージ:\n${message}\n\n送信先ルーム:\n${roomList}`;
  
  const response = ui.alert('送信の確認', confirmMessage, ui.ButtonSet.OK_CANCEL);

  if (response == ui.Button.OK) {
    sendMultipleMsg(message, rooms);
    messageCell.clearContent();
    ui.alert('送信完了', 'メッセージを送信しました。', ui.ButtonSet.OK);
  } else {
    ui.alert('キャンセル', '送信をキャンセルしました。', ui.ButtonSet.OK);
  }
}

// 送信対象のルームを取得する関数
function getTargetRooms(sheet) {
  const lastRow = sheet.getLastRow();
  const lastColumn = sheet.getLastColumn();
  if (lastRow <= 1 || lastColumn < ROOM_LIST_START_COLUMN + 2) return []; // データが無い場合

  const range = sheet.getRange(2, ROOM_LIST_START_COLUMN, lastRow - 1, 3);
  const values = range.getValues();

  return values
    .filter(row => row[1] > 0 && row[0]) // ルームIDが存在し、投稿対象が1以上
    .map(row => ({
      room_id: row[0],
      name: row[2] || `不明 (ID: ${row[0]})`
    }));
}

// Chatworkにメッセージを送る関数
function postChatwork(roomId, message) {
 const params = {
   "headers" : {"X-ChatWorkToken" : CHATWORK_TOKEN },
   "method" : "POST",
   "payload" : {
     "body" : message,
     "self_unread" : "1"
   }
 };
 const url = `https://api.chatwork.com/v2/rooms/${roomId}/messages`;
 try {
   const response = UrlFetchApp.fetch(url, params);
   if (response.getResponseCode() !== 200) {
     console.error(`Failed to send message to room ${roomId}. Status code: ${response.getResponseCode()}`);
   }
 } catch (error) {
   console.error(`Error sending message to room ${roomId}: ${error}`);
 }
}

// チャットワークに一斉投稿する関数
function sendMultipleMsg(message, rooms) {
  for (let room of rooms) {  
    postChatwork(room.room_id, message);
    console.log(`Sent message to room ${room.room_id} (${room.name})`);
  }
}

// 最新のルーム一覧を読込む関数
function getRooms() {
 const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(MAIN_SHEET);
 const params = {
   headers : {"X-ChatWorkToken" : CHATWORK_TOKEN},
   method : "get"
 };
 const url = "https://api.chatwork.com/v2/rooms";

 try {
   const response = UrlFetchApp.fetch(url, params);
   if (response.getResponseCode() !== 200) {
     throw new Error(`Failed to get rooms. Status code: ${response.getResponseCode()}`);
   }

   const rooms = JSON.parse(response.getContentText());
   const values = [['ルームID', '投稿対象:1', 'ルーム名']];
   
   for (let room of rooms) {
     values.push([room.room_id, "", room.name]);
   }

   sheet.getRange(1, ROOM_LIST_START_COLUMN, values.length, values[0].length).setValues(values);
   SpreadsheetApp.getUi().alert('ルーム一覧を更新しました。');
 } catch (error) {
   console.error(`Error getting rooms: ${error}`);
   SpreadsheetApp.getUi().alert('ルーム一覧の取得に失敗しました。');
 }
}


赤丸箇所に各自のチャットワークAPIを貼り付けます。


■チャットワークAPI

チャットワーク上部メニューのアカウントから、サービス連携 → APIトークンまで進みます。
※APIトークンは第三者に開示しないよう、取り扱いにご注意ください。

トークンが表示されていない場合は、管理者への承認が必要と思われますので、各自で確認してください。

APIトークンをコピーして、スプレッドシートのコードが表示されているApps Scriptに戻ります。

画像の箇所にコピーしたAPIトークンを上書きします。

ctrl+sを押して、GASを保存します。


■ルーム一覧を読み込み

スプレッドシート上部のメニュー → GAS → 最新のルームを読み込み を選択


初回実行時のみ、権限を求められるので、許可やOKを選んで進んでください。


該当アカウントの所持しているルーム一覧がスプレッドシートに記載されます。
F列の「投稿対象」に「1」を入れると、「1」が入っているルーム宛に投稿出来ます。
画像で言えば、「マイチャット」と「テスト1」に一括送信予定です。

次に送りたいメッセージを準備します。
「B1セル」に任意でよいですが、今回は「メッセージ」と入力します。
そして、送信したいメッセージを「B2セル」に入力します。
今回は「てすと送信」とします。

①「送信したいルーム」と②「送りたいメッセージ」の準備が出来たら、スプレッドシート上部のメニュー → GAS → メッセージを一斉送信 を選択


誤送信防ぐために、①「送信したいルーム」と②「送りたいメッセージ」の確認ウィンドウが表示されます。


チャットワークを確認すると同時刻に同内容が対象のルームに送信されていることを確認できました。
これで完了です。おつかれさまでした。

送信完了後はスプレッドシート上のB2セルメッセージは削除されます。

また、B2セルが空白時はエラーがでるようにしています。


https://note.com/nagatsuma/n/n75d7744ca19b
今回のコードは上記記事を参考にさせて頂きました。
記事通りに進めてもうまく実行できずに、Perplexityさん(AI)に相談しながら調整をしていきました。


具体的には、実行不可な原因調査、予約投稿や完了日時の記載は不要なので即時送信するように調整。
あとは、シート1、シート2で分かれていたのをシート1にまとめたり、送信前の確認ウィンドウなど、

Perplexityが一晩でやってくれました(これにはジェバンニもニッコリ)

もし、この記事通りに進めてもうまくいかない場合はお使いのAIに相談してみてください。
適当な回答されるかな~と偏見を持っていましたが、意外に短時間で作成できたのはAIのおかげでした。

また、素人が作成したコードです。
使用に当たって損害等が発生しても責任は負えませんので、自己責任でご使用ください。
質問や相談等も受けられないです。悪しからず。

おわり。


お肉や海産物、カニなどを販売しておりますので、是非見てください!↓