appback-remoteagent 0.13.0 → 0.13.1

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/dist/index.js CHANGED
@@ -60,7 +60,7 @@ async function main() {
60
60
  console.error("Local UI failed to start:", error);
61
61
  });
62
62
  }
63
- const botInfos = config.telegramBotTokens.map((token, index) => buildBotInfo(token, index));
63
+ const botInfos = await Promise.all(config.telegramBotTokens.map((token, index) => resolveBotInfo(token, index)));
64
64
  const bots = config.telegramBotTokens.map((token, index) => createBot(token, bridge, botManagement, botInfos[index]));
65
65
  if (config.telegramCommandMenuEnabled) {
66
66
  for (const bot of bots) {
@@ -416,11 +416,41 @@ class AsyncSemaphore {
416
416
  }
417
417
  }
418
418
  }
419
- function buildBotInfo(token, index) {
419
+ async function resolveBotInfo(token, index) {
420
+ try {
421
+ const { stdout } = await execFileAsync("curl", [
422
+ "-sS",
423
+ "-4",
424
+ "--max-time",
425
+ "10",
426
+ `https://api.telegram.org/bot${token}/getMe`,
427
+ ]);
428
+ const payload = JSON.parse(stdout);
429
+ if (payload.ok && payload.result?.id && payload.result.username) {
430
+ return buildBotInfoFromIdentity(payload.result.id, payload.result.username, payload.result.first_name);
431
+ }
432
+ console.warn(`Telegram getMe failed for bot ${tokenIdLabel(token)}: ${payload.description || "missing bot identity"}`);
433
+ }
434
+ catch (error) {
435
+ console.warn(`Telegram getMe failed for bot ${tokenIdLabel(token)}: ${summarizeTelegramIdentityError(error)}`);
436
+ }
437
+ return buildFallbackBotInfo(token, index);
438
+ }
439
+ function buildBotInfoFromIdentity(id, username, firstName) {
440
+ return {
441
+ id,
442
+ is_bot: true,
443
+ first_name: firstName || username,
444
+ username,
445
+ can_join_groups: false,
446
+ can_read_all_group_messages: false,
447
+ supports_inline_queries: false,
448
+ };
449
+ }
450
+ function buildFallbackBotInfo(token, index) {
420
451
  const id = Number.parseInt(token.split(":", 1)[0] ?? "", 10);
421
- const configuredUsername = config.telegramBotUsernames[index];
422
452
  const fallbackUsername = knownBotUsername(id);
423
- const username = configuredUsername || fallbackUsername || `bot_${Number.isFinite(id) ? id : index + 1}`;
453
+ const username = fallbackUsername || `bot_${Number.isFinite(id) ? id : index + 1}`;
424
454
  return {
425
455
  id: Number.isFinite(id) ? id : index + 1,
426
456
  is_bot: true,
@@ -431,6 +461,20 @@ function buildBotInfo(token, index) {
431
461
  supports_inline_queries: false,
432
462
  };
433
463
  }
464
+ function tokenIdLabel(token) {
465
+ return token.split(":", 1)[0] || "unknown";
466
+ }
467
+ function summarizeTelegramIdentityError(error) {
468
+ if (!(error instanceof Error)) {
469
+ return String(error);
470
+ }
471
+ const code = typeof error === "object" && error !== null && "code" in error
472
+ ? String(error.code ?? "")
473
+ : "";
474
+ return [code, error.message.replace(/bot\d+:[A-Za-z0-9_-]+/g, "bot[redacted]")]
475
+ .filter(Boolean)
476
+ .join(" ");
477
+ }
434
478
  function knownBotUsername(id) {
435
479
  if (id === 8369496408) {
436
480
  return "codex_remoteagent_bot";
@@ -206,8 +206,8 @@ export class BotManagementService {
206
206
  const transient = [];
207
207
  for (const bot of bots) {
208
208
  try {
209
- await this.fetchBotIdentity(bot.token);
210
- alive.push(bot);
209
+ const identity = await this.fetchBotIdentity(bot.token);
210
+ alive.push({ ...identity, index: bot.index });
211
211
  }
212
212
  catch (error) {
213
213
  const reason = error instanceof Error ? error.message : String(error);
@@ -453,7 +453,8 @@ export class BotManagementService {
453
453
  : singleTokenLine
454
454
  ? [singleTokenLine.slice("TELEGRAM_BOT_TOKEN=".length).trim()].filter(Boolean)
455
455
  : [];
456
- const usernames = usernameLine ? this.parseCsv(usernameLine.slice("TELEGRAM_BOT_USERNAMES=".length)) : [];
456
+ const configuredUsernames = usernameLine ? this.parseCsv(usernameLine.slice("TELEGRAM_BOT_USERNAMES=".length)) : [];
457
+ const usernames = await this.normalizeUsernamesFromTelegram(tokens, configuredUsernames);
457
458
  return {
458
459
  lines,
459
460
  tokens,
@@ -462,7 +463,7 @@ export class BotManagementService {
462
463
  };
463
464
  }
464
465
  async writeEnvConfig(originalLines, tokens, usernames, mainBotId) {
465
- const normalizedUsernames = this.normalizeUsernames(tokens, usernames);
466
+ const normalizedUsernames = await this.normalizeUsernamesFromTelegram(tokens, usernames);
466
467
  const normalizedMainBotId = this.resolveMainBotId(this.zipBots(tokens, normalizedUsernames), mainBotId);
467
468
  const nextLines = [];
468
469
  let hasMulti = false;
@@ -510,7 +511,23 @@ export class BotManagementService {
510
511
  await fs.writeFile(this.envPath, output, "utf8");
511
512
  }
512
513
  normalizeUsernames(tokens, usernames) {
513
- return tokens.map((token, index) => usernames[index]?.trim() || `bot_${this.tokenId(token)}`);
514
+ return tokens.map((token, index) => usernames[index]?.trim() || this.fallbackUsername(token));
515
+ }
516
+ async normalizeUsernamesFromTelegram(tokens, usernames) {
517
+ const normalized = [];
518
+ for (const token of tokens) {
519
+ try {
520
+ const identity = await this.fetchBotIdentity(token);
521
+ normalized.push(identity.username);
522
+ }
523
+ catch {
524
+ normalized.push(this.fallbackUsername(token));
525
+ }
526
+ }
527
+ return normalized;
528
+ }
529
+ fallbackUsername(token) {
530
+ return `bot_${this.tokenId(token)}`;
514
531
  }
515
532
  zipBots(tokens, usernames) {
516
533
  const normalizedUsernames = this.normalizeUsernames(tokens, usernames);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appback-remoteagent",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
4
4
  "description": "Personal installable session server for continuing local AI work across PC and Telegram",
5
5
  "license": "MIT",
6
6
  "type": "module",