Contents
導入とクイックスタート — Notion と Slack 連携 手順
Notion と Slack 連携 手順 を短時間で検証したい運用担当・開発者向けに、最短で動かす手順と運用の要点を整理します。Notion と Slack 連携 手順 の準備、公式連携、外部ツール、カスタム実装、テストと運用までを順に説明します。
クイックスタート(3ステップ)
まずは最短で動かすための実行手順を示します。3ステップで通知が届くことを確認してください。
- Notionでテスト用データベースを作成する(必須プロパティ: Title、Status、Assignee、Due、Notified(Checkbox))。
- Notion公式のSlack連携を有効にし、Automationsで「新規ページ作成 → Send Slack message」を作成してプロパティを差し込む。
- テストページを作り、Slackで受信されることとNotifiedが更新されることを確認する。
公式連携(Notion Automations と Slackアプリ)
公式の組み合わせは最短で動作確認でき、運用負荷も低い選択肢です。管理者承認さえクリアできれば、まずはこちらで基本フローを固めます。
導入手順
以下は管理者権限があることを前提にした手順です。管理者承認やワークスペースの制限に注意してください。
- SlackのApp DirectoryからNotionアプリをインストールするか、Notion側の設定画面からSlack連携へ進みます。
- インストール時に表示されるOAuthスコープを確認して承認します(管理者承認が必要な場合は申請フローを用意)。
- Notionで対象データベースを共有し、Automationsでトリガーと「Send Slack message」アクションを作成します。
Automationsでのテンプレート例
Automationsはシンプルなメッセージ向けです。複雑なBlock Kitは使えない点に注意してください。
- メッセージテンプレート(プレーンテキスト/マークダウン風)例:
新しいタスク: {{Title}}
担当: {{Assignee}}
期限: {{Due}}
<{{Page URL}}|Notionで開く>
注意点: プライベートチャンネルへ投稿する場合はBotをチャンネルへ招待する必要があります。Automationsの実行ログで失敗理由を確認してください。
外部自動化ツールの選定と比較(Zapier / Make / n8n)
外部ツールは柔軟にBlock Kitや条件分岐を組めますが、コストや実行頻度の制約があるため選定基準を明確にします。
共通設計のポイント
外部ツールを使う際の基本設計要素です。これに沿えば移植性が高まります。
- Notion Integrationを作成し、対象DBを共有する。
- トリガー(新規ページ、プロパティ変更など)を選ぶ。
- PeopleやSelectはネストを解く(例: Assignee.name)。
- Slackへはchat.postMessage相当で投稿。Block KitはJSON組立てで送る。
- 投稿後にNotifiedフラグを更新して重複を防ぐ。
ツール比較(概略)
下表は選定の参考です。実行回数やポーリング間隔はプランにより変わるため、導入前に必ず確認してください。
| ツール | コストの目安 | 実行頻度 | セルフホスト | 向く用途 |
|---|---|---|---|---|
| Zapier | SaaS、無料枠あり | 無料はポーリング遅め | いいえ | 簡単なワークフロー、初心者向け |
| Make | SaaS、柔軟なJSON操作 | 中〜高、プラン次第 | いいえ | 複雑なデータ変換・連携 |
| n8n | OSS(セルフホスト可) | 自ホスト次第で高頻度 | はい | カスタム要件・自社運用向け |
比較のポイントは「コスト」「実行回数」「セルフホスト可否」「管理責任」です。組織のポリシーに合わせて選んでください。
カスタム実装:Notion API と Slack API(サンプルと仕様)
自由度を重視する場合はカスタム実装が有効です。ここでは必要スコープ、代表的なエンドポイント、署名検証、コードサンプルを示します。
必要スコープと管理者承認の目安
権限は最小化が基本です。以下は典型的な最小スコープです。実際の組織ポリシーにより管理者承認が必要になります。
- Notion(OAuthの場合/Integrationの場合は共有で権限付与):
- databases.read(DBクエリ)
- pages.read / pages.write(ページ取得・更新)
-
blocks.read / blocks.write(ブロック操作が必要な場合)
組織のセキュリティポリシーによりOAuth承認が必要です。 -
Slack(Botアプリの代表的な最小スコープ):
- chat:write(Botとしてメッセージ送信)
- chat:write.public(Botがチャンネル未参加でも投稿する場合)
- channels:read / groups:read(チャンネル一覧やプライベート判定)
- commands(Slashコマンドを使う場合)
ワークスペースのアプリインストール方針により管理者承認が発生します。
詳細は公式ドキュメントを参照してください(Notion APIとSlack APIのドキュメント)。
代表的なエンドポイント(概要)
- Notion: POST /v1/databases/{database_id}/query、GET /v1/pages/{page_id}、PATCH /v1/pages/{page_id} など。
- Slack: POST /api/chat.postMessage、POST /api/chat.postEphemeral、OAuth用エンドポイントなど。
以下はNotionデータベースクエリのcurl例(ヘッダやバージョンは例示です。最新版は公式ドキュメントを確認してください)。
|
1 2 3 4 5 6 7 8 9 10 11 |
curl -X POST "https://api.notion.com/v1/databases/{database_id}/query" \ -H "Authorization: Bearer $NOTION_TOKEN" \ -H "Notion-Version: 2022-06-28" \ -H "Content-Type: application/json" \ -d '{ "filter": { "property": "Status", "select": { "equals": "Todo" } } }' |
Node.js 実装例(取得→Slack通知→Notified更新)
以下は実運用で使う際の最小例です。プロパティ名は本文で統一して「Title」「Assignee」「Due」「Notified」を扱います。エラーハンドリングやレート制御は実運用で拡張してください。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
// 必要: npm i @notionhq/client @slack/web-api const { Client } = require('@notionhq/client'); const { WebClient } = require('@slack/web-api'); const notion = new Client({ auth: process.env.NOTION_TOKEN }); const slack = new WebClient(process.env.SLACK_BOT_TOKEN); // ページを取得してSlackへ通知し、Notifiedを立てる関数 async function notifyPage(pageId, channel) { try { const page = await notion.pages.retrieve({ page_id: pageId }); // Titleプロパティ抽出(プロパティ名は "Title" を想定) const title = (page.properties?.Title?.title?.[0]?.plain_text) || '(無題)'; // Assignee(People)は配列を結合して表示 const assignees = (page.properties?.Assignee?.people || []) .map(p => p.name || p.id) .join(', ') || '(未割当)'; const due = page.properties?.Due?.date?.start || '未設定'; const url = page.url || `https://www.notion.so/${pageId.replace(/-/g, '')}`; // SlackへBlock Kitで投稿(簡易例) const post = await slack.chat.postMessage({ channel, text: `新しいタスク: ${title}`, blocks: [ { type: 'header', text: { type: 'plain_text', text: `新しいタスク: ${title}` } }, { type: 'section', text: { type: 'mrkdwn', text: `*担当*: ${assignees}\n*期限*: ${due}\n<${url}|Notionで開く>` } } ] }); if (!post.ok) { console.error('Slack error:', post.error); return; } // Notifiedチェックを立てて重複防止 await notion.pages.update({ page_id: pageId, properties: { Notified: { checkbox: true } } }); } catch (err) { // レート制限やAPIエラーのハンドリングをここに追加 console.error('notifyPage error:', err); throw err; } } |
- 注: Notionのpeople配列内の要素はnameが存在しない場合もあるため、フォールバックが必要です。
- 注: 実運用では指数バックオフやリトライ、キュー(SQS等)を組み合わせてください。
Slackの受信Webhook(署名検証)サンプル(Node.js/Express)
Slackの受信エンドポイントでは署名検証が必須です。以下は基本的な検証例です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
const express = require('express'); const crypto = require('crypto'); const bodyParser = require('body-parser'); const app = express(); // raw bodyを保持するための設定 app.use(bodyParser.json({ verify: (req, res, buf) => { req.rawBody = buf; } })); app.post('/slack/commands', (req, res) => { const timestamp = req.headers['x-slack-request-timestamp']; const signature = req.headers['x-slack-signature']; const fiveMin = 60 * 5; // リプレイ攻撃防止 if (Math.abs(Math.floor(Date.now() / 1000) - Number(timestamp)) > fiveMin) { return res.status(400).send('ignore'); } const base = `v0:${timestamp}:${req.rawBody.toString()}`; const hmac = crypto.createHmac('sha256', process.env.SLACK_SIGNING_SECRET); hmac.update(base); const expected = `v0=${hmac.digest('hex')}`; // タイミングアタック対策で timingSafeEqual を使用 if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature || ''))) { return res.status(401).send('verification failed'); } // ここでpayloadを処理(例えばNotionにページを作るなど) res.send('OK'); }); app.listen(3000); |
詳細はSlack公式の「Verifying requests from Slack」を参照してください。
Block Kit の具体例(JSON)
下記はSlackに投げるBlock Kitの例です。ボタンでNotionページへ誘導します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
{ "blocks": [ { "type": "header", "text": { "type": "plain_text", "text": "新しいタスク: サンプルタイトル" } }, { "type": "section", "fields": [ { "type": "mrkdwn", "text": "*担当*\n佐藤太郎" }, { "type": "mrkdwn", "text": "*期限*\n2026-06-30" } ] }, { "type": "actions", "elements": [ { "type": "button", "text": { "type": "plain_text", "text": "Notionで開く" }, "url": "https://www.notion.so/ページID" } ] } ] } |
テスト・運用・トラブルシューティング(監視・ログ・ガバナンス)
導入後の安定稼働にはテスト設計と運用ルールの明確化が重要です。ここでは具体的な検証手順、典型的なエラー例と対処、運用上のベストプラクティスを示します。
テスト手順と期待レスポンス例
まずはテスト環境で以下を検証します。ログは実行IDごとに残すとトラブル切り分けが速くなります。
- テスト手順:
- テスト用タスクを作成しSlackに通知が届くか確認する。
- NotionでNotifiedがtrueになるか確認する。
-
空の担当、複数担当、長文などを試しフォーマット崩れがないか確認する。
-
Slack API成功例(簡易):
|
1 2 |
{ "ok": true, "channel": "C012345", "ts": "1620000000.000100", "message": { "text": "..." } } |
- Slack APIエラー例:
|
1 2 |
{ "ok": false, "error": "missing_scope" } |
- Notion API成功例(データベースクエリの抜粋):
|
1 2 |
{ "object": "list", "results": [ /* pages... */ ], "next_cursor": null } |
- Notion APIエラー例(例):
|
1 2 |
{ "object": "error", "status": 401, "code": "unauthorized", "message": "..." } |
エラーが出たら、まずはAPIのHTTPステータスとレスポンスbodyをログで確認し、権限・トークン・対象IDの誤りをチェックしてください。
よくある障害と対処法(具体例)
- 403 / insufficient_scope(Slack): Botがチャンネルに参加しているか、chat:write等のスコープが不足していないか確認。
- 401 / unauthorized(Notion): IntegrationがDBを共有されているか、トークンが正しいかを確認。
- 重複投稿: Notifiedフラグや処理済みIDをDB/キューで管理しデデュープする。
- レート制限: 429等が返る場合は指数バックオフとバッチ化を実装する。
- マッピング不整合: Notionプロパティ名や型が変更された場合は事前に検証ルーチンを用意する。
例外ケースの期待挙動
- 複数担当者: Assigneeのnameをカンマ結合して表示する。空なら "(未割当)" 表示。
- 空フィールド: フォールバック値(未設定等)をテンプレートで用意する。
- 長文(Description等): Slack側で折りたたむか、スレッドへ分割する。Blockの長さ制限に注意する。
運用・セキュリティの具体策
- トークン管理とローテーション:
- 目安: 長期運用トークンは90日ごとのローテーションを推奨。高リスク環境では30〜60日。
- ローテーショントリガー: 人事異動、漏洩疑い、キーがコミットされた場合は即時ローテーション。
- Secret Manager運用例:
- AWS Secrets Manager: シークレットにKMSを使用し、Lambdaで自動ローテーションを実装。IAMは最小権限。
- GCP Secret Manager: バージョニングを使って安全にロールアウト。Cloud Scheduler + Cloud Functionで自動更新可能。
- Azure Key Vault: マネージドIDを使い、アクセスはKey Vaultのポリシーで制御。
- ログ運用: Authorizationヘッダやトークンはログに出さない。出す場合はマスキングを徹底する。構造化ログとアクセス制御を設定する。
- 監視とアラート: エラー率やレイテンシの閾値を定め、運用チームへ通知する。Automationsの失敗ログも定期チェックする。
- 2-way同期の設計: 更新ループを避けるため、更新起点を示すメタプロパティ(updated_by_integration等)を設定し、自分が起点の更新イベントは無視するロジックを入れる。
まとめ — Notion と Slack 連携 手順
Notion と Slack 連携 手順 を実務で導入する際は、まず最短の公式連携で動作を確認し、その上で外部ツールかカスタム実装へ拡張してください。導入時は必須プロパティ(Title、Status、Assignee、Due、Notified)を揃え、管理者承認とトークン管理方針を整備することが安定稼働の鍵です。運用ではトークンローテーション、最小権限、レート制御、署名検証、ログの秘匿を徹底してください。
参照(最新の仕様確認に利用してください): Notion API ドキュメント(https://developers.notion.com/)、Slack API(https://api.slack.com/)