dsh-tg-bridge 1.2.7 → 1.2.8
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/bridge.mjs +33 -2
- package/package.json +1 -1
package/bridge.mjs
CHANGED
|
@@ -607,6 +607,7 @@ export function toTelegramHtml(input) {
|
|
|
607
607
|
async function send(chatId, text, threadId = 0, replyTo = 0) {
|
|
608
608
|
const html = config.plainText === true ? '' : toTelegramHtml(text);
|
|
609
609
|
const parts = html ? chunk(html, 3800) : chunk(toPlainText(text) || '(пусто)');
|
|
610
|
+
let lastId = 0;
|
|
610
611
|
for (const part of parts) {
|
|
611
612
|
const body = { chat_id: chatId, text: part, disable_web_page_preview: true };
|
|
612
613
|
if (html) body.parse_mode = 'HTML';
|
|
@@ -627,7 +628,9 @@ async function send(chatId, text, threadId = 0, replyTo = 0) {
|
|
|
627
628
|
res = await tg('sendMessage', body);
|
|
628
629
|
}
|
|
629
630
|
log(`sent chat=${chatId}${threadId ? ` topic=${threadId}` : ''} msg=${res.message_id} len=${part.length}${html ? ' html' : ''}`);
|
|
631
|
+
lastId = res.message_id;
|
|
630
632
|
}
|
|
633
|
+
return lastId;
|
|
631
634
|
}
|
|
632
635
|
|
|
633
636
|
/** Remember which topics already got their seed message, so it happens once. */
|
|
@@ -1398,12 +1401,33 @@ function maybeExitForRestart() {
|
|
|
1398
1401
|
setTimeout(() => process.exit(75), 300).unref?.();
|
|
1399
1402
|
}
|
|
1400
1403
|
|
|
1404
|
+
/**
|
|
1405
|
+
* Queue notices, one per topic. A notice exists only while the person is
|
|
1406
|
+
* waiting: the moment the queued turn starts it is deleted, so a long session
|
|
1407
|
+
* does not leave a column of "идёт уже 7 мин" messages behind (it did).
|
|
1408
|
+
*/
|
|
1409
|
+
const busyNotices = new Map();
|
|
1410
|
+
|
|
1411
|
+
async function clearBusyNotice(key) {
|
|
1412
|
+
const notice = busyNotices.get(key);
|
|
1413
|
+
if (!notice) return;
|
|
1414
|
+
busyNotices.delete(key);
|
|
1415
|
+
try {
|
|
1416
|
+
await tg('deleteMessage', { chat_id: notice.chatId, message_id: notice.messageId });
|
|
1417
|
+
} catch (error) {
|
|
1418
|
+
log(`busy notice delete failed: ${error.message}`);
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1401
1422
|
function enqueue(key, task, onBusy) {
|
|
1402
1423
|
const prev = queues.get(key) || Promise.resolve();
|
|
1403
1424
|
const queued = queues.has(key);
|
|
1404
1425
|
const run = prev
|
|
1405
1426
|
.then(() => acquire())
|
|
1406
|
-
.then(() => {
|
|
1427
|
+
.then(async () => {
|
|
1428
|
+
// The person was told "your message is queued"; that notice has done its
|
|
1429
|
+
// job the moment the turn starts and must not linger in the chat.
|
|
1430
|
+
await clearBusyNotice(key);
|
|
1407
1431
|
// Remember when the turn actually started: the queue notice has to say
|
|
1408
1432
|
// "идёт уже 24 мин", not just "занято" — silence is what reads as a hang.
|
|
1409
1433
|
turnStartedAt.set(key, Date.now());
|
|
@@ -1412,6 +1436,7 @@ function enqueue(key, task, onBusy) {
|
|
|
1412
1436
|
.catch((error) => log(`turn queue error ${key}: ${error.message}`))
|
|
1413
1437
|
.finally(() => {
|
|
1414
1438
|
turnStartedAt.delete(key);
|
|
1439
|
+
clearBusyNotice(key).catch(() => {});
|
|
1415
1440
|
release();
|
|
1416
1441
|
if (queues.get(key) === run) queues.delete(key);
|
|
1417
1442
|
// A deferred restart waits for exactly this moment: the answer is out and
|
|
@@ -1728,16 +1753,22 @@ async function main() {
|
|
|
1728
1753
|
? async () => {
|
|
1729
1754
|
await new Promise((resolve) => setTimeout(resolve, Number(config.busyNoticeMs ?? 45000)));
|
|
1730
1755
|
if (!queues.has(queueKey)) return; // already finished
|
|
1756
|
+
// One notice per topic: a second queued message must not add a
|
|
1757
|
+
// second copy of the same line.
|
|
1758
|
+
if (busyNotices.has(queueKey)) return;
|
|
1731
1759
|
const started = turnStartedAt.get(queueKey);
|
|
1732
1760
|
const mins = started ? Math.max(1, Math.round((Date.now() - started) / 60000)) : 0;
|
|
1733
1761
|
const notice = mins > 0
|
|
1734
1762
|
? t(lang, 'msg.busy.since', { min: mins })
|
|
1735
1763
|
: t(lang, 'msg.busy.now');
|
|
1736
|
-
await send(
|
|
1764
|
+
const messageId = await send(
|
|
1737
1765
|
msg.chat.id,
|
|
1738
1766
|
`⏳ ${notice}`,
|
|
1739
1767
|
thread,
|
|
1740
1768
|
);
|
|
1769
|
+
if (messageId) busyNotices.set(queueKey, { chatId: msg.chat.id, messageId });
|
|
1770
|
+
// The turn may have started while the notice was in flight.
|
|
1771
|
+
if (!queues.has(queueKey)) await clearBusyNotice(queueKey);
|
|
1741
1772
|
}
|
|
1742
1773
|
: undefined,
|
|
1743
1774
|
);
|
package/package.json
CHANGED