Files
Orchestrator/bahn/Confluence_Bot/scripts/lib/confluence-api.ps1
T
ankn a5f8fb49ab Migrate all repos into monorepo context folders
Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
      Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
      Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)

Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
2026-06-30 20:39:52 +02:00

161 lines
6.4 KiB
PowerShell

# Shared Confluence API functions
# Source this file in other scripts: . "$PSScriptRoot/lib/confluence-api.ps1"
function Invoke-ConfluenceApi {
param([string]$Endpoint, [hashtable]$Params = @{}, [string]$Method = "Get", [string]$Body = $null)
$QS = ($Params.GetEnumerator() | ForEach-Object {
"$($_.Key)=$([Uri]::EscapeDataString($_.Value))"
}) -join "&"
$Uri = "$ApiBase$Endpoint"
if ($QS) { $Uri = "$Uri`?$QS" }
try {
if ($Body) {
$Resp = Invoke-WebRequest -Uri $Uri -Method $Method -Headers $Headers -Body ([System.Text.Encoding]::UTF8.GetBytes($Body)) -UseBasicParsing -ErrorAction Stop
} else {
$Resp = Invoke-WebRequest -Uri $Uri -Method $Method -Headers $Headers -UseBasicParsing -ErrorAction Stop
}
return ($Resp.Content | ConvertFrom-Json)
} catch {
Write-Host " ERROR at $Uri : $($_.Exception.Message)" -ForegroundColor Red
return $null
}
}
function Get-ChildPages {
param([string]$PageId)
$AllChildren = @()
$Start = 0
do {
$Result = Invoke-ConfluenceApi -Endpoint "/content/$PageId/child/page" -Params @{
start = "$Start"
limit = "$PerPage"
expand = "version"
}
if ($null -eq $Result) { break }
$Pages = $Result.results
if ($null -eq $Pages -or $Pages.Count -eq 0) { break }
$AllChildren += $Pages
$Start += $PerPage
$Size = 0
if ($Result.size) { $Size = $Result.size }
} while ($Size -ge $PerPage)
return $AllChildren
}
function Get-PageContent {
param([string]$PageId)
return Invoke-ConfluenceApi -Endpoint "/content/$PageId" -Params @{
expand = "body.storage,version,ancestors,metadata.labels,space"
}
}
function Convert-HtmlToText($html) {
if ($null -eq $html) { return "" }
$text = $html -replace '<br\s*/?>', "`n"
$text = $text -replace '<p[^>]*>', "`n"
$text = $text -replace '</p>', ""
$text = $text -replace '<li[^>]*>', "`n- "
$text = $text -replace '<h[1-6][^>]*>', "`n## "
$text = $text -replace '</h[1-6]>', "`n"
$text = $text -replace '<tr[^>]*>', "`n| "
$text = $text -replace '<td[^>]*>', " | "
$text = $text -replace '<th[^>]*>', " | "
$text = $text -replace '<[^>]+>', ''
Add-Type -AssemblyName System.Web -ErrorAction SilentlyContinue
try { $text = [System.Web.HttpUtility]::HtmlDecode($text) } catch {}
return $text.Trim()
}
function Create-Or-Update-Page {
param([string]$Title, [string]$HtmlBody, [string]$ParentId)
$SearchUri = "$ApiBase/content?spaceKey=$SpaceKey&title=$([Uri]::EscapeDataString($Title))&type=page"
try {
$SearchResp = Invoke-WebRequest -Uri $SearchUri -Headers $Headers -UseBasicParsing -ErrorAction Stop
$SearchData = $SearchResp.Content | ConvertFrom-Json
} catch {
Write-Host " ERROR searching: $($_.Exception.Message)" -ForegroundColor Red
return $null
}
if ($SearchData.results -and $SearchData.results.Count -gt 0) {
$PageId = $SearchData.results[0].id
try {
$VerResp = Invoke-WebRequest -Uri "$ApiBase/content/$PageId`?expand=version,body.storage" -Headers $Headers -UseBasicParsing -ErrorAction Stop
$VerData = $VerResp.Content | ConvertFrom-Json
$Version = $VerData.version.number + 1
$CurrentBody = ""
if ($VerData.body -and $VerData.body.storage) { $CurrentBody = $VerData.body.storage.value }
$NormCurrent = ($CurrentBody -replace '<[^>]+>' -replace '&\w+;' -replace '\s+', ' ').Trim()
$NormNew = ($HtmlBody -replace '<[^>]+>' -replace '&\w+;' -replace '\s+', ' ').Trim()
if ($NormCurrent -eq $NormNew) {
Write-Host " No changes (ID: $PageId)" -ForegroundColor DarkGray
return $PageId
}
} catch {
$Version = $SearchData.results[0].version.number + 1
}
Write-Host " Updating (ID: $PageId, v$Version)..." -NoNewline
$Body = @{
version = @{ number = $Version }
title = $Title
type = "page"
body = @{ storage = @{ value = $HtmlBody; representation = "storage" } }
} | ConvertTo-Json -Depth 10
try {
$Resp = Invoke-WebRequest -Uri "$ApiBase/content/$PageId" -Method Put -Headers $Headers -Body ([System.Text.Encoding]::UTF8.GetBytes($Body)) -UseBasicParsing -ErrorAction Stop
Write-Host " OK" -ForegroundColor Green
return ($Resp.Content | ConvertFrom-Json).id
} catch {
Write-Host " ERROR: $($_.Exception.Message)" -ForegroundColor Red
return $null
}
} else {
Write-Host " Creating new page..." -NoNewline
$Body = @{
type = "page"
title = $Title
space = @{ key = $SpaceKey }
ancestors = @(@{ id = $ParentId })
body = @{ storage = @{ value = $HtmlBody; representation = "storage" } }
} | ConvertTo-Json -Depth 10
try {
$Resp = Invoke-WebRequest -Uri "$ApiBase/content" -Method Post -Headers $Headers -Body ([System.Text.Encoding]::UTF8.GetBytes($Body)) -UseBasicParsing -ErrorAction Stop
Write-Host " OK" -ForegroundColor Green
return ($Resp.Content | ConvertFrom-Json).id
} catch {
Write-Host " ERROR: $($_.Exception.Message)" -ForegroundColor Red
return $null
}
}
}
function Move-Page($PageId, $NewParentId) {
$Page = Invoke-ConfluenceApi -Endpoint "/content/$PageId" -Params @{ expand = "version,ancestors" }
if (-not $Page) { return $false }
if ($Page.ancestors -and $Page.ancestors.Count -gt 0) {
if ($Page.ancestors[-1].id -eq $NewParentId) { return $true }
}
$Version = $Page.version.number + 1
$Json = @{
type = "page"; title = $Page.title
version = @{ number = $Version }
ancestors = @(@{ id = $NewParentId })
} | ConvertTo-Json -Depth 10
$Result = Invoke-ConfluenceApi -Endpoint "/content/$PageId" -Method "Put" -Body $Json
return ($null -ne $Result)
}
function Delete-Page($PageId) {
try {
Invoke-WebRequest -Uri "$ApiBase/content/$PageId" -Method Delete -Headers $Headers -UseBasicParsing -ErrorAction Stop
return $true
} catch {
Write-Host " ERROR deleting $PageId : $($_.Exception.Message)" -ForegroundColor Red
return $false
}
}