SlackのダイレクトメッセージやメンションをChatworkに自動転送するシステムのセットアップ方法

DX, GAS

  • HOME
  • ブログ
  • DX , GAS
  • SlackのダイレクトメッセージやメンションをChatworkに自動転送するシステムのセットアップ方法

「Slackのメンション、Chatworkでも確認できたら便利なのに…」
「SlackもChatworkも使ってると、通知見逃しちゃうんだよな…」
そんな悩みを解決するGASを開発しました!

このガイドでは、Google Apps Script(GAS)を使って、Slackからのメッセージを自動的にChatworkに転送する機能のセットアップ手順を説明します。

前提条件

以下のものが必要です:

  1. Googleアカウント(Google Apps Scriptを使用するため)
  1. Slackワークスペースの管理者権限またはアプリを追加できる権限
  1. Chatworkアカウントとアクセス権限のあるChatworkのルーム
  1. Slack APIトークンとChatwork APIトークン

セットアップ手順

1. 新しいGoogleスプレッドシートを作成

  1. Google Driveにアクセス
  1. 「新規」 > 「Googleスプレッドシート」をクリック
  1. シートに適切な名前を付ける(例:「Slack-Chatwork Bridge」)

2. Google Apps Scriptプロジェクトを作成

  1. スプレッドシートで「拡張機能」 > 「Apps Script」をクリック
  1. プロジェクト名を変更する(例:「SlackChatworkBridge」)
  1. デフォルトで開かれている コード.gs ファイルの内容を全て削除

3. Slack Chatwork Bridgeライブラリを追加

  1. Apps Scriptエディタで、「ライブラリ」(+)ボタンをクリック
  1. 「スクリプトID」欄に以下のIDを入力:
    1t8W38zqyDrb6rLLf8WRIs4n29_-GcyWSMSI3HHl-MiuA5VrW5YZWRfVY
  1. 「検索」ボタンをクリック
  1. ライブラリ名として「SlackChatworkBridge」が表示される
  1. バージョン選択で最新バージョンを選択
  1. 「追加」ボタンをクリック

4. ユーザー側コードを追加

  1. Apps Scriptエディタで、コード.gs ファイルに以下のコードを貼り付け:

// ========================================================================
// 【設定セクション】ここに必要な情報を入力してください
// ========================================================================
// 初回のみ設定が必要です。設定後にapplyConfigSettingsを実行してください。
// 各項目の説明は以下の通りです。
// ※設定完了後、このファイルにトークン情報が残ります。ファイルの共有設定にご注意ください。

// Chatwork API Token: Chatwork APIを利用するためのトークン
const CHATWORK_API_TOKEN = ""; // ここにChatworkのAPIトークンを入力

// Chatwork Room ID: メッセージを転送するChatworkのルームID
const CHATWORK_ROOM_ID = ""; // ここにChatworkのルームIDを入力

// Chatwork User IDs: 通知したいChatworkユーザーID(複数ある場合はカンマ区切り)
const CHATWORK_USER_IDS = ""; // 例: "12345,67890"

// Slack Verification Token: SlackのEvent APIのVerification Token
const SLACK_VERIFICATION_TOKEN = ""; // ここにSlackの検証トークンを入力

// Slack Bot Token: SlackのBotユーザートークン(xoxb-から始まる)
const SLACK_BOT_TOKEN = ""; // ここにSlackのBotトークンを入力

// Target Slack User ID: 監視対象のSlackユーザーID(特定のユーザーを監視する場合)
const TARGET_SLACK_USER_ID = ""; // 必要な場合のみ入力
// ========================================================================

/**
 * 設定を適用する関数
 * この関数を実行すると、上記で設定した値がプロパティに保存されます
 */
function applyConfigSettings() {
  // 上部で定義した変数から設定オブジェクトを作成
  const configObject = {
    "CHATWORK_API_TOKEN": CHATWORK_API_TOKEN,
    "CHATWORK_ROOM_ID": CHATWORK_ROOM_ID,
    "CHATWORK_USER_IDS": CHATWORK_USER_IDS,
    "SLACK_VERIFICATION_TOKEN": SLACK_VERIFICATION_TOKEN,
    "SLACK_BOT_TOKEN": SLACK_BOT_TOKEN,
    "TARGET_SLACK_USER_ID": TARGET_SLACK_USER_ID
  };

  // 設定値を保存
  saveConfigBatch(configObject);

  // 設定状況を確認
  setupProperties();

  Logger.log("設定の適用が完了しました。設定状況は上記のログを確認してください。");
  Logger.log("この後、WebアプリとしてデプロイしてSlackのEvent APIに連携してください。");
}

/**
 * ユーザーの設定を取得する関数
 * ユーザー固有のスクリプトプロパティを利用
 * @return {Object} 設定オブジェクト
 */
function getConfig() {
  // ユーザー固有のプロパティストアを使用(共有されないストア)
  const properties = PropertiesService.getUserProperties();

  // 各設定値を安全に取得
  const config = {
    CHATWORK_API_TOKEN: properties.getProperty('CHATWORK_API_TOKEN') || '',
    CHATWORK_ROOM_ID: properties.getProperty('CHATWORK_ROOM_ID') || '',
    CHATWORK_USER_IDS: properties.getProperty('CHATWORK_USER_IDS') || '',
    SLACK_VERIFICATION_TOKEN: properties.getProperty('SLACK_VERIFICATION_TOKEN') || '',
    SLACK_BOT_TOKEN: properties.getProperty('SLACK_BOT_TOKEN') || '',
    TARGET_SLACK_USER_ID: properties.getProperty('TARGET_SLACK_USER_ID') || ''
  };

  return config;
}

/**
 * 設定値を保存する関数
 * @param {String} key - 設定キー
 * @param {String} value - 設定値
 */
function saveConfig(key, value) {
  if (!key) return false;

  // ユーザー固有のプロパティストアに保存
  const properties = PropertiesService.getUserProperties();
  properties.setProperty(key, value);

  Logger.log(`設定を保存しました: ${key}`);
  return true;
}

/**
 * 複数の設定値をまとめて保存する関数
 * @param {Object} configObject - 設定オブジェクト
 */
function saveConfigBatch(configObject) {
  if (!configObject || typeof configObject !== 'object') return false;

  const properties = PropertiesService.getUserProperties();

  for (const key in configObject) {
    if (configObject[key]) {
      properties.setProperty(key, configObject[key]);
    }
  }

  Logger.log('設定をまとめて保存しました');
  return true;
}

/**
 * スクリプトプロパティの設定状況を確認する関数
 */
function setupProperties() {
  const config = getConfig();

  // ログに現在の設定状況を出力
  Logger.log('=== 現在のプロパティ設定状況 ===');
  Logger.log(`- Chatwork API Token: ${config.CHATWORK_API_TOKEN ? '設定済み' : '未設定'}`);
  Logger.log(`- Chatwork Room ID: ${config.CHATWORK_ROOM_ID || '未設定'}`);
  Logger.log(`- Chatwork User IDs (通知先): ${config.CHATWORK_USER_IDS || '未設定'}`);
  Logger.log('  ※ Chatwork User IDsはアカウントID(数字)を入力してください。メールアドレスではありません。');
  Logger.log('  ※ ChatworkのプロフィールURLなどから確認できます(例:<https://www.chatwork.com/△△△> の△△△部分)');
  Logger.log(`- Slack Verification Token: ${config.SLACK_VERIFICATION_TOKEN ? '設定済み' : '未設定'}`);
  Logger.log(`- Slack Bot Token: ${config.SLACK_BOT_TOKEN ? '設定済み' : '未設定'}`);
  Logger.log(`- Target Slack User ID: ${config.TARGET_SLACK_USER_ID || '未設定'}`);

  Logger.log('\\n=== 設定方法のガイド ===');
  Logger.log('1. プロパティを設定するには以下のコードを実行してください:');
  Logger.log('   saveConfig("CHATWORK_API_TOKEN", "あなたのChatworkトークン");');
  Logger.log('   saveConfig("CHATWORK_ROOM_ID", "転送先のルームID");');
  Logger.log('   ... その他の設定も同様に ...');
  Logger.log('2. まとめて設定するには saveConfigBatch({キー: 値, ...}); を使います');
  Logger.log('3. 設定後、再度 setupProperties() を実行して設定状況を確認できます');
}

/**
 * WebアプリのGETリクエスト処理
 */
function doGet(e) {
  return SlackChatworkBridge.doGet(e);
}

/**
 * SlackからのPOSTリクエスト処理
 * イベントの受信とChatworkへの転送を行います
 */
function doPost(e) {
  try {
    // URL検証チャレンジだけは直接処理する(重要)
    if (e && e.postData) {
      const jsonData = JSON.parse(e.postData.contents);
      if (jsonData.type === 'url_verification') {
        return ContentService.createTextOutput(jsonData.challenge);
      }
    }

    // ユーザー設定を取得
    const config = getConfig();

    // 新しいライブラリ関数を呼び出し、設定を引数として渡す
    return SlackChatworkBridge.doPost(e, config);
  } catch (error) {
    Logger.log('doPost処理エラー: ' + error.toString());
    return ContentService.createTextOutput('OK');
  }
}

/**
 * テストメッセージを送信する関数
 */
function testForwarding() {
  // ユーザー設定を取得して引数として渡す
  const config = getConfig();
  SlackChatworkBridge.testForwarding(config);
}

/**
 * SlackとChatworkの接続をテストする関数
 */
function testConnection() {
  // ユーザー設定を取得して引数として渡す
  const config = getConfig();
  SlackChatworkBridge.testConnection(config);
}

/**
 * トラブルシューティングのための診断情報を表示する関数
 */
function troubleshoot() {
  Logger.log("=== トラブルシューティング開始 ===");

  // 設定情報を確認
  const config = getConfig();
  const keys = [
    'CHATWORK_API_TOKEN',
    'CHATWORK_ROOM_ID',
    'CHATWORK_USER_IDS',
    'SLACK_VERIFICATION_TOKEN',
    'SLACK_BOT_TOKEN',
    'TARGET_SLACK_USER_ID'
  ];

  // 現在の設定状況を表示
  Logger.log("1. ユーザー側の設定状況:");
  for (const key of keys) {
    const value = config[key] || '未設定';
    const displayValue = key.includes('TOKEN') ? (value !== '未設定' ? '設定済み' : '未設定') : value;
    Logger.log(`- ${key}: ${displayValue}`);
  }

  // 接続テスト
  Logger.log("\\n2. 接続テストを実行...");
  try {
    testConnection();
  } catch (e) {
    Logger.log(`接続テストでエラーが発生しました: ${e.toString()}`);
  }

  // デプロイ情報を確認
  Logger.log("\\n3. デプロイ情報:");
  try {
    const url = ScriptApp.getService().getUrl();
    Logger.log(`- WebアプリURL: ${url || '情報を取得できません'}`);
  } catch (e) {
    Logger.log(`- WebアプリURL: 取得できません (${e.toString()})`);
  }

  Logger.log("\\n4. ライブラリ情報:");
  try {
    const libraryInfo = SlackChatworkBridge.getLibraryInfo();
    Logger.log(`- 名前: ${libraryInfo.name}`);
    Logger.log(`- バージョン: ${libraryInfo.version}`);
    Logger.log(`- 説明: ${libraryInfo.description}`);
    Logger.log(`- セキュリティモデル: ${libraryInfo.securityModel}`);
  } catch (e) {
    Logger.log(`- ライブラリ情報の取得に失敗: ${e.toString()}`);
  }

  Logger.log("=== トラブルシューティング完了 ===");
}

/**
 * すべての設定を消去する関数(注意: すべての設定が削除されます)
 */
function clearAllConfig() {
  const properties = PropertiesService.getUserProperties();
  properties.deleteAllProperties();
  Logger.log('すべての設定を削除しました。setupProperties() を実行して確認できます。');
}
  1. 保存 でコードを保存

5. 必要な設定情報の準備

5.1 Chatwork APIトークンの取得

Chatworkの仕様が自分のアカウントのAPIトークンで自分に対してToメッセージを送っても通知が来ない(未読マークもつかない)となっているので、BotとなるChatworkアカウントを作成して、そのBotアカウントのAPIトークンを使用をオススメします。
  1. Chatworkにログインし、Chatwork画面の右上にある「利用者名」以下のメニュー内にある「サービス連携」をクリック
  1. 左側メニューの「APIトークン」をクリック
  1. 表示されたAPIトークンをメモ

5.2 Chatworkルームの準備とルームIDの取得

  1. 転送先にするルームを開く(既存のルームでも新規作成でも可)
  1. ブラウザのURLから数字のみの部分をメモ
    • 例: https://www.chatwork.com/#!rid12345678 の場合、12345678 がルームID

5.3 Slackアプリケーションの作成

  1. Slack API にアクセスし、「Create New App」をクリック
  1. 「From Scratch」を選択
  1. アプリ名(例:「Chatwork連携」)と作成するSlackワークスペースを選択
  1. 「Create App」をクリック

5.4 Slackボットトークンの取得

  1. 左側メニューの「OAuth & Permissions」をクリック
  1. 「Scopes」セクションで「Bot Token Scopes」に以下の権限を追加:
    • channels:read – パブリックチャンネルの情報の読み取り
    • groups:read – プライベートチャンネルの情報の読み取り
    • users:read – ユーザー情報の読み取り
    • im:read – DMの読み取り
  1. ページ上部の「Install to Workspace」ボタンをクリック
  1. 表示される認証画面で「許可する」をクリック
  1. インストール後に表示される「Bot User OAuth Token」(xoxb-で始まる)をメモ

5.5 Slack検証トークンの取得

  1. 左側メニューの「Basic Information」をクリック
  1. 「App Credentials」セクションの「Verification Token」をメモ

5.6 監視対象SlackユーザーのユーザーIDを取得

  1. 監視対象とするユーザー(DMやメンションを転送したいユーザー)のSlackプロフィールを開く
  1. ユーザーの「・・・」をクリック
  1. 「メンバーIDをコピー」を選択(通常はUで始まるID)
  1. コピーしたユーザーIDをメモ

6. Apps Scriptの設定

  1. Apps Scriptエディタで、最上部の変数にAPIトークンやIDを入力:

const CHATWORK_API_TOKEN = "取得したChatworkのAPIトークン";
const CHATWORK_ROOM_ID = "取得したChatworkのルームID";
const CHATWORK_USER_IDS = "通知したいChatworkユーザーID(オプション)";
const SLACK_VERIFICATION_TOKEN = "取得したSlackの検証トークン";
const SLACK_BOT_TOKEN = "取得したSlackのボットトークン";
const TARGET_SLACK_USER_ID = "監視対象のSlackユーザーID";
  1. ファイルを保存後、applyConfigSettings 関数を選択して実行ボタン(再生アイコン)をクリック
  1. 初回実行時に権限確認が表示されるため「許可」を選択
  1. 実行ログに「設定の適用が完了しました」と表示されることを確認

7. WebアプリとしてデプロイしURLを取得

  1. 「デプロイ」ボタンをクリック
  1. 「新しいデプロイ」を選択
  1. 「種類の選択」で「ウェブアプリ」を選択
  1. 説明に「Slack-Chatwork Bridge」などと入力
  1. 「次のユーザーとして実行」は「自分」を選択
  1. 「アクセスできるユーザー」は「全員」を選択
  1. 「デプロイ」ボタンをクリック
  1. 表示されるウェブアプリURLをコピー

8. Slackでのイベント設定

  1. Slack APIに戻り、作成したアプリを選択
  1. 左側メニューから「Event Subscriptions」を選択
  1. 「Enable Events」をオンにする
  1. 「Request URL」欄に、先ほどコピーしたウェブアプリのURLを貼り付け
  1. URLが検証されるまで待つ(緑色のチェックマークが表示されればOK)
  1. 「Subscribe to events on behalf of users」セクションで以下のイベントを追加:
    • message.im – DMを監視するため
    • message.channels – 公開チャンネルのメンション監視のため
    • message.groups – プライベートチャンネルのメンション監視のため(必要な場合)
  1. 「Save Changes」ボタンをクリック

9. 動作確認

  1. Apps Scriptエディタに戻り、testConnection 関数を実行
  1. ログに「Chatwork接続成功」と「Slack接続成功」のメッセージが表示されることを確認
  1. testForwarding 関数を実行し、テストメッセージがChatworkに転送されるか確認
  1. 実際の動作テスト:
    • Slackで監視対象ユーザーにDMを送信
    • 公開チャンネルで監視対象ユーザーをメンション(@ユーザー名)
    • これらのメッセージがChatworkに転送されることを確認

10. トラブルシューティング

もし設定がうまくいかない場合は、以下の手順でトラブルシューティングを行ってください。

  1. troubleshoot 関数を実行し、設定状況や接続状態を確認
  1. 各種トークンやIDが正しく設定されているか再確認
  1. Slackの「Event Subscriptions」でURLが検証されているか確認
  1. デプロイが成功しているか、そしてURLが正しくSlackに設定されているか確認
  1. エラーが発生している場合は、Apps Scriptの実行ログを確認(「表示」>「ログ」)

主なエラーケース:

  • 「Chatwork API呼び出し失敗」: ChatworkのAPIトークンかルームIDが正しくないか、権限が不足
  • 「Slack認証エラー」: SlackのBoTトークンが正しくないか失効している
  • URL検証失敗: SlackのVerification TokenとGoogle Apps Scriptの設定が一致していない

よくあるご質問

Q: Chatworkにメッセージは転送されますが通知されません

A: Chatworkの仕様でAPIトークンを発行したChatworkアカウントだとToメッセージでも通知が来ません。そこで、BotとなるChatworkアカウントを作成して、そのBotアカウントのAPIトークンを使用することで通知が来るようにできます。

設定項目の詳細説明

設定キー 説明
CHATWORK_API_TOKEN ChatworkのAPIトークン(API設定からメッセージ送信権限をつけて発行)
CHATWORK_ROOM_ID 転送先のChatworkルームID(URLから取得できる数字)
CHATWORK_USER_IDS 通知するChatworkユーザーID(任意、複数はカンマ区切り)
SLACK_VERIFICATION_TOKEN SlackのApp Credentials内にあるVerification Token
SLACK_BOT_TOKEN SlackのOAuthセクションにあるBot User OAuth Token(xoxb-で始まる)
TARGET_SLACK_USER_ID 監視対象のSlackユーザーID(通常Uで始まる)

まとめ

お疲れ様でした!これで、Slackの重要なメンションやDMを見逃すリスクを減らし、Chatworkで効率的に情報をキャッチアップできるようになりました。

このGASスクリプトは、あくまで一例です。特定のチャンネルのメッセージだけを転送したり、メッセージの内容に応じて通知先を変えたりするなど、さらにカスタマイズすることも可能です。ぜひ、ご自身の使い方に合わせて改良してみてください。

もし設定で困ったことや、「もっとこうしたい」という要望があれば、お気軽にコメントなどで教えてください。

関連記事一覧