new site
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
#requires -version 5.1
|
||||
<#
|
||||
kie-image.ps1 - generate hero/OG images via kie.ai (z-image by default).
|
||||
Loads KIE_API_KEY from .env.local at repo root (or $env:KIE_API_KEY).
|
||||
Usage:
|
||||
powershell -File seo-audit-2026-05-27\scripts\kie-image.ps1 -Prompt "..." -OutPath "images/<slug>-hero.png" [-Model z-image] [-Aspect 16:9] [-Resolution 2K]
|
||||
Models: z-image (default, fast), nano-banana-2 (premium fallback), nano-banana-pro.
|
||||
Mechanism: POST /api/v1/jobs/createTask with callBackUrl -> ntfy.sh topic -> poll for result.
|
||||
Note: The old /api/v1/jobs/getTaskDetails polling endpoint no longer exists (API change 2026-05).
|
||||
Results are now delivered via callBackUrl (webhook). This script uses ntfy.sh as a
|
||||
free anonymous webhook receiver since no public server is required.
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$Prompt,
|
||||
[Parameter(Mandatory)][string]$OutPath,
|
||||
[string]$Model = "z-image",
|
||||
[string]$Aspect = "16:9",
|
||||
[string]$Resolution = "2K",
|
||||
[string]$Format = "png",
|
||||
[int]$TimeoutSec = 300
|
||||
)
|
||||
$ErrorActionPreference = "Stop"
|
||||
$repoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
|
||||
if(-not $env:KIE_API_KEY){
|
||||
$envFile = Join-Path $repoRoot ".env.local"
|
||||
if(Test-Path $envFile){
|
||||
$line = Get-Content $envFile -ErrorAction SilentlyContinue | Where-Object { $_ -match '^KIE_API_KEY=' } | Select-Object -First 1
|
||||
if($line){ $env:KIE_API_KEY = ($line -replace '^KIE_API_KEY=','').Trim('"',"'") }
|
||||
}
|
||||
}
|
||||
if(-not $env:KIE_API_KEY){ throw "KIE_API_KEY not set (env var or .env.local)" }
|
||||
|
||||
# Generate unique ntfy.sh topic for callback
|
||||
$ntfyTopic = "kie-img-$(Get-Date -Format 'yyyyMMddHHmmss')-$(Get-Random -Maximum 9999)"
|
||||
$callBackUrl = "https://ntfy.sh/$ntfyTopic"
|
||||
|
||||
$headers = @{ Authorization = "Bearer $($env:KIE_API_KEY)"; 'Content-Type' = 'application/json' }
|
||||
$body = @{
|
||||
model = $Model
|
||||
input = @{ prompt = $Prompt; aspect_ratio = $Aspect; resolution = $Resolution; output_format = $Format }
|
||||
callBackUrl = $callBackUrl
|
||||
} | ConvertTo-Json -Depth 6
|
||||
|
||||
Write-Host "[kie-image] submit model=$Model aspect=$Aspect res=$Resolution"
|
||||
Write-Host "[kie-image] callback=$callBackUrl"
|
||||
$create = Invoke-RestMethod -Uri 'https://api.kie.ai/api/v1/jobs/createTask' -Method POST -Headers $headers -Body $body
|
||||
if($create.code -ne 200){ throw "createTask failed: $($create | ConvertTo-Json -Depth 5 -Compress)" }
|
||||
$taskId = $create.data.taskId
|
||||
Write-Host "[kie-image] taskId=$taskId polling via ntfy.sh..."
|
||||
|
||||
$deadline = (Get-Date).AddSeconds($TimeoutSec)
|
||||
$imageUrl = $null
|
||||
while((Get-Date) -lt $deadline){
|
||||
Start-Sleep -Seconds 8
|
||||
try {
|
||||
$r = Invoke-WebRequest -Uri "https://ntfy.sh/$ntfyTopic/json?poll=1" -UseBasicParsing -ErrorAction Stop
|
||||
$text = [System.Text.Encoding]::UTF8.GetString($r.RawContentStream.ToArray())
|
||||
# Parse NDJSON lines for kie.ai callback
|
||||
$lines = $text -split '[\r\n]+' | Where-Object { $_ -match '"event":"message"' }
|
||||
foreach ($line in $lines) {
|
||||
try {
|
||||
$msg = $line | ConvertFrom-Json
|
||||
$payload = $msg.message | ConvertFrom-Json
|
||||
if ($payload.code -eq 200 -and $payload.data.taskId -eq $taskId) {
|
||||
$state = $payload.data.state
|
||||
Write-Host "[kie-image] state=$state"
|
||||
if ($state -eq 'success') {
|
||||
$rj = $payload.data.resultJson | ConvertFrom-Json
|
||||
$imageUrl = $rj.resultUrls[0]
|
||||
break
|
||||
}
|
||||
if ($state -eq 'failed' -or $state -eq 'error') {
|
||||
throw "task failed: $($payload | ConvertTo-Json -Depth 5 -Compress)"
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
} catch { }
|
||||
if ($imageUrl) { break }
|
||||
}
|
||||
if(-not $imageUrl){ throw "timed out after $TimeoutSec s waiting for task $taskId" }
|
||||
|
||||
$outFull = Join-Path $repoRoot $OutPath
|
||||
$outDir = Split-Path -Parent $outFull
|
||||
if($outDir -and -not (Test-Path $outDir)){ New-Item -ItemType Directory -Force -Path $outDir | Out-Null }
|
||||
Invoke-WebRequest -Uri $imageUrl -OutFile $outFull -UseBasicParsing
|
||||
Write-Host "[kie-image] saved: $outFull"
|
||||
Write-Output $outFull
|
||||
Reference in New Issue
Block a user