Confluence
コラボレーションツール
Confluence
概要
Confluenceは、Atlassian開発のチーム向けコラボレーション・ナレッジマネジメントツールです。企業向けの階層的な情報整理、強力なアクセス制御、豊富な統合機能を提供し、3,000以上のアプリ連携が可能。大企業での標準的なナレッジマネジメントツールとして、Jiraとの統合によりDevOpsワークフローに最適化されています。管理者機能とスケーラビリティで企業向け市場をリードし、チームのドキュメント作成、プロジェクト管理、情報共有を包括的にサポートします。
詳細
Confluence 2025年版は、企業レベルのコラボレーションとナレッジマネジメントにおける決定版ツールとしての地位を確立しています。Atlassianエコシステムの中核として、Jira Software、Bitbucket、Trelloとの密接な統合により、開発チームから経営陣まで全社的な情報管理プラットフォームを提供。豊富なページテンプレート、リアルタイム共同編集、高度な検索機能、カスタムマクロ、レポート機能により、技術文書、プロジェクト計画、会議議事録、ナレッジベースを効率的に管理できます。REST API v2による外部システム連携、SAML SSO、高度な権限管理により、セキュリティと統合性を両立。クラウド版では最新のUI/UXとAI機能を導入し、モダンなワークスペース体験を実現しています。
主な特徴
- 階層的ページ構造: スペース、ページ、サブページによる体系的な情報整理
- リアルタイム共同編集: 複数メンバーによる同時編集とコメント機能
- 豊富なテンプレート: プロジェクト計画、会議議事録、技術仕様書等のテンプレート
- 強力な検索機能: ページ内容、コメント、添付ファイルの包括的検索
- アプリマーケットプレイス: 3,000以上のサードパーティアプリ連携
- 高度な権限管理: スペース、ページ、コンテンツレベルの細かな権限設定
メリット・デメリット
メリット
- Atlassianエコシステムとの完璧な統合によるワークフロー効率化
- 企業レベルのセキュリティとコンプライアンス機能(SOC2、GDPR対応)
- 豊富なテンプレートと業界ベストプラクティスの実装
- 強力なレポート機能とアナリティクスによる利用状況可視化
- 大規模組織対応のスケーラビリティと安定性
- 24/7サポートと充実したドキュメント・トレーニング
- REST APIによる柔軟なシステム統合とカスタマイズ
- 継続的な機能追加とセキュリティアップデート
デメリット
- 高額な利用料金(中小企業には負担が大きい)
- 複雑なUI設定で初期導入時の学習コストが高い
- Atlassianエコシステム外のツールとの統合制限
- オンプレミス版のサポート終了(2024年2月)によるクラウド移行必要
- カスタマイズにはマーケットプレイスアプリが必要で追加コスト発生
- 大量データ時の検索パフォーマンス低下
- 過度に複雑な権限設定による運用負荷増加
参考ページ
- Confluence 公式サイト
- Confluence 公式ドキュメント
- Confluence REST API ドキュメント
- Confluence Marketplace
- Atlassian Community
書き方の例
基本設定とスペース作成
# Confluence Cloudへのアクセス設定
# 1. Atlassianアカウント作成: https://id.atlassian.com
# 2. APIトークン生成: https://id.atlassian.com/manage-profile/security/api-tokens
# 3. 管理権限の確認: 組織管理者から権限付与
# 基本的なスペース構成例
チーム名スペース/
├── プロジェクト管理/
│ ├── プロジェクト計画
│ ├── 進捗レポート
│ └── 完了報告
├── 技術文書/
│ ├── API仕様書
│ ├── アーキテクチャ設計
│ └── 運用手順書
└── 会議記録/
├── 週次ミーティング
├── 月次レビュー
└── 意思決定記録
REST API基本操作
import requests
from requests.auth import HTTPBasicAuth
import json
# Confluence REST API設定
CONFLUENCE_URL = "https://your-domain.atlassian.net"
API_TOKEN = "your-api-token"
EMAIL = "[email protected]"
class ConfluenceAPI:
def __init__(self, base_url, email, api_token):
self.base_url = base_url.rstrip('/')
self.session = requests.Session()
self.session.auth = HTTPBasicAuth(email, api_token)
self.session.headers.update({
'Accept': 'application/json',
'Content-Type': 'application/json'
})
def get_spaces(self):
"""スペース一覧取得"""
url = f"{self.base_url}/rest/api/space"
response = self.session.get(url)
response.raise_for_status()
return response.json()
def get_page(self, page_id, expand="body.storage,version"):
"""ページ情報取得"""
url = f"{self.base_url}/rest/api/content/{page_id}"
params = {"expand": expand}
response = self.session.get(url, params=params)
response.raise_for_status()
return response.json()
def create_page(self, space_key, title, content, parent_id=None):
"""新規ページ作成"""
url = f"{self.base_url}/rest/api/content"
page_data = {
"type": "page",
"title": title,
"space": {"key": space_key},
"body": {
"storage": {
"value": content,
"representation": "storage"
}
}
}
if parent_id:
page_data["ancestors"] = [{"id": parent_id}]
response = self.session.post(url, data=json.dumps(page_data))
response.raise_for_status()
return response.json()
def update_page(self, page_id, title, content, version_number):
"""ページ更新"""
url = f"{self.base_url}/rest/api/content/{page_id}"
page_data = {
"id": page_id,
"type": "page",
"title": title,
"body": {
"storage": {
"value": content,
"representation": "storage"
}
},
"version": {
"number": version_number + 1
}
}
response = self.session.put(url, data=json.dumps(page_data))
response.raise_for_status()
return response.json()
def search_content(self, query, type="page"):
"""コンテンツ検索"""
url = f"{self.base_url}/rest/api/search"
params = {
"cql": f"type={type} and text ~ \"{query}\"",
"expand": "content.body.storage"
}
response = self.session.get(url, params=params)
response.raise_for_status()
return response.json()
# 使用例
confluence = ConfluenceAPI(CONFLUENCE_URL, EMAIL, API_TOKEN)
# スペース一覧表示
spaces = confluence.get_spaces()
for space in spaces['results']:
print(f"スペース: {space['name']} (key: {space['key']})")
# 新規ページ作成
page_content = """
<h1>プロジェクトキックオフ</h1>
<h2>目的</h2>
<p>新プロジェクトの開始に向けた準備と役割分担を明確化する</p>
<h2>参加者</h2>
<ul>
<li>プロジェクトマネージャー: 田中</li>
<li>開発リーダー: 佐藤</li>
<li>デザイナー: 鈴木</li>
</ul>
<h2>スケジュール</h2>
<table>
<tr><th>フェーズ</th><th>期間</th><th>担当</th></tr>
<tr><td>設計</td><td>2週間</td><td>佐藤</td></tr>
<tr><td>実装</td><td>4週間</td><td>開発チーム</td></tr>
<tr><td>テスト</td><td>1週間</td><td>QAチーム</td></tr>
</table>
"""
new_page = confluence.create_page(
space_key="DEV",
title="プロジェクトキックオフ 2025-01-01",
content=page_content
)
print(f"新規ページ作成: {new_page['_links']['webui']}")
ページテンプレートとマクロ活用
<!-- プロジェクト計画テンプレート -->
<ac:structured-macro ac:name="info">
<ac:parameter ac:name="title">プロジェクト基本情報</ac:parameter>
<ac:rich-text-body>
<table>
<tr><th>項目</th><th>内容</th></tr>
<tr><td>プロジェクト名</td><td>[プロジェクト名を入力]</td></tr>
<tr><td>開始日</td><td><time datetime="2025-01-01" /></td></tr>
<tr><td>完了予定日</td><td><time datetime="2025-03-31" /></td></tr>
<tr><td>予算</td><td>[予算を入力]</td></tr>
</table>
</ac:rich-text-body>
</ac:structured-macro>
<!-- ステータスマクロ -->
<h2>プロジェクトステータス</h2>
<ac:structured-macro ac:name="status">
<ac:parameter ac:name="colour">Green</ac:parameter>
<ac:parameter ac:name="title">進行中</ac:parameter>
</ac:structured-macro>
<!-- タスクリスト -->
<h2>タスクリスト</h2>
<ac:task-list>
<ac:task>
<ac:task-id>1</ac:task-id>
<ac:task-status>incomplete</ac:task-status>
<ac:task-body>要件定義書の作成</ac:task-body>
</ac:task>
<ac:task>
<ac:task-id>2</ac:task-id>
<ac:task-status>complete</ac:task-status>
<ac:task-body>チーム編成</ac:task-body>
</ac:task>
</ac:task-list>
<!-- Jira Issues マクロ -->
<ac:structured-macro ac:name="jira">
<ac:parameter ac:name="server">https://your-domain.atlassian.net</ac:parameter>
<ac:parameter ac:name="jqlQuery">project = "MYPROJECT" AND status != Done</ac:parameter>
<ac:parameter ac:name="columns">key,summary,type,status,assignee</ac:parameter>
</ac:structured-macro>
<!-- チームメンバー情報 -->
<h2>チームメンバー</h2>
<ac:structured-macro ac:name="user-profile">
<ac:parameter ac:name="user">@tanaka</ac:parameter>
</ac:structured-macro>
<!-- 会議議事録テンプレート -->
<h1>週次ミーティング議事録</h1>
<ac:structured-macro ac:name="info">
<ac:parameter ac:name="title">ミーティング情報</ac:parameter>
<ac:rich-text-body>
<p><strong>日時:</strong> <time datetime="2025-01-08T10:00" /></p>
<p><strong>場所:</strong> 会議室A / Zoom</p>
<p><strong>司会:</strong> @moderator</p>
<p><strong>書記:</strong> @secretary</p>
</ac:rich-text-body>
</ac:structured-macro>
<h2>参加者</h2>
<ul>
<li><ac:link><ri:user ri:account-id="user1" /></ac:link></li>
<li><ac:link><ri:user ri:account-id="user2" /></ac:link></li>
</ul>
<h2>議事内容</h2>
<h3>前回アクションアイテムの確認</h3>
<!-- 前回の未完了アイテムを参照 -->
<ac:structured-macro ac:name="excerpt-include">
<ac:parameter ac:name="nopanel">true</ac:parameter>
<ac:parameter ac:name="">前回ミーティング</ac:parameter>
</ac:structured-macro>
<h3>今回の議題</h3>
<ol>
<li>プロジェクト進捗確認</li>
<li>課題と対策検討</li>
<li>次期計画の検討</li>
</ol>
<h2>決定事項</h2>
<ac:structured-macro ac:name="tip">
<ac:rich-text-body>
<ul>
<li>決定事項1</li>
<li>決定事項2</li>
</ul>
</ac:rich-text-body>
</ac:structured-macro>
<h2>アクションアイテム</h2>
<table>
<tr><th>アクション</th><th>担当者</th><th>期限</th><th>ステータス</th></tr>
<tr>
<td>タスク1の実行</td>
<td><ac:link><ri:user ri:account-id="user1" /></ac:link></td>
<td><time datetime="2025-01-15" /></td>
<td><ac:structured-macro ac:name="status">
<ac:parameter ac:name="colour">Blue</ac:parameter>
<ac:parameter ac:name="title">新規</ac:parameter>
</ac:structured-macro></td>
</tr>
</table>
権限管理とワークフロー設定
# Confluence権限管理API
class ConfluencePermissions:
def __init__(self, confluence_api):
self.api = confluence_api
def get_space_permissions(self, space_key):
"""スペース権限取得"""
url = f"{self.api.base_url}/rest/api/space/{space_key}/permission"
response = self.api.session.get(url)
response.raise_for_status()
return response.json()
def add_space_permission(self, space_key, user_key, permission_type):
"""スペース権限追加"""
url = f"{self.api.base_url}/rest/api/space/{space_key}/permission"
permission_data = {
"subject": {
"type": "user",
"identifier": user_key
},
"operation": {
"operation": permission_type, # "read", "administer", etc.
"targetType": "space"
}
}
response = self.api.session.post(url, data=json.dumps(permission_data))
response.raise_for_status()
return response.json()
def add_page_restriction(self, page_id, restrictions):
"""ページアクセス制限追加"""
url = f"{self.api.base_url}/rest/api/content/{page_id}/restriction"
restriction_data = {
"restrictions": restrictions
}
response = self.api.session.post(url, data=json.dumps(restriction_data))
response.raise_for_status()
return response.json()
# 使用例:階層的権限設定
permissions = ConfluencePermissions(confluence)
# 技術文書スペースの権限設定
space_permissions = permissions.get_space_permissions("TECH")
# 新規メンバーに読み取り権限を付与
permissions.add_space_permission(
space_key="TECH",
user_key="[email protected]",
permission_type="read"
)
# 機密ページに制限を設定
sensitive_page_restrictions = [
{
"operation": "read",
"restrictions": {
"user": [
{"type": "known", "username": "[email protected]"},
{"type": "known", "username": "[email protected]"}
]
}
}
]
permissions.add_page_restriction("123456", sensitive_page_restrictions)
自動化とCI/CD統合
# CI/CDパイプラインとの統合例
import os
from datetime import datetime
class ConfluenceAutomation:
def __init__(self, confluence_api):
self.api = confluence_api
def create_release_notes(self, version, changelog, jira_issues):
"""リリースノート自動生成"""
# JiraチケットのリンクHTML生成
jira_links = []
for issue in jira_issues:
jira_links.append(f'<ac:structured-macro ac:name="jira">
<ac:parameter ac:name="key">{issue}</ac:parameter>
</ac:structured-macro>')
content = f"""
<h1>リリースノート v{version}</h1>
<p><strong>リリース日:</strong> {datetime.now().strftime('%Y-%m-%d')}</p>
<h2>新機能・改善</h2>
<ac:structured-macro ac:name="info">
<ac:rich-text-body>
{changelog}
</ac:rich-text-body>
</ac:structured-macro>
<h2>修正された問題</h2>
{''.join(jira_links)}
<h2>既知の問題</h2>
<ac:structured-macro ac:name="warning">
<ac:parameter ac:name="title">注意事項</ac:parameter>
<ac:rich-text-body>
<p>現在調査中の問題については、Jiraでトラッキングしています。</p>
</ac:rich-text-body>
</ac:structured-macro>
"""
return self.api.create_page(
space_key="RELEASE",
title=f"リリースノート v{version}",
content=content
)
def update_api_documentation(self, openapi_spec):
"""API仕様書自動更新"""
content = f"""
<h1>API仕様書</h1>
<p><strong>更新日:</strong> {datetime.now().strftime('%Y-%m-%d %H:%M')}</p>
<ac:structured-macro ac:name="code">
<ac:parameter ac:name="language">yaml</ac:parameter>
<ac:parameter ac:name="title">OpenAPI Specification</ac:parameter>
<ac:rich-text-body>
<![CDATA[{openapi_spec}]]>
</ac:rich-text-body>
</ac:structured-macro>
"""
# 既存API仕様書ページを検索
search_results = self.api.search_content("API仕様書")
if search_results['results']:
# 既存ページを更新
page = search_results['results'][0]
page_id = page['content']['id']
current_version = page['content']['version']['number']
return self.api.update_page(
page_id=page_id,
title="API仕様書",
content=content,
version_number=current_version
)
else:
# 新規ページ作成
return self.api.create_page(
space_key="DEV",
title="API仕様書",
content=content
)
# GitHub Actions / GitLab CI での使用例
def main():
# 環境変数からConfluence設定を取得
confluence_url = os.getenv('CONFLUENCE_URL')
email = os.getenv('CONFLUENCE_EMAIL')
api_token = os.getenv('CONFLUENCE_API_TOKEN')
confluence = ConfluenceAPI(confluence_url, email, api_token)
automation = ConfluenceAutomation(confluence)
# Git情報からリリースノート生成
version = os.getenv('RELEASE_VERSION', '1.0.0')
changelog = os.getenv('CHANGELOG', '機能改善とバグ修正')
jira_issues = os.getenv('JIRA_ISSUES', '').split(',')
# リリースノート作成
release_page = automation.create_release_notes(version, changelog, jira_issues)
print(f"リリースノート作成完了: {release_page['_links']['webui']}")
# API仕様書更新(OpenAPIファイルがある場合)
if os.path.exists('openapi.yaml'):
with open('openapi.yaml', 'r', encoding='utf-8') as f:
openapi_spec = f.read()
api_page = automation.update_api_documentation(openapi_spec)
print(f"API仕様書更新完了: {api_page.get('_links', {}).get('webui', 'N/A')}")
if __name__ == "__main__":
main()
Advanced活用法とカスタムマクロ
// Confluence カスタムマクロ開発例(Atlassian Connect)
// atlassian-connect.json設定例
{
"name": "Custom Dashboard Macro",
"description": "カスタムダッシュボードマクロ",
"key": "custom-dashboard",
"baseUrl": "https://your-app.example.com",
"vendor": {
"name": "Your Company",
"url": "https://yourcompany.com"
},
"authentication": {
"type": "jwt"
},
"scopes": ["read", "write"],
"modules": {
"staticContentMacros": [
{
"url": "/dashboard",
"description": {
"value": "プロジェクトダッシュボード表示"
},
"name": {
"value": "Dashboard"
},
"key": "dashboard-macro",
"bodyType": "none",
"outputType": "block",
"featured": true,
"categories": ["reporting"],
"parameters": [
{
"identifier": "project",
"name": {
"value": "プロジェクト"
},
"type": "string",
"required": true
}
]
}
]
},
"apiVersion": 1,
"lifecycle": {
"installed": "/installed",
"uninstalled": "/uninstalled"
}
}
// マクロレンダリングのNode.js実装例
const express = require('express');
const atlassianJwt = require('atlassian-jwt');
const app = express();
app.get('/dashboard', (req, res) => {
// JWTトークン検証
const token = req.query.jwt;
const decoded = atlassianJwt.decode(token, process.env.CLIENT_SECRET);
// プロジェクトパラメータ取得
const projectKey = req.query.project;
// ダッシュボードHTML生成
const dashboardHtml = `
<div style="border: 1px solid #ddd; padding: 15px; border-radius: 5px;">
<h3>プロジェクト: ${projectKey}</h3>
<div style="display: flex; justify-content: space-between;">
<div class="metric">
<h4>完了タスク</h4>
<span style="font-size: 24px; color: green;">85%</span>
</div>
<div class="metric">
<h4>残り日数</h4>
<span style="font-size: 24px; color: orange;">12日</span>
</div>
<div class="metric">
<h4>チーム効率</h4>
<span style="font-size: 24px; color: blue;">92%</span>
</div>
</div>
<div style="margin-top: 15px;">
<canvas id="progress-chart" width="400" height="200"></canvas>
</div>
</div>
<script>
// Chart.js等でグラフ描画
</script>
`;
res.send(dashboardHtml);
});