@s0nderlabs/anima-plugin-telegram 0.24.11 → 0.24.13
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/package.json +2 -2
- package/src/listener.ts +33 -0
- package/src/types.ts +13 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@s0nderlabs/anima-plugin-telegram",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Telegram gateway plugin for anima — long-poll bot, debounced dispatch, reactions, allowlist",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"test": "bun test"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@s0nderlabs/anima-core": "0.24.
|
|
42
|
+
"@s0nderlabs/anima-core": "0.24.13",
|
|
43
43
|
"grammy": "^1.42.0",
|
|
44
44
|
"zod": "^3.23.8"
|
|
45
45
|
}
|
package/src/listener.ts
CHANGED
|
@@ -237,6 +237,14 @@ export class TelegramListener {
|
|
|
237
237
|
this.installCallbackHandler(handler)
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
+
// v0.24.12: operator-notifier slot. Gateway fills it with brain clarify
|
|
241
|
+
// questions on autonomous market wakes; we broadcast to every allowed
|
|
242
|
+
// chat so the operator sees the question on their phone when no TUI is
|
|
243
|
+
// attached.
|
|
244
|
+
if (this.opts.operatorNotifier) {
|
|
245
|
+
this.opts.operatorNotifier.current = text => this.notifyOperators(text)
|
|
246
|
+
}
|
|
247
|
+
|
|
240
248
|
await clearWebhookBeforePolling(this.bot)
|
|
241
249
|
|
|
242
250
|
// v0.20.0: register the bot command menu so Telegram clients show
|
|
@@ -279,6 +287,7 @@ export class TelegramListener {
|
|
|
279
287
|
clearTimeout(this.retryTimer)
|
|
280
288
|
this.retryTimer = null
|
|
281
289
|
}
|
|
290
|
+
if (this.opts.operatorNotifier) this.opts.operatorNotifier.current = null
|
|
282
291
|
if (!this.running) {
|
|
283
292
|
this.releaseLock()
|
|
284
293
|
return
|
|
@@ -298,6 +307,30 @@ export class TelegramListener {
|
|
|
298
307
|
this.releaseLock()
|
|
299
308
|
}
|
|
300
309
|
|
|
310
|
+
/**
|
|
311
|
+
* v0.24.12: broadcast a short text to every allowed operator chat. Used
|
|
312
|
+
* by the gateway to forward unsolicited brain prompts (clarify on
|
|
313
|
+
* autonomous market wakes) when no TUI is connected. Best-effort: per-chat
|
|
314
|
+
* failures are logged but don't stop the broadcast.
|
|
315
|
+
*/
|
|
316
|
+
private async notifyOperators(text: string): Promise<void> {
|
|
317
|
+
if (!this.running) return
|
|
318
|
+
const trimmed = text.trim()
|
|
319
|
+
if (trimmed.length === 0) return
|
|
320
|
+
const body = trimmed.length > 3500 ? `${trimmed.slice(0, 3500)}\n[truncated]` : trimmed
|
|
321
|
+
await Promise.allSettled(
|
|
322
|
+
this.opts.allowedUserIds.map(async chatId => {
|
|
323
|
+
try {
|
|
324
|
+
await this.bot.api.sendMessage(chatId, body)
|
|
325
|
+
} catch (err) {
|
|
326
|
+
console.warn(
|
|
327
|
+
`[telegram] notifyOperators chat=${chatId} failed: ${(err as Error).message?.slice(0, 200) ?? 'unknown'}`,
|
|
328
|
+
)
|
|
329
|
+
}
|
|
330
|
+
}),
|
|
331
|
+
)
|
|
332
|
+
}
|
|
333
|
+
|
|
301
334
|
private scheduleStartRetry(): void {
|
|
302
335
|
if (this.stopped) return
|
|
303
336
|
if (this.retryAttempts >= MAX_LOCK_RETRY_ATTEMPTS) {
|
package/src/types.ts
CHANGED
|
@@ -50,6 +50,19 @@ export interface TelegramRuntimeContext {
|
|
|
50
50
|
* modal handles all approvals as before.
|
|
51
51
|
*/
|
|
52
52
|
approvalBridge?: TelegramApprovalBridge
|
|
53
|
+
/**
|
|
54
|
+
* v0.24.12: outbound slot the listener fills on `start()` with a method
|
|
55
|
+
* that broadcasts a short text to every allowed operator chat. The
|
|
56
|
+
* gateway uses it to forward unsolicited brain prompts (clarify on
|
|
57
|
+
* autonomous market wakes) when no TUI is connected. When absent, the
|
|
58
|
+
* gateway logs the question to activity-log only.
|
|
59
|
+
*/
|
|
60
|
+
operatorNotifier?: OperatorNotifierSlot
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Mutable slot the listener fills on start so the gateway can broadcast clarify questions. */
|
|
64
|
+
export interface OperatorNotifierSlot {
|
|
65
|
+
current: ((text: string) => Promise<void>) | null
|
|
53
66
|
}
|
|
54
67
|
|
|
55
68
|
export type ApprovalChoiceKind = 'once' | 'session' | 'always' | 'deny'
|