@blunking/codexlink 0.1.9 → 0.1.10

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 CHANGED
@@ -58,12 +58,11 @@ Telegram aktivieren:
58
58
  blun-codex telegram-plugin
59
59
  ```
60
60
 
61
- Wenn Telegram noch nicht eingerichtet ist, startet automatisch ein kurzer Setup-Flow und fragt:
62
-
63
- - Telegram Bot Token
64
- - erlaubte Chat ID(s)
65
-
66
- Die Werte werden automatisch lokal an die richtige Stelle geschrieben. Du musst keine `.env`-Datei suchen.
61
+ Wenn Telegram noch nicht eingerichtet ist, startet automatisch ein kurzer Setup-Flow und fragt:
62
+
63
+ - Telegram Bot Token
64
+
65
+ Danach oeffnest du Telegram und sendest eine Nachricht an den Bot. CodexLink erkennt Chat oder Gruppe automatisch und schreibt alles lokal an die richtige Stelle. Du musst keine Chat-ID suchen und keine `.env`-Datei bearbeiten.
67
66
 
68
67
  Pruefen:
69
68
 
@@ -241,17 +240,18 @@ The bundled plugin lives under `telegram-plugin/` and contains:
241
240
 
242
241
  ## First-run behavior
243
242
 
244
- `blun-codex telegram-plugin` now behaves like a guided setup for normal users:
245
-
246
- 1. check whether Telegram is already configured
247
- 2. ask only for a missing Bot Token
248
- 3. save everything automatically into the local Telegram state folder
249
- 4. continue into Telegram mode
250
-
251
- Allowed Chat ID(s) are optional. If you leave them unset, the bot can currently accept any chat it can see. You can tighten that later with:
252
-
253
- ```powershell
254
- blun-codex telegram-setup
243
+ `blun-codex telegram-plugin` now behaves like a guided setup for normal users:
244
+
245
+ 1. check whether Telegram is already configured
246
+ 2. ask only for a missing Bot Token
247
+ 3. wait for one Telegram message to the bot
248
+ 4. detect and store the chat/group ID automatically
249
+ 5. continue into Telegram mode
250
+
251
+ Allowed Chat ID(s) are no longer typed by hand. To pair a different chat or group later, run:
252
+
253
+ ```powershell
254
+ blun-codex telegram-setup
255
255
  ```
256
256
 
257
257
  If something is missing later, `blun-codex telegram-doctor` tells you exactly what is missing and what to run next.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blunking/codexlink",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "BLUN CLI launcher with Telegram channel support for one visible session.",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -59,7 +59,7 @@ function Test-TelegramTokenFormat {
59
59
  return $Value -match '^\d{6,}:[A-Za-z0-9_-]{20,}$'
60
60
  }
61
61
 
62
- function Test-AllowedChatIdsFormat {
62
+ function Test-AllowedChatIdsFormat {
63
63
  param([string]$Value)
64
64
  if (-not $Value) { return $false }
65
65
  $parts = @($Value -split "," | ForEach-Object { $_.Trim() } | Where-Object { $_ })
@@ -69,9 +69,143 @@ function Test-AllowedChatIdsFormat {
69
69
  return $false
70
70
  }
71
71
  }
72
- return $true
73
- }
74
-
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
210
  param(
77
211
  [string]$Prompt,
@@ -151,8 +285,9 @@ if (-not (Test-AllowedChatIdsFormat -Value $currentAllowedChatIds)) {
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
  }
@@ -198,10 +328,10 @@ if (-not $Json) {
198
328
  Write-Host "CodexLink Telegram Setup" -ForegroundColor Cyan
199
329
  Write-Host "Profil: $profileAgent"
200
330
  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
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-Allowlist ist optional und blockiert den Start nicht mehr." -ForegroundColor DarkGray
334
+ Write-Host "Die Chat-ID wird automatisch erkannt. Du musst sie nicht wissen." -ForegroundColor DarkGray
205
335
  Write-Host ""
206
336
  }
207
337
 
@@ -211,18 +341,38 @@ if ($needsToken) {
211
341
  -CurrentValue $currentToken `
212
342
  -Validator { param($v) Test-TelegramTokenFormat -Value $v } `
213
343
  -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 ",")
344
+ $envValues["BLUN_TELEGRAM_BOT_TOKEN"] = $currentToken
225
345
  $changed = $true
346
+ $tokenWasPrompted = $true
347
+ }
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
+ }
226
376
  }
227
377
 
228
378
  $envValues["BLUN_TELEGRAM_AGENT_NAME"] = $profileAgent