@blunking/codexlink 0.1.9 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +253 -251
- package/blun-codex.ps1 +140 -140
- package/package.json +40 -40
- package/start-codex-agent.ps1 +727 -727
- package/telegram-doctor.ps1 +214 -214
- package/telegram-plugin/dispatcher.js +1 -1
- package/telegram-plugin/lib/bridge.js +49 -19
- package/telegram-plugin/lib/storage.js +25 -25
- package/telegram-plugin/lib/telegram.js +2 -1
- package/telegram-plugin/poller.js +1 -1
- package/telegram-setup.ps1 +318 -168
- package/telegram-status.ps1 +256 -256
- package/telegram-title-embed.ps1 +105 -105
- package/telegram-title-watcher.ps1 +103 -103
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { pollOnce } from "./lib/bridge.js";
|
|
3
3
|
import { isCurrentSidecarPid } from "./lib/singleton.js";
|
|
4
4
|
|
|
5
|
-
const intervalMs = Number.parseInt(process.env.BLUN_TELEGRAM_POLL_INTERVAL_MS || "
|
|
5
|
+
const intervalMs = Number.parseInt(process.env.BLUN_TELEGRAM_POLL_INTERVAL_MS || "700", 10) || 700;
|
|
6
6
|
let stopping = false;
|
|
7
7
|
|
|
8
8
|
function sleep(ms) {
|
package/telegram-setup.ps1
CHANGED
|
@@ -1,96 +1,230 @@
|
|
|
1
|
-
param(
|
|
2
|
-
[string]$Profile = "default",
|
|
3
|
-
[switch]$EnsureConfigured,
|
|
4
|
-
[switch]$Json
|
|
5
|
-
)
|
|
6
|
-
|
|
7
|
-
$ErrorActionPreference = "Stop"
|
|
8
|
-
|
|
9
|
-
function Try-ReadJson {
|
|
10
|
-
param([string]$Path)
|
|
11
|
-
if (-not (Test-Path $Path)) { return $null }
|
|
12
|
-
try { return Get-Content -Raw -Path $Path | ConvertFrom-Json } catch { return $null }
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function Ensure-Dir {
|
|
16
|
-
param([string]$Path)
|
|
17
|
-
if (-not (Test-Path $Path)) {
|
|
18
|
-
New-Item -ItemType Directory -Path $Path -Force | Out-Null
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function Resolve-ConfiguredPath {
|
|
23
|
-
param([string]$Value, [string]$RuntimeRoot)
|
|
24
|
-
if (-not $Value) { return "" }
|
|
25
|
-
$expanded = [Environment]::ExpandEnvironmentVariables($Value)
|
|
26
|
-
if ([System.IO.Path]::IsPathRooted($expanded)) { return $expanded }
|
|
27
|
-
return [System.IO.Path]::GetFullPath((Join-Path $RuntimeRoot $expanded))
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function Read-DotEnvFile {
|
|
31
|
-
param([string]$Path)
|
|
32
|
-
$values = @{}
|
|
33
|
-
if (-not (Test-Path $Path)) { return $values }
|
|
34
|
-
foreach ($line in (Get-Content -Path $Path)) {
|
|
35
|
-
if (-not $line) { continue }
|
|
36
|
-
if ($line.Trim().StartsWith("#")) { continue }
|
|
37
|
-
$parts = $line -split "=", 2
|
|
38
|
-
if ($parts.Count -ne 2) { continue }
|
|
39
|
-
$values[$parts[0].Trim()] = $parts[1]
|
|
40
|
-
}
|
|
41
|
-
return $values
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function Write-DotEnvFile {
|
|
45
|
-
param(
|
|
46
|
-
[string]$Path,
|
|
47
|
-
[hashtable]$Values
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
$lines = foreach ($key in ($Values.Keys | Sort-Object)) {
|
|
51
|
-
"$key=$($Values[$key])"
|
|
52
|
-
}
|
|
53
|
-
Set-Content -Path $Path -Value $lines -Encoding UTF8
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function Test-TelegramTokenFormat {
|
|
57
|
-
param([string]$Value)
|
|
58
|
-
if (-not $Value) { return $false }
|
|
59
|
-
return $Value -match '^\d{6,}:[A-Za-z0-9_-]{20,}$'
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function Test-AllowedChatIdsFormat {
|
|
63
|
-
param([string]$Value)
|
|
64
|
-
if (-not $Value) { return $false }
|
|
65
|
-
$parts = @($Value -split "," | ForEach-Object { $_.Trim() } | Where-Object { $_ })
|
|
66
|
-
if ($parts.Count -eq 0) { return $false }
|
|
67
|
-
foreach ($part in $parts) {
|
|
68
|
-
if ($part -notmatch '^-?\d+$') {
|
|
69
|
-
return $false
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return $true
|
|
73
|
-
}
|
|
74
|
-
|
|
1
|
+
param(
|
|
2
|
+
[string]$Profile = "default",
|
|
3
|
+
[switch]$EnsureConfigured,
|
|
4
|
+
[switch]$Json
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
$ErrorActionPreference = "Stop"
|
|
8
|
+
|
|
9
|
+
function Try-ReadJson {
|
|
10
|
+
param([string]$Path)
|
|
11
|
+
if (-not (Test-Path $Path)) { return $null }
|
|
12
|
+
try { return Get-Content -Raw -Path $Path | ConvertFrom-Json } catch { return $null }
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function Ensure-Dir {
|
|
16
|
+
param([string]$Path)
|
|
17
|
+
if (-not (Test-Path $Path)) {
|
|
18
|
+
New-Item -ItemType Directory -Path $Path -Force | Out-Null
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function Resolve-ConfiguredPath {
|
|
23
|
+
param([string]$Value, [string]$RuntimeRoot)
|
|
24
|
+
if (-not $Value) { return "" }
|
|
25
|
+
$expanded = [Environment]::ExpandEnvironmentVariables($Value)
|
|
26
|
+
if ([System.IO.Path]::IsPathRooted($expanded)) { return $expanded }
|
|
27
|
+
return [System.IO.Path]::GetFullPath((Join-Path $RuntimeRoot $expanded))
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function Read-DotEnvFile {
|
|
31
|
+
param([string]$Path)
|
|
32
|
+
$values = @{}
|
|
33
|
+
if (-not (Test-Path $Path)) { return $values }
|
|
34
|
+
foreach ($line in (Get-Content -Path $Path)) {
|
|
35
|
+
if (-not $line) { continue }
|
|
36
|
+
if ($line.Trim().StartsWith("#")) { continue }
|
|
37
|
+
$parts = $line -split "=", 2
|
|
38
|
+
if ($parts.Count -ne 2) { continue }
|
|
39
|
+
$values[$parts[0].Trim()] = $parts[1]
|
|
40
|
+
}
|
|
41
|
+
return $values
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function Write-DotEnvFile {
|
|
45
|
+
param(
|
|
46
|
+
[string]$Path,
|
|
47
|
+
[hashtable]$Values
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
$lines = foreach ($key in ($Values.Keys | Sort-Object)) {
|
|
51
|
+
"$key=$($Values[$key])"
|
|
52
|
+
}
|
|
53
|
+
Set-Content -Path $Path -Value $lines -Encoding UTF8
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function Test-TelegramTokenFormat {
|
|
57
|
+
param([string]$Value)
|
|
58
|
+
if (-not $Value) { return $false }
|
|
59
|
+
return $Value -match '^\d{6,}:[A-Za-z0-9_-]{20,}$'
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function Test-AllowedChatIdsFormat {
|
|
63
|
+
param([string]$Value)
|
|
64
|
+
if (-not $Value) { return $false }
|
|
65
|
+
$parts = @($Value -split "," | ForEach-Object { $_.Trim() } | Where-Object { $_ })
|
|
66
|
+
if ($parts.Count -eq 0) { return $false }
|
|
67
|
+
foreach ($part in $parts) {
|
|
68
|
+
if ($part -notmatch '^-?\d+$') {
|
|
69
|
+
return $false
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return $true
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function Invoke-TelegramSetupRequest {
|
|
76
|
+
param(
|
|
77
|
+
[string]$Token,
|
|
78
|
+
[string]$Method,
|
|
79
|
+
[hashtable]$Body = @{}
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
$uri = "https://api.telegram.org/bot$Token/$Method"
|
|
83
|
+
try {
|
|
84
|
+
return Invoke-RestMethod -Method Post -Uri $uri -ContentType "application/json" -Body ($Body | ConvertTo-Json -Depth 10) -TimeoutSec 35
|
|
85
|
+
} catch {
|
|
86
|
+
$message = $_.Exception.Message
|
|
87
|
+
if ($_.ErrorDetails -and $_.ErrorDetails.Message) {
|
|
88
|
+
$message = $_.ErrorDetails.Message
|
|
89
|
+
}
|
|
90
|
+
throw "Telegram $Method fehlgeschlagen: $message"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function Get-TelegramBotInfo {
|
|
95
|
+
param([string]$Token)
|
|
96
|
+
$response = Invoke-TelegramSetupRequest -Token $Token -Method "getMe"
|
|
97
|
+
if (-not $response.ok) {
|
|
98
|
+
throw "Telegram Bot Token wurde von Telegram abgelehnt."
|
|
99
|
+
}
|
|
100
|
+
return $response.result
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function Get-TelegramUpdatesForSetup {
|
|
104
|
+
param(
|
|
105
|
+
[string]$Token,
|
|
106
|
+
[long]$Offset = 0,
|
|
107
|
+
[int]$TimeoutSeconds = 0
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
$body = @{
|
|
111
|
+
timeout = $TimeoutSeconds
|
|
112
|
+
limit = 20
|
|
113
|
+
allowed_updates = @("message", "edited_message", "channel_post")
|
|
114
|
+
}
|
|
115
|
+
if ($Offset -gt 0) {
|
|
116
|
+
$body["offset"] = $Offset
|
|
117
|
+
}
|
|
118
|
+
$response = Invoke-TelegramSetupRequest -Token $Token -Method "getUpdates" -Body $body
|
|
119
|
+
if (-not $response.ok) {
|
|
120
|
+
return @()
|
|
121
|
+
}
|
|
122
|
+
return @($response.result)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function Get-TelegramUpdateId {
|
|
126
|
+
param($Update)
|
|
127
|
+
try {
|
|
128
|
+
return [long]$Update.update_id
|
|
129
|
+
} catch {
|
|
130
|
+
return 0
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function Get-TelegramChatFromUpdate {
|
|
135
|
+
param($Update)
|
|
136
|
+
|
|
137
|
+
$message = $null
|
|
138
|
+
if ($Update.message) {
|
|
139
|
+
$message = $Update.message
|
|
140
|
+
} elseif ($Update.edited_message) {
|
|
141
|
+
$message = $Update.edited_message
|
|
142
|
+
} elseif ($Update.channel_post) {
|
|
143
|
+
$message = $Update.channel_post
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (-not $message -or -not $message.chat -or -not $message.chat.id) {
|
|
147
|
+
return $null
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
$chat = $message.chat
|
|
151
|
+
$title = ""
|
|
152
|
+
if ($chat.title) {
|
|
153
|
+
$title = [string]$chat.title
|
|
154
|
+
} elseif ($chat.username) {
|
|
155
|
+
$title = "@" + [string]$chat.username
|
|
156
|
+
} elseif ($chat.first_name -or $chat.last_name) {
|
|
157
|
+
$title = ((@($chat.first_name, $chat.last_name) | Where-Object { $_ }) -join " ")
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return [ordered]@{
|
|
161
|
+
chat_id = [string]$chat.id
|
|
162
|
+
chat_type = [string]$chat.type
|
|
163
|
+
title = $title
|
|
164
|
+
update_id = Get-TelegramUpdateId -Update $Update
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function Wait-TelegramPairingChat {
|
|
169
|
+
param(
|
|
170
|
+
[string]$Token,
|
|
171
|
+
$BotInfo,
|
|
172
|
+
[int]$TimeoutSeconds = 90
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
$baseline = Get-TelegramUpdatesForSetup -Token $Token -TimeoutSeconds 0
|
|
176
|
+
$offset = 0
|
|
177
|
+
foreach ($update in $baseline) {
|
|
178
|
+
$offset = [Math]::Max($offset, (Get-TelegramUpdateId -Update $update) + 1)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
$botName = if ($BotInfo.username) { "@" + [string]$BotInfo.username } else { "deinen Bot" }
|
|
182
|
+
Write-Host ""
|
|
183
|
+
Write-Host "Telegram Pairing" -ForegroundColor Cyan
|
|
184
|
+
Write-Host "Oeffne Telegram und sende jetzt eine neue Nachricht an $botName." -ForegroundColor White
|
|
185
|
+
Write-Host "Fuer Gruppen: Bot in die Gruppe einladen und dort kurz '$botName connect' schreiben." -ForegroundColor DarkGray
|
|
186
|
+
Write-Host "Ich erkenne die Chat-ID automatisch. Du musst keine ID suchen." -ForegroundColor DarkGray
|
|
187
|
+
Write-Host ""
|
|
188
|
+
|
|
189
|
+
$deadline = (Get-Date).AddSeconds($TimeoutSeconds)
|
|
190
|
+
while ((Get-Date) -lt $deadline) {
|
|
191
|
+
$remaining = [Math]::Max(1, [int]([Math]::Ceiling(($deadline - (Get-Date)).TotalSeconds)))
|
|
192
|
+
$pollTimeout = [Math]::Min(10, $remaining)
|
|
193
|
+
$updates = Get-TelegramUpdatesForSetup -Token $Token -Offset $offset -TimeoutSeconds $pollTimeout
|
|
194
|
+
foreach ($update in $updates) {
|
|
195
|
+
$updateId = Get-TelegramUpdateId -Update $update
|
|
196
|
+
if ($updateId -gt 0) {
|
|
197
|
+
$offset = [Math]::Max($offset, $updateId + 1)
|
|
198
|
+
}
|
|
199
|
+
$chat = Get-TelegramChatFromUpdate -Update $update
|
|
200
|
+
if ($chat -and $chat.chat_id) {
|
|
201
|
+
return $chat
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return $null
|
|
207
|
+
}
|
|
208
|
+
|
|
75
209
|
function Prompt-RequiredValue {
|
|
76
|
-
param(
|
|
77
|
-
[string]$Prompt,
|
|
78
|
-
[string]$CurrentValue,
|
|
79
|
-
[scriptblock]$Validator,
|
|
80
|
-
[string]$ErrorMessage
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
while ($true) {
|
|
84
|
-
$fullPrompt = if ($CurrentValue) { "$Prompt [$CurrentValue]" } else { $Prompt }
|
|
85
|
-
$inputValue = Read-Host -Prompt $fullPrompt
|
|
86
|
-
if (-not $inputValue -and $CurrentValue) {
|
|
87
|
-
$inputValue = $CurrentValue
|
|
88
|
-
}
|
|
89
|
-
$inputValue = [string]$inputValue
|
|
90
|
-
if (& $Validator $inputValue) {
|
|
91
|
-
return $inputValue
|
|
92
|
-
}
|
|
93
|
-
Write-Host $ErrorMessage -ForegroundColor Yellow
|
|
210
|
+
param(
|
|
211
|
+
[string]$Prompt,
|
|
212
|
+
[string]$CurrentValue,
|
|
213
|
+
[scriptblock]$Validator,
|
|
214
|
+
[string]$ErrorMessage
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
while ($true) {
|
|
218
|
+
$fullPrompt = if ($CurrentValue) { "$Prompt [$CurrentValue]" } else { $Prompt }
|
|
219
|
+
$inputValue = Read-Host -Prompt $fullPrompt
|
|
220
|
+
if (-not $inputValue -and $CurrentValue) {
|
|
221
|
+
$inputValue = $CurrentValue
|
|
222
|
+
}
|
|
223
|
+
$inputValue = [string]$inputValue
|
|
224
|
+
if (& $Validator $inputValue) {
|
|
225
|
+
return $inputValue
|
|
226
|
+
}
|
|
227
|
+
Write-Host $ErrorMessage -ForegroundColor Yellow
|
|
94
228
|
}
|
|
95
229
|
}
|
|
96
230
|
|
|
@@ -122,19 +256,19 @@ function Get-ProfilePath {
|
|
|
122
256
|
$runtimeRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
123
257
|
$profilePath = Get-ProfilePath -RuntimeRoot $runtimeRoot -ProfileName $Profile
|
|
124
258
|
$profileJson = Try-ReadJson -Path $profilePath
|
|
125
|
-
|
|
126
|
-
if (-not $profileJson) {
|
|
127
|
-
throw "Profile not found or invalid: $profilePath"
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
$profileAgent = if ($profileJson.agent_name) { [string]$profileJson.agent_name } else { $Profile.ToLower() }
|
|
131
|
-
$stateDir = if ($profileJson.telegram -and $profileJson.telegram.state_dir) {
|
|
132
|
-
Resolve-ConfiguredPath -Value ([string]$profileJson.telegram.state_dir) -RuntimeRoot $runtimeRoot
|
|
133
|
-
} else {
|
|
134
|
-
Join-Path $env:USERPROFILE (".codex\channels\telegram-" + $profileAgent)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
Ensure-Dir -Path $stateDir
|
|
259
|
+
|
|
260
|
+
if (-not $profileJson) {
|
|
261
|
+
throw "Profile not found or invalid: $profilePath"
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
$profileAgent = if ($profileJson.agent_name) { [string]$profileJson.agent_name } else { $Profile.ToLower() }
|
|
265
|
+
$stateDir = if ($profileJson.telegram -and $profileJson.telegram.state_dir) {
|
|
266
|
+
Resolve-ConfiguredPath -Value ([string]$profileJson.telegram.state_dir) -RuntimeRoot $runtimeRoot
|
|
267
|
+
} else {
|
|
268
|
+
Join-Path $env:USERPROFILE (".codex\channels\telegram-" + $profileAgent)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
Ensure-Dir -Path $stateDir
|
|
138
272
|
$envPath = Join-Path $stateDir ".env"
|
|
139
273
|
$envValues = Read-DotEnvFile -Path $envPath
|
|
140
274
|
|
|
@@ -147,12 +281,13 @@ $currentAllowedChatIds = [string]$envValues["BLUN_TELEGRAM_ALLOWED_CHAT_ID"]
|
|
|
147
281
|
if (-not (Test-AllowedChatIdsFormat -Value $currentAllowedChatIds)) {
|
|
148
282
|
$currentAllowedChatIds = [string]$envValues["TELEGRAM_ALLOWED_CHAT_ID"]
|
|
149
283
|
}
|
|
150
|
-
|
|
284
|
+
|
|
151
285
|
$needsToken = -not (Test-TelegramTokenFormat -Value $currentToken)
|
|
152
286
|
$needsChatIds = -not (Test-AllowedChatIdsFormat -Value $currentAllowedChatIds)
|
|
153
287
|
$changed = $false
|
|
288
|
+
$tokenWasPrompted = $false
|
|
154
289
|
|
|
155
|
-
if ($EnsureConfigured -and -not $needsToken) {
|
|
290
|
+
if ($EnsureConfigured -and -not $needsToken -and -not $needsChatIds) {
|
|
156
291
|
$result = [ordered]@{
|
|
157
292
|
ok = $true
|
|
158
293
|
changed = $false
|
|
@@ -160,18 +295,13 @@ if ($EnsureConfigured -and -not $needsToken) {
|
|
|
160
295
|
state_dir = $stateDir
|
|
161
296
|
env_path = $envPath
|
|
162
297
|
missing = @()
|
|
163
|
-
optional = @(
|
|
164
|
-
"allowed_chat_ids"
|
|
165
|
-
)
|
|
298
|
+
optional = @()
|
|
166
299
|
}
|
|
167
300
|
if ($Json) {
|
|
168
301
|
$result | ConvertTo-Json -Depth 6
|
|
169
302
|
} else {
|
|
170
303
|
Write-Host "Telegram ist bereits eingerichtet fuer Profil '$profileAgent'." -ForegroundColor Green
|
|
171
304
|
Write-Host "State-Ordner: $stateDir"
|
|
172
|
-
if ($needsChatIds) {
|
|
173
|
-
Write-Host "Hinweis: keine Chat-Allowlist gesetzt. Der Bot akzeptiert aktuell alle Chats, die er sehen kann." -ForegroundColor Yellow
|
|
174
|
-
}
|
|
175
305
|
}
|
|
176
306
|
exit 0
|
|
177
307
|
}
|
|
@@ -192,63 +322,83 @@ if ($EnsureConfigured -and $Json -and $needsToken) {
|
|
|
192
322
|
} | ConvertTo-Json -Depth 6
|
|
193
323
|
exit 2
|
|
194
324
|
}
|
|
195
|
-
|
|
196
|
-
if (-not $Json) {
|
|
197
|
-
Write-Host ""
|
|
198
|
-
Write-Host "CodexLink Telegram Setup" -ForegroundColor Cyan
|
|
199
|
-
Write-Host "Profil: $profileAgent"
|
|
200
|
-
Write-Host "Lokaler State-Ordner: $stateDir"
|
|
201
|
-
Write-Host ""
|
|
202
|
-
Write-Host "Ich speichere die Telegram-Werte automatisch an die richtige lokale Stelle." -ForegroundColor DarkGray
|
|
325
|
+
|
|
326
|
+
if (-not $Json) {
|
|
327
|
+
Write-Host ""
|
|
328
|
+
Write-Host "CodexLink Telegram Setup" -ForegroundColor Cyan
|
|
329
|
+
Write-Host "Profil: $profileAgent"
|
|
330
|
+
Write-Host "Lokaler State-Ordner: $stateDir"
|
|
331
|
+
Write-Host ""
|
|
332
|
+
Write-Host "Ich speichere die Telegram-Werte automatisch an die richtige lokale Stelle." -ForegroundColor DarkGray
|
|
203
333
|
Write-Host "Du musst keine .env-Datei selbst suchen." -ForegroundColor DarkGray
|
|
204
|
-
Write-Host "Chat-ID
|
|
334
|
+
Write-Host "Die Chat-ID wird automatisch erkannt. Du musst sie nicht wissen." -ForegroundColor DarkGray
|
|
205
335
|
Write-Host ""
|
|
206
336
|
}
|
|
207
|
-
|
|
208
|
-
if ($needsToken) {
|
|
209
|
-
$currentToken = Prompt-RequiredValue `
|
|
210
|
-
-Prompt "Telegram Bot Token" `
|
|
211
|
-
-CurrentValue $currentToken `
|
|
212
|
-
-Validator { param($v) Test-TelegramTokenFormat -Value $v } `
|
|
213
|
-
-ErrorMessage "Bitte einen gueltigen Telegram Bot Token eingeben. Beispiel: 123456789:ABC..."
|
|
214
|
-
$envValues["BLUN_TELEGRAM_BOT_TOKEN"] = $currentToken
|
|
215
|
-
$changed = $true
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (-not $EnsureConfigured -and $needsChatIds) {
|
|
219
|
-
$currentAllowedChatIds = Prompt-RequiredValue `
|
|
220
|
-
-Prompt "Erlaubte Chat ID(s), komma-getrennt" `
|
|
221
|
-
-CurrentValue $currentAllowedChatIds `
|
|
222
|
-
-Validator { param($v) Test-AllowedChatIdsFormat -Value $v } `
|
|
223
|
-
-ErrorMessage "Bitte mindestens eine numerische Chat-ID eingeben. Mehrere IDs mit Komma trennen."
|
|
224
|
-
$envValues["BLUN_TELEGRAM_ALLOWED_CHAT_ID"] = (($currentAllowedChatIds -split "," | ForEach-Object { $_.Trim() } | Where-Object { $_ }) -join ",")
|
|
337
|
+
|
|
338
|
+
if ($needsToken) {
|
|
339
|
+
$currentToken = Prompt-RequiredValue `
|
|
340
|
+
-Prompt "Telegram Bot Token" `
|
|
341
|
+
-CurrentValue $currentToken `
|
|
342
|
+
-Validator { param($v) Test-TelegramTokenFormat -Value $v } `
|
|
343
|
+
-ErrorMessage "Bitte einen gueltigen Telegram Bot Token eingeben. Beispiel: 123456789:ABC..."
|
|
344
|
+
$envValues["BLUN_TELEGRAM_BOT_TOKEN"] = $currentToken
|
|
225
345
|
$changed = $true
|
|
346
|
+
$tokenWasPrompted = $true
|
|
226
347
|
}
|
|
227
|
-
|
|
228
|
-
$
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
$
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
Write-Host ""
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
Write-Host
|
|
253
|
-
Write-Host "
|
|
254
|
-
|
|
348
|
+
|
|
349
|
+
if ($needsChatIds -and -not $Json) {
|
|
350
|
+
try {
|
|
351
|
+
$botInfo = Get-TelegramBotInfo -Token $currentToken
|
|
352
|
+
$shouldPair = $tokenWasPrompted -or (-not $EnsureConfigured)
|
|
353
|
+
if ($shouldPair) {
|
|
354
|
+
$pairedChat = Wait-TelegramPairingChat -Token $currentToken -BotInfo $botInfo -TimeoutSeconds 90
|
|
355
|
+
if ($pairedChat -and $pairedChat.chat_id) {
|
|
356
|
+
$currentAllowedChatIds = [string]$pairedChat.chat_id
|
|
357
|
+
$envValues["BLUN_TELEGRAM_ALLOWED_CHAT_ID"] = $currentAllowedChatIds
|
|
358
|
+
$envValues["BLUN_TELEGRAM_PAIRING_DONE"] = "1"
|
|
359
|
+
$changed = $true
|
|
360
|
+
$label = if ($pairedChat.title) { "$($pairedChat.title) ($($pairedChat.chat_type))" } else { $pairedChat.chat_type }
|
|
361
|
+
Write-Host "Gekoppelt: $label -> $currentAllowedChatIds" -ForegroundColor Green
|
|
362
|
+
} else {
|
|
363
|
+
$envValues["BLUN_TELEGRAM_PAIRING_DONE"] = "1"
|
|
364
|
+
Write-Host "Keine Telegram-Nachricht erkannt. Ich starte ohne Allowlist; du kannst spaeter erneut `blun-codex telegram-setup` ausfuehren." -ForegroundColor Yellow
|
|
365
|
+
}
|
|
366
|
+
} else {
|
|
367
|
+
Write-Host "Hinweis: keine Chat-Allowlist gesetzt. Der Bot akzeptiert aktuell alle Chats, die er sehen kann." -ForegroundColor Yellow
|
|
368
|
+
}
|
|
369
|
+
} catch {
|
|
370
|
+
if ($tokenWasPrompted) {
|
|
371
|
+
throw
|
|
372
|
+
}
|
|
373
|
+
Write-Host $_.Exception.Message -ForegroundColor Yellow
|
|
374
|
+
Write-Host "Ich starte ohne Allowlist; du kannst spaeter erneut `blun-codex telegram-setup` ausfuehren." -ForegroundColor Yellow
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
$envValues["BLUN_TELEGRAM_AGENT_NAME"] = $profileAgent
|
|
379
|
+
$envValues["BLUN_TELEGRAM_STATE_DIR"] = $stateDir
|
|
380
|
+
Write-DotEnvFile -Path $envPath -Values $envValues
|
|
381
|
+
|
|
382
|
+
$result = [ordered]@{
|
|
383
|
+
ok = $true
|
|
384
|
+
changed = $changed
|
|
385
|
+
profile = $profileAgent
|
|
386
|
+
state_dir = $stateDir
|
|
387
|
+
env_path = $envPath
|
|
388
|
+
missing = @()
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if ($Json) {
|
|
392
|
+
$result | ConvertTo-Json -Depth 6
|
|
393
|
+
exit 0
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
Write-Host ""
|
|
397
|
+
Write-Host "Telegram ist jetzt eingerichtet." -ForegroundColor Green
|
|
398
|
+
Write-Host "Gespeichert unter: $envPath"
|
|
399
|
+
Write-Host ""
|
|
400
|
+
Write-Host "Naechster Schritt:" -ForegroundColor Cyan
|
|
401
|
+
Write-Host " blun-codex --profile $profileAgent telegram-plugin"
|
|
402
|
+
Write-Host ""
|
|
403
|
+
Write-Host "Pruefen kannst du spaeter mit:" -ForegroundColor Cyan
|
|
404
|
+
Write-Host " blun-codex --profile $profileAgent telegram-doctor"
|