🚀 Executive Summary
TL;DR: This guide addresses the problem of missed Confluence page updates by providing a Python script solution. It automates sending notifications to a Microsoft Teams channel whenever a specific Confluence page is updated, leveraging the Confluence API and Teams Incoming Webhooks.
🎯 Key Takeaways
- The solution tracks Confluence page updates reliably by comparing version numbers obtained via the Confluence REST API using the `expand=version` parameter, which is more robust than timestamp comparisons.
- Secure credential management is implemented using `python-dotenv` and a `config.env` file to store sensitive information like Atlassian API tokens and Teams webhook URLs, preventing hard-coding within the script.
- State management is handled by a simple `last_version.txt` file, which stores the last known page version, ensuring notifications are only triggered for new updates and not on every script execution.
Syncing Confluence Page Updates to Microsoft Teams
Hey team, Darian Vance here. Let’s talk about a classic problem: keeping everyone in sync with crucial documentation. I used to spend way too much time manually checking our key Confluence pages for updates before a release, or worse, finding out a critical change was missed by the team because no one saw it. This simple Python script I’m about to show you saved me hours and eliminated that ‘out-of-the-loop’ feeling. It automatically pings a Teams channel whenever a specific Confluence page is updated. It’s a real ‘set it and forget it’ solution that adds a ton of value.
Prerequisites
Before we dive in, make sure you have the following ready to go:
- Your Confluence domain (e.g.,
your-company.atlassian.net). - A Confluence Page ID for the page you want to monitor. You can find this in the URL when editing the page.
- An Atlassian API token with read permissions for Confluence.
- A Microsoft Teams channel where you have permission to add an Incoming Webhook.
- A Python 3 environment where you can run scripts.
The Guide: Step-by-Step
Step 1: Get Your Credentials
First, we need to gather our secrets. In my production setups, I always store credentials outside the script itself. We’ll use a configuration file for this.
- Atlassian API Token: Go to your Atlassian account settings, find ‘API tokens’ under security, and create a new token. Give it a descriptive name and copy it somewhere safe immediately.
- Microsoft Teams Webhook URL: In your target Teams channel, click the three dots (…) next to the channel name, select ‘Connectors’, and search for ‘Incoming Webhook’. Configure it, give it a name like “Confluence Updates”, and copy the generated URL.
Step 2: Project Setup and Dependencies
Alright, let’s get our project folder ready. I’ll skip the standard virtualenv setup since you likely have your own workflow for that. Just make sure you have a clean environment to work in.
Once your environment is active, you’ll need to install a couple of Python libraries. You can do this by running the commands to install requests (for making HTTP API calls) and python-dotenv (for securely managing our credentials).
Next, inside your project directory, create a file named config.env. This is where we’ll store our secrets so they aren’t hard-coded in the script. Add your credentials to it like this:
# config.env
ATLASSIAN_DOMAIN="your-company.atlassian.net"
ATLASSIAN_USER_EMAIL="your.email@yourcompany.com"
ATLASSIAN_API_TOKEN="YourSuperSecretAPIToken"
CONFLUENCE_PAGE_ID="123456789"
TEAMS_WEBHOOK_URL="https://yourcompany.webhook.office.com/..."
Step 3: The Python Script
Now for the main event. Create a file named check_confluence.py and add the following code. I’ll break down what each part does right after the block.
import os
import requests
from dotenv import load_dotenv
STATE_FILE = "last_version.txt"
def get_confluence_page_details():
"""Fetches the latest version details for a specific Confluence page."""
domain = os.getenv("ATLASSIAN_DOMAIN")
user_email = os.getenv("ATLASSIAN_USER_EMAIL")
api_token = os.getenv("ATLASSIAN_API_TOKEN")
page_id = os.getenv("CONFLUENCE_PAGE_ID")
url = f"https://{domain}/wiki/rest/api/content/{page_id}"
params = {"expand": "version"}
try:
response = requests.get(
url,
auth=(user_email, api_token),
params=params,
timeout=10
)
response.raise_for_status()
data = response.json()
page_title = data.get("title")
page_version = data.get("version", {}).get("number")
page_url = f"https://{domain}/wiki" + data.get("_links", {}).get("webui")
if not all([page_title, page_version, page_url]):
print("Error: Could not parse all required page details from Confluence API response.")
return None
return {"title": page_title, "version": page_version, "url": page_url}
except requests.exceptions.RequestException as e:
print(f"Error connecting to Confluence: {e}")
return None
def send_teams_notification(page_details):
"""Sends a formatted notification to the configured MS Teams webhook."""
webhook_url = os.getenv("TEAMS_WEBHOOK_URL")
if not webhook_url:
print("Error: TEAMS_WEBHOOK_URL is not set.")
return
payload = {
"@type": "MessageCard",
"@context": "http://schema.org/extensions",
"themeColor": "0076D7",
"summary": f"Confluence Page Updated: {page_details['title']}",
"sections": [{
"activityTitle": f"Confluence Page Updated: **{page_details['title']}**",
"activitySubtitle": f"A new version ({page_details['version']}) is now available.",
"facts": [{"name": "Action", "value": "Review the changes"}],
"markdown": True
}],
"potentialAction": [{
"@type": "OpenUri",
"name": "View Page in Confluence",
"targets": [{"os": "default", "uri": page_details['url']}]
}]
}
try:
response = requests.post(webhook_url, json=payload, timeout=10)
response.raise_for_status()
print(f"Successfully sent notification for version {page_details['version']}.")
except requests.exceptions.RequestException as e:
print(f"Error sending Teams notification: {e}")
def main():
"""Main function to check for updates and trigger notifications."""
load_dotenv('config.env')
print("Checking for Confluence page updates...")
page_details = get_confluence_page_details()
if not page_details:
print("Could not retrieve page details. Exiting.")
return
current_version = page_details["version"]
last_known_version = 0
try:
with open(STATE_FILE, 'r') as f:
last_known_version = int(f.read().strip())
except (FileNotFoundError, ValueError):
print("State file not found or invalid. Creating a new one.")
last_known_version = 0
print(f"Current version on Confluence: {current_version}. Last known version: {last_known_version}")
if current_version > last_known_version:
print("New version detected. Sending notification...")
send_teams_notification(page_details)
with open(STATE_FILE, 'w') as f:
f.write(str(current_version))
else:
print("No new updates found.")
if __name__ == "__main__":
main()
Code Breakdown:
- State Management: The script reads a file called
last_version.txt. This is our simple “database” to remember the last version number we saw. Comparing version numbers is much more reliable than comparing timestamps. - get_confluence_page_details(): This function handles the API call to Confluence. It uses Basic Auth with your email and API token. Critically, we use
expand=versionto ensure the version number is included in the response. - send_teams_notification(): This builds the JSON payload for the Teams webhook. The format here is called a “MessageCard”. It creates a nicely formatted message with a title, a summary, and a button to view the page directly.
- main(): This is the orchestrator. It loads the environment variables from
config.env, gets the current page details, compares the version number with our saved state, and if the current version is newer, it calls the notification function and updates the state file.
Pro Tip: For more complex or interactive notifications in Teams, look into “Adaptive Cards”. They offer a much richer set of formatting options than the basic MessageCard format I’ve used here.
Step 4: Scheduling the Script
The script is useless if we don’t run it automatically. For this, we use a scheduler.
- On Linux/macOS: You can use cron. A common setup is to run the script every hour. The cron command would look something like this. Remember to run it from your project directory.
0 * * * * python3 check_confluence.py
- On Windows: You can use the built-in Task Scheduler to achieve the same result. Create a new task that triggers on a schedule and set the action to run your Python interpreter with the script file as the argument.
Common Pitfalls
Here are a few spots where I’ve tripped up in the past, so you can avoid them:
- API Token Permissions: If you’re getting 401 Unauthorized or 403 Forbidden errors, the first thing to check is your Atlassian API token. Ensure it has the necessary read permissions for Confluence.
- Incorrect Webhook URL: It sounds obvious, but double-check that you’ve copied the entire webhook URL from Teams into your
config.envfile. A single missing character will cause silent failures. - The First Run: The script is designed to only notify on changes. The very first time it runs, it will see the current version, save it to
last_version.txt, and send no notification. This is expected. The alerts will start on the *next* update.
Conclusion
And that’s it. You now have a simple, robust, and low-maintenance way to bridge the communication gap between your documentation hub and your team’s primary communication channel. This simple pattern—check an API for a state change, compare to a local state file, and notify on a delta—is incredibly powerful. Feel free to adapt it for monitoring build statuses, ticket updates, or anything else with an API. Happy automating!
🤖 Frequently Asked Questions
âť“ How can I automatically get notified in Microsoft Teams when a Confluence page is updated?
You can achieve this using a Python script that monitors a specific Confluence page’s version via its REST API, compares it to a locally stored `last_version.txt` file, and sends a formatted MessageCard notification to a Microsoft Teams Incoming Webhook when a new version is detected.
âť“ How does this Python script approach compare to built-in Confluence notifications or third-party integrations?
This custom Python script offers granular control over which specific Confluence pages trigger notifications and allows for highly customized MessageCard formatting in Teams. It serves as a lightweight, self-hosted alternative to potentially more complex or costly third-party integrations, providing direct API control.
âť“ What should I check if my Confluence update notifications aren’t appearing in Teams?
First, verify your Atlassian API token has the necessary read permissions for Confluence to avoid 401/403 errors. Second, ensure the Microsoft Teams Incoming Webhook URL in your `config.env` is copied entirely and correctly. Also, remember the script’s initial run will save the current version to `last_version.txt` without sending a notification, with alerts starting on subsequent updates.
Leave a Reply