@wrongstack/telegram 1.0.11 → 1.0.12

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/index.js +75 -52
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -708,7 +708,62 @@ var Poller = class _Poller {
708
708
  }
709
709
  };
710
710
 
711
+ // src/text-format.ts
712
+ var MAX_TELEGRAM_MESSAGE_LENGTH = 4096;
713
+ function truncateForTelegram(text, maxLen = 4e3) {
714
+ const effectiveMaxLen = Math.min(maxLen, MAX_TELEGRAM_MESSAGE_LENGTH);
715
+ if (text.length <= effectiveMaxLen) return text;
716
+ const cutoff = effectiveMaxLen - 30;
717
+ if (cutoff <= 0) return `${text.slice(0, Math.max(0, effectiveMaxLen - 1))}\u2026`;
718
+ const paraSearchEnd = effectiveMaxLen - 3;
719
+ const paraIdx = text.lastIndexOf("\n\n", paraSearchEnd);
720
+ if (paraIdx > cutoff) {
721
+ return `${text.slice(0, paraIdx)}
722
+
723
+ \u2026`;
724
+ }
725
+ const nlSearchEnd = effectiveMaxLen - 2;
726
+ const nlIdx = text.lastIndexOf("\n", nlSearchEnd);
727
+ if (nlIdx > cutoff) {
728
+ return `${text.slice(0, nlIdx)}
729
+ \u2026`;
730
+ }
731
+ const sentenceSearchEnd = effectiveMaxLen - 1;
732
+ const sentenceRe = /[.!?](?=\s)/g;
733
+ let match;
734
+ let sentenceIdx = -1;
735
+ match = sentenceRe.exec(text);
736
+ while (match !== null) {
737
+ if (match.index + 1 > sentenceSearchEnd) break;
738
+ if (match.index + 1 > cutoff) sentenceIdx = match.index + 1;
739
+ match = sentenceRe.exec(text);
740
+ }
741
+ if (sentenceIdx > cutoff) {
742
+ return `${text.slice(0, sentenceIdx)}\u2026`;
743
+ }
744
+ const spaceSearchEnd = effectiveMaxLen - 2;
745
+ const spaceIdx = text.lastIndexOf(" ", spaceSearchEnd);
746
+ if (spaceIdx > cutoff) {
747
+ return `${text.slice(0, spaceIdx)} \u2026`;
748
+ }
749
+ const hardSlice = text.slice(0, effectiveMaxLen - 20);
750
+ const hardResult = `${hardSlice}\u2026[+${text.length - hardSlice.length} chars]`;
751
+ if (hardResult.length <= effectiveMaxLen) return hardResult;
752
+ return `${text.slice(0, effectiveMaxLen - 1)}\u2026`;
753
+ }
754
+ function escapeHtml(text) {
755
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
756
+ }
757
+
711
758
  // src/outbox.ts
759
+ var TELEGRAM_WIRE_LIMIT = 4096;
760
+ function fitHtmlWireText(escaped) {
761
+ if (escaped.length <= TELEGRAM_WIRE_LIMIT) return escaped;
762
+ const cut = escaped.slice(0, TELEGRAM_WIRE_LIMIT);
763
+ const lastAmp = cut.lastIndexOf("&");
764
+ const lastSemi = cut.lastIndexOf(";");
765
+ return lastAmp > lastSemi ? cut.slice(0, lastAmp) : cut;
766
+ }
712
767
  var TelegramOutbox = class {
713
768
  deps;
714
769
  constructor(deps) {
@@ -719,10 +774,12 @@ var TelegramOutbox = class {
719
774
  let lastErr;
720
775
  for (let attempt = 1; attempt <= 3; attempt++) {
721
776
  try {
777
+ const mode = this.deps.getParseMode?.();
778
+ const wireText = mode === "HTML" ? fitHtmlWireText(escapeHtml(text)) : text;
722
779
  const timeout = AbortSignal.timeout(1e4);
723
- const result = await this.deps.api().sendMessage(chatId, text, {
780
+ const result = await this.deps.api().sendMessage(chatId, wireText, {
724
781
  signal: signal ? AbortSignal.any([signal, timeout]) : timeout,
725
- parseMode: this.deps.getParseMode?.()
782
+ parseMode: mode
726
783
  });
727
784
  return { ok: true, result };
728
785
  } catch (err) {
@@ -753,10 +810,12 @@ var TelegramOutbox = class {
753
810
  let lastErr;
754
811
  for (let attempt = 1; attempt <= 3; attempt++) {
755
812
  try {
813
+ const mode = this.deps.getParseMode?.();
814
+ const wireText = mode === "HTML" ? fitHtmlWireText(escapeHtml(text)) : text;
756
815
  const timeout = AbortSignal.timeout(1e4);
757
- const result = await this.deps.api().sendMessageWithKeyboard(chatId, text, buttons, {
816
+ const result = await this.deps.api().sendMessageWithKeyboard(chatId, wireText, buttons, {
758
817
  signal: signal ? AbortSignal.any([signal, timeout]) : timeout,
759
- parseMode: this.deps.getParseMode?.()
818
+ parseMode: mode
760
819
  });
761
820
  return { ok: true, result };
762
821
  } catch (err) {
@@ -793,50 +852,6 @@ var TelegramOutbox = class {
793
852
  }
794
853
  };
795
854
 
796
- // src/text-format.ts
797
- var MAX_TELEGRAM_MESSAGE_LENGTH = 4096;
798
- function truncateForTelegram(text, maxLen = 4e3) {
799
- const effectiveMaxLen = Math.min(maxLen, MAX_TELEGRAM_MESSAGE_LENGTH);
800
- if (text.length <= effectiveMaxLen) return text;
801
- const cutoff = effectiveMaxLen - 30;
802
- if (cutoff <= 0) return `${text.slice(0, Math.max(0, effectiveMaxLen - 1))}\u2026`;
803
- const paraSearchEnd = effectiveMaxLen - 3;
804
- const paraIdx = text.lastIndexOf("\n\n", paraSearchEnd);
805
- if (paraIdx > cutoff) {
806
- return `${text.slice(0, paraIdx)}
807
-
808
- \u2026`;
809
- }
810
- const nlSearchEnd = effectiveMaxLen - 2;
811
- const nlIdx = text.lastIndexOf("\n", nlSearchEnd);
812
- if (nlIdx > cutoff) {
813
- return `${text.slice(0, nlIdx)}
814
- \u2026`;
815
- }
816
- const sentenceSearchEnd = effectiveMaxLen - 1;
817
- const sentenceRe = /[.!?](?=\s)/g;
818
- let match;
819
- let sentenceIdx = -1;
820
- match = sentenceRe.exec(text);
821
- while (match !== null) {
822
- if (match.index + 1 > sentenceSearchEnd) break;
823
- if (match.index + 1 > cutoff) sentenceIdx = match.index + 1;
824
- match = sentenceRe.exec(text);
825
- }
826
- if (sentenceIdx > cutoff) {
827
- return `${text.slice(0, sentenceIdx)}\u2026`;
828
- }
829
- const spaceSearchEnd = effectiveMaxLen - 2;
830
- const spaceIdx = text.lastIndexOf(" ", spaceSearchEnd);
831
- if (spaceIdx > cutoff) {
832
- return `${text.slice(0, spaceIdx)} \u2026`;
833
- }
834
- const hardSlice = text.slice(0, effectiveMaxLen - 20);
835
- const hardResult = `${hardSlice}\u2026[+${text.length - hardSlice.length} chars]`;
836
- if (hardResult.length <= effectiveMaxLen) return hardResult;
837
- return `${text.slice(0, effectiveMaxLen - 1)}\u2026`;
838
- }
839
-
840
855
  // src/bot.ts
841
856
  var TelegramBot = class {
842
857
  api;
@@ -1423,10 +1438,18 @@ var OffsetStore = class {
1423
1438
  const tmp = `${this.path}.${process.pid}.${randomUUID2().slice(0, 8)}.tmp`;
1424
1439
  const fd = openSync(tmp, "w");
1425
1440
  try {
1426
- writeSync(fd, JSON.stringify(offset));
1427
- fsyncSync(fd);
1428
- } finally {
1429
- closeSync(fd);
1441
+ try {
1442
+ writeSync(fd, JSON.stringify(offset));
1443
+ fsyncSync(fd);
1444
+ } finally {
1445
+ closeSync(fd);
1446
+ }
1447
+ } catch (err) {
1448
+ try {
1449
+ unlinkSync2(tmp);
1450
+ } catch {
1451
+ }
1452
+ throw err;
1430
1453
  }
1431
1454
  try {
1432
1455
  renameSync2(tmp, this.path);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrongstack/telegram",
3
- "version": "1.0.11",
3
+ "version": "1.0.12",
4
4
  "license": "MIT",
5
5
  "description": "WrongStack plugin — Telegram bridge: send messages, receive prompts, get notified.",
6
6
  "repository": {
@@ -26,11 +26,11 @@
26
26
  "!dist/**/*.map"
27
27
  ],
28
28
  "peerDependencies": {
29
- "@wrongstack/core": "1.0.11"
29
+ "@wrongstack/core": "1.0.12"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/node": "^26.5.1",
33
- "@wrongstack/core": "1.0.11",
33
+ "@wrongstack/core": "1.0.12",
34
34
  "typescript": "^7.0.2"
35
35
  },
36
36
  "publishConfig": {