grasys blog

Gmail の内容を要約して Slack へ通知する

こんにちは、mhosoya です。

弊社では、日々のコミュニケーションの基盤として Slack を活用しています。
業務連絡から雑談まで、Slack を利用しています。

そのため、情報はできるだけ Slack に集約させたい!!! と思っています。

Slack から離れることなく、他での状況を把握できるように目指していきたいと思います。

そのため、今回は指定の Gmail の内容を要約させて Slack に通知させようかと思います。

今回、 Google Workspace Studio(旧Workspace Flows)を使用して実現していきます。

Google Workspace Studio (旧 Workspace Flows )とは

Google Workspace Studio は、Gemini を使用して Google Workspace サービス全体で日常の定型的なタスクをノーコードで自動化できるオンライン アプリです。

Google Workspace の有料プランを契約していれば、基本機能として Google Workspace Studio が含まれています。

全体の流れ

Slack

  1. Slack アプリの作成・設定
  2. Slack アプリの権限を設定する
  3. (省略可) Slack アプリのアイコン画像を設定する
  4. Slack ワークスペース にインストール
  5. Slack アプリを追加する

Google Workspace Studio

  1. GAS(Google Apps Script) で Slack に送信する処理を用意する
  2. Google Workspace Studio で flow を作成する

Slack API でアプリを作成する

Slack アプリの作り方を選択する

  1. Slack API: Applications の画面を開く
  2. Create New App を押下する
  3. From scratch を選択する
Create Slack New App

Slack アプリの基本設定

  1. App Name に 任意の名前 を設定する
    • 今回は Gmail Summarizer を設定します
  2. Pick a workspace to develop your app in に 通知 を送りたい ワークスペース を選択する
New Slack App Settings

Slack アプリの権限を設定する

  1. Features > OAuth & Permissions を選択する
  2. スコープ > ボット トークンのスコープ で下記の OAuth スコープ を追加する
    • chat:write
      • メッセージを送信する権限
Slack App OAuth & Permissions
slack app oauth & permissions

(省略可) Slack アプリのアイコン画像を設定する

今回は、 Nano Banana 2 で生成したアイコン画像を使っていきたいと思います

gmail summarizer icon
  • Settings > Basic Information を選択する
    • App icon & Preview に任意のアイコン画像を設定する
slack app display information

Slack ワークスペース にインストール

  1. Install App > Install to ワークスペース名 を押下する
  2. 作成した アプリ に Slack へのアクセスを許可する
slack api install app
Slack Api Apply Install App

Slack BOT トークン

  • Install App > Installed App Settings のBot User OAuth Token をコピーして控えておく
Copy Slack Bot User OAuth Token

ここまでで Slack Api でのアプリ作成・設定の作業は完了です

Slack アプリを追加する

今回、作成した Slack アプリを追加していきます

App の 三点リーダーメニュー > 管理する > アプリをブラウズする を選択する

add slack app 01

作成した Slack アプリを選択する

add slack app 02

作成した Slack アプリの詳細から「アプリを開く」を押下する

add slack app 03

Slack アプリが追加されたことを確認する

add slack app 04

作成した Slack アプリから DM を送ってみる

Slack メンバー ID をコピーする

プロフィール画面の右下にある三点リーダー から メンバー ID を コピー を選択する
※ここでコピーした Slack のメンバー ID は後ほど使用するため、控えておいてください

copy slack member id 01

copy slack member id 02

DM チャネルをオープンする

USER_ID="U**********"
BOT_TOKEN="xoxb-**********-**************-************************"

curl -X POST \
  -H "Authorization: Bearer $BOT_TOKEN" \
  -H "Content-Type: application/json" \
  --data "{\"users\": \"$USER_ID\"}" \
  https://slack.com/api/conversations.open

レスポンスから channel.id を控えておく

{
  "ok": true,
  "no_op": false,
  "already_open": false,
  "channel": {
    "id": "**ここの値をコピー**"
  },
  "warning": "missing_charset",
  "response_metadata": {
    "warnings": [
      "missing_charset"
    ]
  }
}

上記で取得した channel.id を指定して、DM でメッセージを送信する

BOT_TOKEN="xoxb-**********-**************-************************"
CHANNEL_ID="D**********"

curl -X POST \
  -H "Authorization: Bearer ${BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  --data '{"channel":"'"${CHANNEL_ID}"'", "text":"Hello from bot!"}' \
  https://slack.com/api/chat.postMessage

成功!

{
  "ok": true,
  "channel": "D**********",
  "ts": "1772383582.206849",
  "message": {
    "user": "U**********",
    "type": "message",
    "ts": "1772383582.206849",
    "bot_id": "B**********",
    "app_id": "A**********",
    "text": "Hello from bot!",
    "team": "T********",
    "bot_profile": {
      "id": "B**********",
      "app_id": "A**********",
      "user_id": "U**********",
      "name": "Gmail Summarizer",
      "icons": {
        "image_36": "https://avatars.slack-edge.com/2026-03-01/10619740460705_a5781b3e6a56152a37b2_36.png",
        "image_48": "https://avatars.slack-edge.com/2026-03-01/10619740460705_a5781b3e6a56152a37b2_48.png",
        "image_72": "https://avatars.slack-edge.com/2026-03-01/10619740460705_a5781b3e6a56152a37b2_72.png"
      },
      "deleted": false,
      "updated": 1772381995,
      "team_id": "T********"
    },
    "blocks": [
      {
        "type": "rich_text",
        "block_id": "*****",
        "elements": [
          {
            "type": "rich_text_section",
            "elements": [
              {
                "type": "text",
                "text": "Hello from bot!"
              }
            ]
          }
        ]
      }
    ]
  },
  "warning": "missing_charset",
  "response_metadata": {
    "warnings": [
      "missing_charset"
    ]
  }
}
received direct message.

GAS(Google Apps Script) で Slack に送信する処理を用意する

Slack への送信は、 GAS で実装していきます

Google Workspace Studio の Step でメール受信 -> 要約 -> スプレッドシート に書き込むまでを行います

GAS では要約を書き込まれたのをトリガーとして発火して、 Slack へメッセージを送信します

まずは、 Apps Script を作成します

create gas

続いて、スクリプトを作成します

create gas script

作成したら、 SlackApiClient.gs に下記のコードを貼り付けます

SlackApiClient.gs

class SlackApiClient {
  constructor() {
    const scriptProperties = PropertiesService.getScriptProperties();
    this.SLACK_BOT_TOKEN = scriptProperties.getProperty("SLACK_BOT_TOKEN");
    this.SLACK_USER_ID = scriptProperties.getProperty("SLACK_USER_ID");
    this.SLACK_API_ENDPOINT_CONVERSATIONS_OPEN = "https://slack.com/api/conversations.open";
    this.SLACK_API_ENDPOINT_POST_MESSAGE = "https://slack.com/api/chat.postMessage";

    this.OPTIONS = {
      "method": "post",
      "contentType": "application/json",
      "headers": {
        "Authorization": Utilities.formatString("Bearer %s", this.SLACK_BOT_TOKEN)
      },
    };
  }

  /// DM を開く
  openConversations() {
    const options = this.OPTIONS;
    const payload = {
      "users": this.SLACK_USER_ID
    };
    options["payload"] = JSON.stringify(payload);

    const response = UrlFetchApp.fetch(this.SLACK_API_ENDPOINT_CONVERSATIONS_OPEN, options).getContentText();
    const json = JSON.parse(response);
    return json.channel.id;
  }

  /// メッセージを送信
  postMessage(message, channelId) {
    const options = this.OPTIONS;
    const payload = {
      "channel": channelId,
      "text": message,
    };
    options["payload"] = JSON.stringify(payload);

    const response = UrlFetchApp.fetch(this.SLACK_API_ENDPOINT_POST_MESSAGE, options).getContentText();
  }
}

続いて、 デフォルトで作成されていた コード.gs に下記を貼り付けます

コード.gs

const SHEET_NAME = "queue";
const START_ROW = 2;
const START_COLUMN = 1;
const MESSAGE_COLUMN_INDEX = 1;
const IS_NOTIFIED_COLUMN_INDEX = 2;
const SLACK_API_ENDPOINT_CONVERSATIONS_OPEN = "https://slack.com/api/conversations.open"

function onChanged(e) {
  if (e.changeType == 'EDIT') {
    const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
    const cellRange = sheet.getRange(START_ROW, START_COLUMN, sheet.getLastRow(), sheet.getLastColumn())
    const values = cellRange.getValues();
    if (values.length === 0) return;

    for (const rowIndex in values) {
      const row = values[rowIndex];
      const is_notified = row[IS_NOTIFIED_COLUMN_INDEX];
      if (is_notified !== false) continue;

      const startRowIndex = Number(START_ROW) + Number(rowIndex);
      const notifiedCell = sheet.getRange(startRowIndex, IS_NOTIFIED_COLUMN_INDEX + 1, 1, 1);
      notifiedCell.setValue("TRUE");

      const message = row[MESSAGE_COLUMN_INDEX];
      sendSlackMessage(message);
    }
  }
}

function sendSlackMessage(message) {
  const slackApiClient = new SlackApiClient();
  const channelId = slackApiClient.openConversations();
  slackApiClient.postMessage(message, channelId);
}

GAS の実装はこれで完了です

続いて、スクリプト プロパティ に下記を設定します

最後に、 スクリプト プロパティ を保存 を押下する

gas script property

Google Workspace Studio からメールの要約を書き込むスプレッドシートを用意します

  • シート名
    • queue
      ※GAS にシート名を指定している
  • セル
    • 列 A , B , C に id , message , is_notified のヘッダーを指定する
prepare spread sheet

最後に、 GASTrigger を設定します

  • 実行する関数を選択
    • onChanged
  • イベントのソースを選択
    • スプレッドシートから
  • イベントの種類を選択
    • 変更時
settings gas trigger

これで一通り完了です

ここでテストをしてみます

先ほど、用意した queue シートのセルに適当な文字を入れます

最後に、 is_notified の列に FALSE を入力してください

gas trigger test

メッセージがきました

これでスプレッドシートに書き込めれば、 Slack にメッセージが送信できるのが確認できました

gas trigger test result

Google Workspace Studio で flow を作成する

Google Workspace Studio で指定したメールを受信したら、要約をしてスプレッドシートに書き込むまでをやっていきます

また、汎用的にやるなら flow は同じで良いかと思いますが、今回はメールの種類毎にどのように要約するか指示を変えたいと思っているので、メールの種類ごとで flow は分けます

まずは、 Google Workspace Studio を開きます
※Gmail の下記から Do more in Studio でも開けます

workspace studio icon on gmail

左のメニューの「+」を押下する

workspace studio top
  • flow の名前は Gmail Summarizer で設定します
  • Starterevent には When I get an email を選択します
    • (指定のメールを受信したことをトリガーとするので)
settings flow starter step

今回は、Google Cloud からメールを受信したら、発火するようにしていきたいと思います

settings flow starter step from email

注意

Gmail 側のフィルター設定で、 受信トレイをスキップ (アーカイブする) が有効になっていると発火しません

その場合は、 Gmail 側のアーカイブ設定は無効にして、 Workspace Studio 側でラベル付与とアーカイブをするようにすると発火しつつ、アーカイブまでしてくれます

workspace studio add label and archive

step には Gemini で要約をする Summarize を指定して、下記を設定する

  • What to summarize
    • Email
  • Select email thread
    • Step 1: Email thread ID
  • Additional instructions for Gemini
    • 任意の指示
workspace studio summarize step

step には Add a row を指定して、各項目を指定する
※Add data by column には指定したスプレッドシートの構造が反映されます

workspace studio add a row step

最後に下にある Save changes を押下する

Test run から過去のメールからテストで使用したいメールを選択して実行する

これで Slack に通知が届けば成功です

summarized google cloud message

Slack への送信する部分は GAS を使用しないといけなかったですが、それ以外はノーコードで簡単に設定ができました

また、2025年12月3日 に Custom Step が GA されたのですが、すぐにプレビューに下がってしまいました

残念。。。

この Custom Step を使用すると社内で共有することができます

なので、今回のような GAS で実装した Slack 送信する Step を共有できるので、誰かが汎用的なものを作ってしまえばノーコードで色々とできるようになるかと思います

再度、 Custom Step が GA されるのを期待して待ちたいと思います!

※当社では情報セキュリティの観点から、入力データがGeminiの学習に利用されないよう設定を施し、社内ポリシーに則ってGmailとの連携を行っております。企業様によって生成AIや外部連携に関する運用ルールは異なりますので、本記事の仕組みをお試しになる際は、事前に社内の方針をご確認ください。


採用情報
お問い合わせ