appback-remoteagent 0.13.19 → 0.13.21

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.
Files changed (2) hide show
  1. package/dist/bot.js +57 -16
  2. package/package.json +1 -1
package/dist/bot.js CHANGED
@@ -726,12 +726,12 @@ ${bridge.formatStatus(mapping)}`);
726
726
  return;
727
727
  }
728
728
  if (action === "main") {
729
- const result = await botManagement.setMainBot(rest?.trim() ?? args[1]?.trim() ?? "");
729
+ const result = await botManagement.setMainBot(commandTarget(args, rest));
730
730
  await reply(ctx, result.message);
731
731
  return;
732
732
  }
733
733
  if (action === "remove") {
734
- const result = await botManagement.removeBot(rest?.trim() ?? "", sourceBotId, sourceBotToken, ctx.chat.id);
734
+ const result = await botManagement.removeBot(commandTarget(args, rest), sourceBotId, sourceBotToken, ctx.chat.id);
735
735
  await reply(ctx, result.message);
736
736
  return;
737
737
  }
@@ -741,14 +741,14 @@ ${bridge.formatStatus(mapping)}`);
741
741
  bot.command("sleep", async (ctx) => {
742
742
  await ensureOwnerControlAccess(ctx);
743
743
  const sourceBotId = getBotId();
744
- const { rest } = parseCommand(ctx.message?.text, 2);
745
- const result = await botManagement.sleepBot(rest?.trim() ?? "", sourceBotId);
744
+ const { args, rest } = parseCommand(ctx.message?.text, 1);
745
+ const result = await botManagement.sleepBot(commandTarget(args, rest), sourceBotId);
746
746
  await reply(ctx, result.message);
747
747
  });
748
748
  bot.command("wake", async (ctx) => {
749
749
  await ensureOwnerControlAccess(ctx);
750
- const { rest } = parseCommand(ctx.message?.text, 2);
751
- const result = await botManagement.wakeBot(rest?.trim() ?? "");
750
+ const { args, rest } = parseCommand(ctx.message?.text, 1);
751
+ const result = await botManagement.wakeBot(commandTarget(args, rest));
752
752
  await reply(ctx, result.message);
753
753
  });
754
754
  bot.command("install", async (ctx) => {
@@ -1427,12 +1427,25 @@ function renderTelegramInlineHtml(line) {
1427
1427
  }).join("");
1428
1428
  }
1429
1429
  function renderTelegramTextLinks(value) {
1430
- return value.replace(/https?:\/\/[^\s<>"']+/g, (url) => {
1431
- const trailingMatch = /[),.;!?]+$/.exec(url);
1430
+ const rendered = [];
1431
+ let cursor = 0;
1432
+ const urlPattern = /https?:\/\/[^\s<>"']+/g;
1433
+ for (const match of value.matchAll(urlPattern)) {
1434
+ const rawUrl = match[0];
1435
+ const start = match.index ?? 0;
1436
+ if (start > cursor) {
1437
+ rendered.push(escapeTelegramHtml(value.slice(cursor, start)));
1438
+ }
1439
+ const trailingMatch = /[),.;!?]+$/.exec(rawUrl);
1432
1440
  const trailing = trailingMatch?.[0] ?? "";
1433
- const cleanUrl = trailing ? url.slice(0, -trailing.length) : url;
1434
- return `<a href="${escapeTelegramHtmlAttribute(cleanUrl)}">${escapeTelegramHtml(cleanUrl)}</a>${escapeTelegramHtml(trailing)}`;
1435
- });
1441
+ const cleanUrl = trailing ? rawUrl.slice(0, -trailing.length) : rawUrl;
1442
+ rendered.push(`<a href="${escapeTelegramHtmlAttribute(cleanUrl)}">${escapeTelegramHtml(cleanUrl)}</a>${escapeTelegramHtml(trailing)}`);
1443
+ cursor = start + rawUrl.length;
1444
+ }
1445
+ if (cursor < value.length) {
1446
+ rendered.push(escapeTelegramHtml(value.slice(cursor)));
1447
+ }
1448
+ return rendered.join("");
1436
1449
  }
1437
1450
  function containsUrl(value) {
1438
1451
  return /https?:\/\/[^\s<>"']+/.test(value);
@@ -1657,6 +1670,9 @@ function parseCommand(text, headCount) {
1657
1670
  rest: remaining || undefined,
1658
1671
  };
1659
1672
  }
1673
+ function commandTarget(args, rest) {
1674
+ return (rest?.trim() || args.slice(1).join(" ").trim() || args[0]?.trim() || "");
1675
+ }
1660
1676
  function formatSecretHelp() {
1661
1677
  return [
1662
1678
  "Secret command guide",
@@ -2223,11 +2239,23 @@ async function sendTelegramDocument(botToken, chatId, document) {
2223
2239
  async function sendTelegramMessage(botToken, chatId, text, extra) {
2224
2240
  const startedAt = Date.now();
2225
2241
  try {
2226
- return await callTelegramApi(botToken, "sendMessage", {
2227
- chat_id: String(chatId),
2228
- text,
2229
- parse_mode: extra?.parse_mode,
2230
- });
2242
+ try {
2243
+ return await callTelegramApi(botToken, "sendMessage", {
2244
+ chat_id: String(chatId),
2245
+ text,
2246
+ parse_mode: extra?.parse_mode,
2247
+ });
2248
+ }
2249
+ catch (error) {
2250
+ if (!extra?.parse_mode || !isTelegramEntityParseError(error)) {
2251
+ throw error;
2252
+ }
2253
+ console.warn(`[telegram-sendMessage-fallback] chat=${chatId} parseMode=${extra.parse_mode}: ${error instanceof Error ? error.message : String(error)}`);
2254
+ return await callTelegramApi(botToken, "sendMessage", {
2255
+ chat_id: String(chatId),
2256
+ text: stripTelegramHtml(text),
2257
+ });
2258
+ }
2231
2259
  }
2232
2260
  finally {
2233
2261
  const elapsedMs = Date.now() - startedAt;
@@ -2236,6 +2264,19 @@ async function sendTelegramMessage(botToken, chatId, text, extra) {
2236
2264
  }
2237
2265
  }
2238
2266
  }
2267
+ function isTelegramEntityParseError(error) {
2268
+ const message = error instanceof Error ? error.message : String(error);
2269
+ return /can'?t parse entities|can't parse entities|Unsupported start tag|Bad Request/i.test(message);
2270
+ }
2271
+ function stripTelegramHtml(value) {
2272
+ return value
2273
+ .replace(/<a\s+href="[^"]*">([\s\S]*?)<\/a>/gi, "$1")
2274
+ .replace(/<\/?(?:b|strong|i|em|u|s|strike|del|code|pre|blockquote)(?:\s[^>]*)?>/gi, "")
2275
+ .replace(/&lt;/g, "<")
2276
+ .replace(/&gt;/g, ">")
2277
+ .replace(/&quot;/g, '"')
2278
+ .replace(/&amp;/g, "&");
2279
+ }
2239
2280
  async function sendTelegramChatAction(botToken, chatId, action) {
2240
2281
  await callTelegramApi(botToken, "sendChatAction", {
2241
2282
  chat_id: String(chatId),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appback-remoteagent",
3
- "version": "0.13.19",
3
+ "version": "0.13.21",
4
4
  "description": "Personal installable session server for continuing local AI work across PC and Telegram",
5
5
  "license": "MIT",
6
6
  "type": "module",