Confluence
Collaboration Tool
Confluence
Overview
Confluence is a team collaboration and knowledge management tool developed by Atlassian. It provides enterprise hierarchical information organization, powerful access control, and rich integration features with over 3,000 app integrations. As a standard knowledge management tool in large enterprises, it's optimized for DevOps workflows through Jira integration. Leading the enterprise market with admin features and scalability, it comprehensively supports team document creation, project management, and information sharing.
Details
Confluence 2025 edition has established its position as the definitive tool for enterprise-level collaboration and knowledge management. As the core of the Atlassian ecosystem, it provides organization-wide information management platforms from development teams to executives through close integration with Jira Software, Bitbucket, and Trello. With rich page templates, real-time collaborative editing, advanced search capabilities, custom macros, and reporting features, it efficiently manages technical documentation, project plans, meeting minutes, and knowledge bases. REST API v2 enables external system integration, SAML SSO, and advanced permission management, balancing security and integration. The cloud version introduces the latest UI/UX and AI features, delivering a modern workspace experience.
Key Features
- Hierarchical Page Structure: Systematic information organization through spaces, pages, and sub-pages
- Real-time Collaborative Editing: Simultaneous editing and commenting by multiple members
- Rich Templates: Templates for project plans, meeting minutes, technical specifications, etc.
- Powerful Search Capabilities: Comprehensive search across page content, comments, and attachments
- App Marketplace: Integration with over 3,000 third-party apps
- Advanced Permission Management: Fine-grained permission settings at space, page, and content levels
Advantages and Disadvantages
Advantages
- Perfect integration with Atlassian ecosystem for workflow efficiency
- Enterprise-level security and compliance features (SOC2, GDPR compliant)
- Rich templates and industry best practice implementations
- Powerful reporting and analytics for usage visibility
- Scalability and stability for large organizations
- 24/7 support with comprehensive documentation and training
- Flexible system integration and customization through REST API
- Continuous feature additions and security updates
Disadvantages
- High licensing costs (significant burden for small businesses)
- Complex UI configuration with high initial learning curve
- Integration limitations with tools outside Atlassian ecosystem
- Server version support termination (February 2024) requiring cloud migration
- Additional costs for customization requiring marketplace apps
- Performance degradation in search with large data volumes
- Increased operational burden from overly complex permission settings
Reference Links
- Confluence Official Site
- Confluence Official Documentation
- Confluence REST API Documentation
- Confluence Marketplace
- Atlassian Community
Usage Examples
Basic Setup and Space Creation
# Confluence Cloud access setup
# 1. Create Atlassian account: https://id.atlassian.com
# 2. Generate API token: https://id.atlassian.com/manage-profile/security/api-tokens
# 3. Verify admin permissions: Grant permissions from organization admin
# Basic space structure example
Team Name Space/
├── Project Management/
│ ├── Project Plans
│ ├── Progress Reports
│ └── Completion Reports
├── Technical Documentation/
│ ├── API Specifications
│ ├── Architecture Design
│ └── Operations Manual
└── Meeting Records/
├── Weekly Meetings
├── Monthly Reviews
└── Decision Records
REST API Basic Operations
import requests
from requests.auth import HTTPBasicAuth
import json
# Confluence REST API configuration
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):
"""Get list of spaces"""
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"):
"""Get page information"""
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):
"""Create new page"""
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):
"""Update page"""
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"):
"""Search content"""
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()
# Usage example
confluence = ConfluenceAPI(CONFLUENCE_URL, EMAIL, API_TOKEN)
# Display space list
spaces = confluence.get_spaces()
for space in spaces['results']:
print(f"Space: {space['name']} (key: {space['key']})")
# Create new page
page_content = """
<h1>Project Kickoff</h1>
<h2>Purpose</h2>
<p>Clarify preparation and role assignments for new project launch</p>
<h2>Participants</h2>
<ul>
<li>Project Manager: Tanaka</li>
<li>Development Lead: Sato</li>
<li>Designer: Suzuki</li>
</ul>
<h2>Schedule</h2>
<table>
<tr><th>Phase</th><th>Duration</th><th>Assignee</th></tr>
<tr><td>Design</td><td>2 weeks</td><td>Sato</td></tr>
<tr><td>Implementation</td><td>4 weeks</td><td>Dev Team</td></tr>
<tr><td>Testing</td><td>1 week</td><td>QA Team</td></tr>
</table>
"""
new_page = confluence.create_page(
space_key="DEV",
title="Project Kickoff 2025-01-01",
content=page_content
)
print(f"New page created: {new_page['_links']['webui']}")
Page Templates and Macro Usage
<!-- Project Plan Template -->
<ac:structured-macro ac:name="info">
<ac:parameter ac:name="title">Project Basic Information</ac:parameter>
<ac:rich-text-body>
<table>
<tr><th>Item</th><th>Content</th></tr>
<tr><td>Project Name</td><td>[Enter project name]</td></tr>
<tr><td>Start Date</td><td><time datetime="2025-01-01" /></td></tr>
<tr><td>Expected Completion</td><td><time datetime="2025-03-31" /></td></tr>
<tr><td>Budget</td><td>[Enter budget]</td></tr>
</table>
</ac:rich-text-body>
</ac:structured-macro>
<!-- Status Macro -->
<h2>Project Status</h2>
<ac:structured-macro ac:name="status">
<ac:parameter ac:name="colour">Green</ac:parameter>
<ac:parameter ac:name="title">In Progress</ac:parameter>
</ac:structured-macro>
<!-- Task List -->
<h2>Task List</h2>
<ac:task-list>
<ac:task>
<ac:task-id>1</ac:task-id>
<ac:task-status>incomplete</ac:task-status>
<ac:task-body>Create requirements document</ac:task-body>
</ac:task>
<ac:task>
<ac:task-id>2</ac:task-id>
<ac:task-status>complete</ac:task-status>
<ac:task-body>Team formation</ac:task-body>
</ac:task>
</ac:task-list>
<!-- Jira Issues Macro -->
<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>
<!-- Team Member Information -->
<h2>Team Members</h2>
<ac:structured-macro ac:name="user-profile">
<ac:parameter ac:name="user">@tanaka</ac:parameter>
</ac:structured-macro>
<!-- Meeting Minutes Template -->
<h1>Weekly Meeting Minutes</h1>
<ac:structured-macro ac:name="info">
<ac:parameter ac:name="title">Meeting Information</ac:parameter>
<ac:rich-text-body>
<p><strong>Date/Time:</strong> <time datetime="2025-01-08T10:00" /></p>
<p><strong>Location:</strong> Conference Room A / Zoom</p>
<p><strong>Moderator:</strong> @moderator</p>
<p><strong>Secretary:</strong> @secretary</p>
</ac:rich-text-body>
</ac:structured-macro>
<h2>Participants</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>Agenda</h2>
<h3>Review Previous Action Items</h3>
<!-- Reference previous incomplete items -->
<ac:structured-macro ac:name="excerpt-include">
<ac:parameter ac:name="nopanel">true</ac:parameter>
<ac:parameter ac:name="">Previous Meeting</ac:parameter>
</ac:structured-macro>
<h3>Current Topics</h3>
<ol>
<li>Project progress review</li>
<li>Issues and countermeasures</li>
<li>Next phase planning</li>
</ol>
<h2>Decisions</h2>
<ac:structured-macro ac:name="tip">
<ac:rich-text-body>
<ul>
<li>Decision 1</li>
<li>Decision 2</li>
</ul>
</ac:rich-text-body>
</ac:structured-macro>
<h2>Action Items</h2>
<table>
<tr><th>Action</th><th>Assignee</th><th>Due Date</th><th>Status</th></tr>
<tr>
<td>Execute Task 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">New</ac:parameter>
</ac:structured-macro></td>
</tr>
</table>
Permission Management and Workflow Setup
# Confluence Permission Management API
class ConfluencePermissions:
def __init__(self, confluence_api):
self.api = confluence_api
def get_space_permissions(self, space_key):
"""Get space permissions"""
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):
"""Add space permission"""
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):
"""Add page access 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()
# Usage example: Hierarchical permission setup
permissions = ConfluencePermissions(confluence)
# Technical documentation space permission setup
space_permissions = permissions.get_space_permissions("TECH")
# Grant read permission to new member
permissions.add_space_permission(
space_key="TECH",
user_key="[email protected]",
permission_type="read"
)
# Set restrictions on confidential pages
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)
Automation and CI/CD Integration
# CI/CD pipeline integration example
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):
"""Auto-generate release notes"""
# Generate Jira ticket link 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>Release Notes v{version}</h1>
<p><strong>Release Date:</strong> {datetime.now().strftime('%Y-%m-%d')}</p>
<h2>New Features & Improvements</h2>
<ac:structured-macro ac:name="info">
<ac:rich-text-body>
{changelog}
</ac:rich-text-body>
</ac:structured-macro>
<h2>Fixed Issues</h2>
{''.join(jira_links)}
<h2>Known Issues</h2>
<ac:structured-macro ac:name="warning">
<ac:parameter ac:name="title">Important Notes</ac:parameter>
<ac:rich-text-body>
<p>Issues currently under investigation are tracked in Jira.</p>
</ac:rich-text-body>
</ac:structured-macro>
"""
return self.api.create_page(
space_key="RELEASE",
title=f"Release Notes v{version}",
content=content
)
def update_api_documentation(self, openapi_spec):
"""Auto-update API documentation"""
content = f"""
<h1>API Documentation</h1>
<p><strong>Updated:</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>
"""
# Search for existing API documentation page
search_results = self.api.search_content("API Documentation")
if search_results['results']:
# Update existing page
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 Documentation",
content=content,
version_number=current_version
)
else:
# Create new page
return self.api.create_page(
space_key="DEV",
title="API Documentation",
content=content
)
# GitHub Actions / GitLab CI usage example
def main():
# Get Confluence settings from environment variables
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)
# Generate release notes from Git information
version = os.getenv('RELEASE_VERSION', '1.0.0')
changelog = os.getenv('CHANGELOG', 'Feature improvements and bug fixes')
jira_issues = os.getenv('JIRA_ISSUES', '').split(',')
# Create release notes
release_page = automation.create_release_notes(version, changelog, jira_issues)
print(f"Release notes created: {release_page['_links']['webui']}")
# Update API documentation (if OpenAPI file exists)
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 documentation updated: {api_page.get('_links', {}).get('webui', 'N/A')}")
if __name__ == "__main__":
main()
Advanced Usage and Custom Macros
// Confluence custom macro development example (Atlassian Connect)
// atlassian-connect.json configuration example
{
"name": "Custom Dashboard Macro",
"description": "Custom dashboard macro",
"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": "Display project dashboard"
},
"name": {
"value": "Dashboard"
},
"key": "dashboard-macro",
"bodyType": "none",
"outputType": "block",
"featured": true,
"categories": ["reporting"],
"parameters": [
{
"identifier": "project",
"name": {
"value": "Project"
},
"type": "string",
"required": true
}
]
}
]
},
"apiVersion": 1,
"lifecycle": {
"installed": "/installed",
"uninstalled": "/uninstalled"
}
}
// Node.js implementation example for macro rendering
const express = require('express');
const atlassianJwt = require('atlassian-jwt');
const app = express();
app.get('/dashboard', (req, res) => {
// JWT token verification
const token = req.query.jwt;
const decoded = atlassianJwt.decode(token, process.env.CLIENT_SECRET);
// Get project parameter
const projectKey = req.query.project;
// Generate dashboard HTML
const dashboardHtml = `
<div style="border: 1px solid #ddd; padding: 15px; border-radius: 5px;">
<h3>Project: ${projectKey}</h3>
<div style="display: flex; justify-content: space-between;">
<div class="metric">
<h4>Completed Tasks</h4>
<span style="font-size: 24px; color: green;">85%</span>
</div>
<div class="metric">
<h4>Days Remaining</h4>
<span style="font-size: 24px; color: orange;">12 days</span>
</div>
<div class="metric">
<h4>Team Efficiency</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>
// Draw charts with Chart.js etc.
</script>
`;
res.send(dashboardHtml);
});