appback-remoteagent 0.13.20 → 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 +48 -10
  2. package/package.json +1 -1
package/dist/bot.js CHANGED
@@ -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);
@@ -2226,11 +2239,23 @@ async function sendTelegramDocument(botToken, chatId, document) {
2226
2239
  async function sendTelegramMessage(botToken, chatId, text, extra) {
2227
2240
  const startedAt = Date.now();
2228
2241
  try {
2229
- return await callTelegramApi(botToken, "sendMessage", {
2230
- chat_id: String(chatId),
2231
- text,
2232
- parse_mode: extra?.parse_mode,
2233
- });
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
+ }
2234
2259
  }
2235
2260
  finally {
2236
2261
  const elapsedMs = Date.now() - startedAt;
@@ -2239,6 +2264,19 @@ async function sendTelegramMessage(botToken, chatId, text, extra) {
2239
2264
  }
2240
2265
  }
2241
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
+ }
2242
2280
  async function sendTelegramChatAction(botToken, chatId, action) {
2243
2281
  await callTelegramApi(botToken, "sendChatAction", {
2244
2282
  chat_id: String(chatId),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appback-remoteagent",
3
- "version": "0.13.20",
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",