beast-agent 2.5.1 → 2.6.0
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/package.json +1 -1
- package/src/main.js +167 -69
package/package.json
CHANGED
package/src/main.js
CHANGED
|
@@ -229,17 +229,20 @@ startHealthServer(); /* splash/boot aşamasından itibaren /health ayakta */
|
|
|
229
229
|
try { setSearchChain(settings.searchChain); } catch {}
|
|
230
230
|
try { setTinyfishKey(settings.tinyfishKey || null); } catch {}
|
|
231
231
|
let wa = null;
|
|
232
|
-
let waChats = new Map(); // jid -> aktif session id
|
|
232
|
+
let waChats = new Map(); // jid -> aktif session id (hepsi KANAL TEK OTURUMUNA bağlı)
|
|
233
|
+
let waSingleSid = null; // KANAL TEK OTURUMU: WhatsApp için BİR oturum — silinmedikçe hep aynı
|
|
233
234
|
let waHistory = new Map(); // jid -> [sid,...] bu sohbete ait tüm oturumlar
|
|
234
235
|
let waBcMode = new Set(); // jid -> BeastCode modu AKTİF (WhatsApp'tan uzaktan kodlama)
|
|
235
236
|
let waJidPn = new Map(); // jid -> gerçek telefon numarası (LID fallback için)
|
|
236
237
|
const WA_HISTORY_CAP = 20;
|
|
237
238
|
let tg = null;
|
|
238
|
-
let tgChats = new Map(); // telegram chatId -> aktif session id
|
|
239
|
+
let tgChats = new Map(); // telegram chatId -> aktif session id (hepsi KANAL TEK OTURUMUNA bağlı)
|
|
240
|
+
let tgSingleSid = null; // KANAL TEK OTURUMU: Telegram için BİR oturum
|
|
239
241
|
let tgHistory = new Map(); // chatId -> [sid,...]
|
|
240
242
|
const TG_HISTORY_CAP = 20;
|
|
241
243
|
let dc = null;
|
|
242
|
-
let dcChats = new Map(); // discord channelId -> aktif session id
|
|
244
|
+
let dcChats = new Map(); // discord channelId -> aktif session id (hepsi KANAL TEK OTURUMUNA bağlı)
|
|
245
|
+
let dcSingleSid = null; // KANAL TEK OTURUMU: Discord için BİR oturum
|
|
243
246
|
let dcHistory = new Map(); // channelId -> [sid,...]
|
|
244
247
|
const DC_HISTORY_CAP = 20;
|
|
245
248
|
const DC_CHATS_FILE = path.join(APP_DIR, 'dc-chats.json');
|
|
@@ -278,6 +281,8 @@ try {
|
|
|
278
281
|
if (!h.includes(s)) h.push(s);
|
|
279
282
|
waHistory.set(j, h.slice(-WA_HISTORY_CAP));
|
|
280
283
|
}
|
|
284
|
+
/* kanal tek oturumu: kayıtlı aktif id (geçersizse ensure yeniden seçer) */
|
|
285
|
+
if (typeof raw.active === 'string' && raw.active) waSingleSid = raw.active;
|
|
281
286
|
/* BeastCode modu: hangi sohbetler uzaktan kodlama yapıyor */
|
|
282
287
|
if (Array.isArray(raw.bcMode)) {
|
|
283
288
|
for (const j of raw.bcMode) if (typeof j === 'string') waBcMode.add(j);
|
|
@@ -293,6 +298,7 @@ function saveWaChats() {
|
|
|
293
298
|
chats: Object.fromEntries(waChats),
|
|
294
299
|
history: Object.fromEntries([...waHistory.entries()].map(([j, a]) => [j, a.slice(-WA_HISTORY_CAP)])),
|
|
295
300
|
bcMode: [...waBcMode],
|
|
301
|
+
active: waSingleSid || '',
|
|
296
302
|
})
|
|
297
303
|
);
|
|
298
304
|
} catch {}
|
|
@@ -1268,12 +1274,26 @@ async function tryWaSlash(jid, rawText, senderNum, payload0) {
|
|
|
1268
1274
|
if (cmd === 'help') {
|
|
1269
1275
|
out = waSlashHelp();
|
|
1270
1276
|
} else if (cmd === 'new') {
|
|
1277
|
+
/* /new: kanalın TEK oturumunu kapat, yenisini aç — aynı anda iki
|
|
1278
|
+
WhatsApp sohbet oturumu olmaz; eski oturum silinir */
|
|
1279
|
+
const oldSid = waSingleSid || waChats.get(jid) || '';
|
|
1280
|
+
if (oldSid) {
|
|
1281
|
+
let olds = null;
|
|
1282
|
+
try { olds = engine.cache.get(oldSid) || null; } catch {}
|
|
1283
|
+
if (!olds || !olds.bcCode) {
|
|
1284
|
+
/* Beast Code panel oturumuysa dokunma — yalnız pointer taşınır */
|
|
1285
|
+
try { engine.deleteSession(oldSid); } catch {}
|
|
1286
|
+
for (const [j, h] of waHistory.entries()) waHistory.set(j, h.filter((x) => x !== oldSid));
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1271
1289
|
const v = engine.createSession();
|
|
1290
|
+
waSingleSid = v.id;
|
|
1291
|
+
for (const j of [...waChats.keys()]) waChats.set(j, v.id);
|
|
1272
1292
|
waChats.set(jid, v.id);
|
|
1273
1293
|
waRememberSession(jid, v.id);
|
|
1274
1294
|
saveWaChats();
|
|
1275
1295
|
wa.setWatchJids([...waChats.keys()]);
|
|
1276
|
-
out = `*Yeni oturum* \`${v.code}\` açıldı —
|
|
1296
|
+
out = `*Yeni oturum* \`${v.code}\` açıldı — eski oturum kapatıldı, artık buradan devam.\nVar olan başka oturuma geçiş: \`/open <kod>\``;
|
|
1277
1297
|
} else if (cmd === 'open') {
|
|
1278
1298
|
if (!arg) {
|
|
1279
1299
|
out = 'Kullanım: `/open <kod>` — kodları görmek için /sessions';
|
|
@@ -1282,7 +1302,9 @@ async function tryWaSlash(jid, rawText, senderNum, payload0) {
|
|
|
1282
1302
|
if (!hit) {
|
|
1283
1303
|
out = `\`${arg.toUpperCase()}\` kodlu oturum bulunamadı. Listeyi görmek için /sessions`;
|
|
1284
1304
|
} else {
|
|
1285
|
-
|
|
1305
|
+
/* /open: kanal TEK oturumunu bu oturuma çevirir — tüm jid'ler bağlanır */
|
|
1306
|
+
waSingleSid = hit.id;
|
|
1307
|
+
for (const j of [...waChats.keys()]) waChats.set(j, hit.id);
|
|
1286
1308
|
waRememberSession(jid, hit.id);
|
|
1287
1309
|
saveWaChats();
|
|
1288
1310
|
wa.setWatchJids([...waChats.keys()]);
|
|
@@ -1564,14 +1586,15 @@ async function tryWaSlash(jid, rawText, senderNum, payload0) {
|
|
|
1564
1586
|
try { engine.interrupt(sid, 'kullanıcı /beastagent ile sohbet moduna döndü'); } catch {}
|
|
1565
1587
|
}
|
|
1566
1588
|
waBcMode.delete(jid);
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1589
|
+
/* KANAL TEK OTURUMU: yeni oturum AÇILMAZ — sohbet oturumuna dönülür
|
|
1590
|
+
(silinmediyse hep aynı; ilk kez ise burada oluşur) */
|
|
1591
|
+
const chatSid = ensureWaSession(jid);
|
|
1592
|
+
const chatS = engine.cache.get(chatSid);
|
|
1570
1593
|
saveWaChats();
|
|
1571
1594
|
if (wa) wa.setWatchJids([...waChats.keys()]);
|
|
1572
1595
|
emitWaEventSafe({ type: 'bc-screen', on: false });
|
|
1573
1596
|
out =
|
|
1574
|
-
`*💬 Sohbet moduna dönüldü* — masaüstünde chat ekranı açıldı,
|
|
1597
|
+
`*💬 Sohbet moduna dönüldü* — masaüstünde chat ekranı açıldı, sohbet oturumu \`${(chatS && chatS.code) || '?'}\`.\n` +
|
|
1575
1598
|
`Kodlar duruyor: \`${waBcWorkspace()}\`\n` +
|
|
1576
1599
|
`Tekrar kodlamak için: /beastcode`;
|
|
1577
1600
|
}
|
|
@@ -1682,19 +1705,58 @@ function waGroupSenderInfo(payload) {
|
|
|
1682
1705
|
return { label, name: (hitP && hitP.name) || '', isOwner: !!(hitP && hitP.owner) };
|
|
1683
1706
|
}
|
|
1684
1707
|
|
|
1685
|
-
/*
|
|
1708
|
+
/* ---------- KANAL TEK OTURUMU (WA/TG/DC) ----------
|
|
1709
|
+
Her kanalın BİR aktif sohbet oturumu vardır; eskisi silinmedikçe hep
|
|
1710
|
+
AYNI oturumdan devam edilir — Beast kendi kendine oturum kapatıp
|
|
1711
|
+
yenisiyle değiştirmez. Yenisi yalnızca: (1) kayıtlı oturum dosyası
|
|
1712
|
+
yoksa (kullanıcı UI'dan sildi), (2) kullanıcı WA'da /new yazarsa.
|
|
1713
|
+
Masaüstü chat UI'daki "+ Yeni Sohbet" bu kuralın dışındadır. */
|
|
1714
|
+
function sessionFileAlive(sid) {
|
|
1715
|
+
try {
|
|
1716
|
+
return !!sid && fs.existsSync(path.join(engine.sessionsDir, String(sid) + '.jsonl'));
|
|
1717
|
+
} catch {
|
|
1718
|
+
return false;
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
/* kanalın yaşayan tek oturumunu döndürür; geçersizse eski bağlamdan devralır,
|
|
1723
|
+
o da yoksa (ilk kullanım) yeni açar ve tüm jid'leri ona bağlar */
|
|
1686
1724
|
function ensureWaSession(jid) {
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1725
|
+
if (!waSingleSid || !sessionFileAlive(waSingleSid)) {
|
|
1726
|
+
let best = '';
|
|
1727
|
+
let bestTs = '';
|
|
1728
|
+
for (const c of new Set([...waChats.values(), waSingleSid])) {
|
|
1729
|
+
if (!c || !sessionFileAlive(c)) continue;
|
|
1730
|
+
let ts = '';
|
|
1731
|
+
try {
|
|
1732
|
+
const s = engine.cache.get(c) || engine._load(c);
|
|
1733
|
+
ts = String((s && s.updatedAt) || '');
|
|
1734
|
+
} catch {}
|
|
1735
|
+
if (!best || ts > bestTs) {
|
|
1736
|
+
best = c;
|
|
1737
|
+
bestTs = ts;
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
waSingleSid = best || engine.createSession().id;
|
|
1741
|
+
saveWaChats();
|
|
1742
|
+
}
|
|
1743
|
+
let dirty = false;
|
|
1744
|
+
for (const [j, s] of waChats.entries()) {
|
|
1745
|
+
if (s !== waSingleSid) {
|
|
1746
|
+
waChats.set(j, waSingleSid);
|
|
1747
|
+
dirty = true;
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1750
|
+
if (jid != null && waChats.get(String(jid)) !== waSingleSid) {
|
|
1751
|
+
waChats.set(String(jid), waSingleSid);
|
|
1752
|
+
dirty = true;
|
|
1753
|
+
}
|
|
1754
|
+
waRememberSession(String(jid), waSingleSid);
|
|
1755
|
+
if (dirty) {
|
|
1692
1756
|
saveWaChats();
|
|
1693
1757
|
if (wa) wa.setWatchJids([...waChats.keys()]);
|
|
1694
|
-
} else {
|
|
1695
|
-
waRememberSession(jid, sid);
|
|
1696
1758
|
}
|
|
1697
|
-
return
|
|
1759
|
+
return waSingleSid;
|
|
1698
1760
|
}
|
|
1699
1761
|
|
|
1700
1762
|
/* ---------- GRUP BAĞLAM AKIŞI (mentionOnly + seeAll) ----------
|
|
@@ -2232,7 +2294,7 @@ async function processWaMessage(jid, payload, senderNum, requeues = 0) {
|
|
|
2232
2294
|
waLog(`skip flush: izinli eşleşme yok (sender=+${senderNum || '?'})`);
|
|
2233
2295
|
return;
|
|
2234
2296
|
}
|
|
2235
|
-
let sid = waChats.get(jid);
|
|
2297
|
+
let sid = waChats.get(jid) || waSingleSid;
|
|
2236
2298
|
if (sid && engine.isBusy(sid)) {
|
|
2237
2299
|
/* oturum hâlâ önceki işle uğraşıyor — KAYBETME: sınırı kaldırdık,
|
|
2238
2300
|
iş bitene dek her debounce turunda yeniden deneriz; kullanıcıya
|
|
@@ -2246,16 +2308,8 @@ async function processWaMessage(jid, payload, senderNum, requeues = 0) {
|
|
|
2246
2308
|
if (!isGroup && requeues > 0) {
|
|
2247
2309
|
// retry sonrası izin yeniden kontrol edilir (yukarıda hit zaten alınıyor)
|
|
2248
2310
|
}
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
sid = v.id;
|
|
2252
|
-
waChats.set(jid, sid);
|
|
2253
|
-
waRememberSession(jid, sid);
|
|
2254
|
-
saveWaChats();
|
|
2255
|
-
if (wa) wa.setWatchJids([...waChats.keys()]);
|
|
2256
|
-
} else {
|
|
2257
|
-
waRememberSession(jid, sid);
|
|
2258
|
-
}
|
|
2311
|
+
/* KANAL TEK OTURUMU: eskisi silinmedikçe hep aynı oturumdan devam */
|
|
2312
|
+
sid = ensureWaSession(jid);
|
|
2259
2313
|
// Cevap verilecek — karşı telefonda "yazıyor…" göstergesi (medya işlenene dek sürer)
|
|
2260
2314
|
wa.setComposing(jid, true);
|
|
2261
2315
|
// Kişi bazlı granül izin: all/web/read/chat
|
|
@@ -2462,6 +2516,8 @@ function ensureWa() {
|
|
|
2462
2516
|
if (Array.isArray(arr)) tgHistory.set(c, arr.filter((x) => typeof x === 'string').slice(-TG_HISTORY_CAP));
|
|
2463
2517
|
}
|
|
2464
2518
|
}
|
|
2519
|
+
/* kanal tek oturumu: kayıtlı aktif id (geçersizse ensure yeniden seçer) */
|
|
2520
|
+
if (raw && typeof raw.active === 'string' && raw.active) tgSingleSid = raw.active;
|
|
2465
2521
|
for (const [c, s] of tgChats.entries()) {
|
|
2466
2522
|
const h = tgHistory.get(c) || [];
|
|
2467
2523
|
if (!h.includes(s)) h.push(s);
|
|
@@ -2477,6 +2533,7 @@ function saveTgChats() {
|
|
|
2477
2533
|
JSON.stringify({
|
|
2478
2534
|
chats: Object.fromEntries(tgChats),
|
|
2479
2535
|
history: Object.fromEntries([...tgHistory.entries()].map(([c, a]) => [c, a.slice(-TG_HISTORY_CAP)])),
|
|
2536
|
+
active: tgSingleSid || '',
|
|
2480
2537
|
})
|
|
2481
2538
|
);
|
|
2482
2539
|
} catch {}
|
|
@@ -2549,21 +2606,14 @@ async function processTgMessage(chatId, payload, requeues = 0) {
|
|
|
2549
2606
|
tgLog(`skip flush: izinli eşleşme yok (sender=${payload.senderId || '?'})`);
|
|
2550
2607
|
return;
|
|
2551
2608
|
}
|
|
2552
|
-
let sid = tgChats.get(chatId);
|
|
2609
|
+
let sid = tgChats.get(chatId) || tgSingleSid;
|
|
2553
2610
|
if (sid && engine.isBusy(sid)) {
|
|
2554
2611
|
/* oturum meşgul — WA ile aynı: kaybetme, iş bitene dek yeniden dene */
|
|
2555
2612
|
await new Promise((r) => setTimeout(r, TG_DEBOUNCE_MS));
|
|
2556
2613
|
return processTgMessage(chatId, payload, requeues + 1);
|
|
2557
2614
|
}
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
sid = v.id;
|
|
2561
|
-
tgChats.set(chatId, sid);
|
|
2562
|
-
tgRememberSession(chatId, sid);
|
|
2563
|
-
saveTgChats();
|
|
2564
|
-
} else {
|
|
2565
|
-
tgRememberSession(chatId, sid);
|
|
2566
|
-
}
|
|
2615
|
+
/* KANAL TEK OTURUMU: eskisi silinmedikçe hep aynı oturumdan devam */
|
|
2616
|
+
sid = ensureTgSession(chatId);
|
|
2567
2617
|
/* Kişi bazlı granül izin: all/web/read/chat */
|
|
2568
2618
|
let perm = hit.perm || (hit.lockdown ? 'chat' : 'all');
|
|
2569
2619
|
engine.setSessionPerm(sid, perm);
|
|
@@ -2686,6 +2736,8 @@ function dcFind(senderId, username) {
|
|
|
2686
2736
|
if (Array.isArray(arr)) dcHistory.set(c, arr.filter((x) => typeof x === 'string').slice(-DC_HISTORY_CAP));
|
|
2687
2737
|
}
|
|
2688
2738
|
}
|
|
2739
|
+
/* kanal tek oturumu: kayıtlı aktif id (geçersizse ensure yeniden seçer) */
|
|
2740
|
+
if (raw && typeof raw.active === 'string' && raw.active) dcSingleSid = raw.active;
|
|
2689
2741
|
for (const [c, s] of dcChats.entries()) {
|
|
2690
2742
|
const h = dcHistory.get(c) || [];
|
|
2691
2743
|
if (!h.includes(s)) h.push(s);
|
|
@@ -2701,6 +2753,7 @@ function saveDcChats() {
|
|
|
2701
2753
|
JSON.stringify({
|
|
2702
2754
|
chats: Object.fromEntries(dcChats),
|
|
2703
2755
|
history: Object.fromEntries([...dcHistory.entries()].map(([c, a]) => [c, a.slice(-DC_HISTORY_CAP)])),
|
|
2756
|
+
active: dcSingleSid || '',
|
|
2704
2757
|
})
|
|
2705
2758
|
);
|
|
2706
2759
|
} catch {}
|
|
@@ -2767,21 +2820,14 @@ async function processDcMessage(channelId, payload) {
|
|
|
2767
2820
|
dcLog(`skip flush: izinli eşleşme yok (sender=${payload.senderId || '?'})`);
|
|
2768
2821
|
return;
|
|
2769
2822
|
}
|
|
2770
|
-
let sid = dcChats.get(channelId);
|
|
2823
|
+
let sid = dcChats.get(channelId) || dcSingleSid;
|
|
2771
2824
|
if (sid && engine.isBusy(sid)) {
|
|
2772
2825
|
/* oturum meşgul — WA/TG ile aynı: kaybetme, iş bitene dek yeniden dene */
|
|
2773
2826
|
await new Promise((r) => setTimeout(r, DC_DEBOUNCE_MS));
|
|
2774
2827
|
return processDcMessage(channelId, payload, 1);
|
|
2775
2828
|
}
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
sid = v.id;
|
|
2779
|
-
dcChats.set(channelId, sid);
|
|
2780
|
-
dcRememberSession(channelId, sid);
|
|
2781
|
-
saveDcChats();
|
|
2782
|
-
} else {
|
|
2783
|
-
dcRememberSession(channelId, sid);
|
|
2784
|
-
}
|
|
2829
|
+
/* KANAL TEK OTURUMU: eskisi silinmedikçe hep aynı oturumdan devam */
|
|
2830
|
+
sid = ensureDcSession(channelId);
|
|
2785
2831
|
/* Kişi bazlı granül izin: all/web/read/chat */
|
|
2786
2832
|
let perm = hit.perm || (hit.lockdown ? 'chat' : 'all');
|
|
2787
2833
|
engine.setSessionPerm(sid, perm);
|
|
@@ -6330,13 +6376,19 @@ function empatiLlmCompose(prompt) {
|
|
|
6330
6376
|
const PROACTIVE_MARK = '🫡 *Beast proaktif:*';
|
|
6331
6377
|
|
|
6332
6378
|
/* bildirimin ALTINA YAZILAN KAYNAK: haberin gerçek linki varsa o, yoksa kaynak adı.
|
|
6333
|
-
Kullanıcı "bu proje neymiş?" diye sorduğunda linkten bulabilsin.
|
|
6379
|
+
Kullanıcı "bu proje neymiş?" diye sorduğunda linkten bulabilsin.
|
|
6380
|
+
TEK SATIR kuralı: satır sonu/boşluklar temizlenir, uzunsa sona "..." gelir. */
|
|
6334
6381
|
function empatiSourceLine(ev) {
|
|
6335
6382
|
if (!ev) return '';
|
|
6336
|
-
const
|
|
6337
|
-
|
|
6338
|
-
const
|
|
6339
|
-
|
|
6383
|
+
const oneLine = (s) =>
|
|
6384
|
+
String(s || '').replace(/\s*\n+\s*/g, ' ').replace(/\s{2,}/g, ' ').trim();
|
|
6385
|
+
const ELLIPSIS = '...';
|
|
6386
|
+
const cap = (s, max) =>
|
|
6387
|
+
oneLine(s).length > max ? oneLine(s).slice(0, max - ELLIPSIS.length) + ELLIPSIS : oneLine(s);
|
|
6388
|
+
const url = oneLine(ev.url);
|
|
6389
|
+
if (/^https?:\/\//i.test(url)) return '🔗 ' + cap(url, 100);
|
|
6390
|
+
const src = oneLine(ev.source);
|
|
6391
|
+
return src ? '🔗 kaynak: ' + cap(src, 80) : '';
|
|
6340
6392
|
}
|
|
6341
6393
|
|
|
6342
6394
|
function empatiInjectToSession(sid, out) {
|
|
@@ -6360,28 +6412,74 @@ function empatiInjectText(ev, out) {
|
|
|
6360
6412
|
);
|
|
6361
6413
|
}
|
|
6362
6414
|
|
|
6363
|
-
/*
|
|
6415
|
+
/* kanalın yaşayan tek oturumu (WA kuralının aynısı — Telegram/Discord) */
|
|
6364
6416
|
function ensureTgSession(chatId) {
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6417
|
+
if (!tgSingleSid || !sessionFileAlive(tgSingleSid)) {
|
|
6418
|
+
let best = '';
|
|
6419
|
+
let bestTs = '';
|
|
6420
|
+
for (const c of new Set([...tgChats.values(), tgSingleSid])) {
|
|
6421
|
+
if (!c || !sessionFileAlive(c)) continue;
|
|
6422
|
+
let ts = '';
|
|
6423
|
+
try {
|
|
6424
|
+
const s = engine.cache.get(c) || engine._load(c);
|
|
6425
|
+
ts = String((s && s.updatedAt) || '');
|
|
6426
|
+
} catch {}
|
|
6427
|
+
if (!best || ts > bestTs) {
|
|
6428
|
+
best = c;
|
|
6429
|
+
bestTs = ts;
|
|
6430
|
+
}
|
|
6431
|
+
}
|
|
6432
|
+
tgSingleSid = best || engine.createSession().id;
|
|
6371
6433
|
saveTgChats();
|
|
6372
6434
|
}
|
|
6373
|
-
|
|
6435
|
+
let dirty = false;
|
|
6436
|
+
for (const [c, s] of tgChats.entries()) {
|
|
6437
|
+
if (s !== tgSingleSid) {
|
|
6438
|
+
tgChats.set(c, tgSingleSid);
|
|
6439
|
+
dirty = true;
|
|
6440
|
+
}
|
|
6441
|
+
}
|
|
6442
|
+
if (chatId != null && tgChats.get(String(chatId)) !== tgSingleSid) {
|
|
6443
|
+
tgChats.set(String(chatId), tgSingleSid);
|
|
6444
|
+
dirty = true;
|
|
6445
|
+
}
|
|
6446
|
+
tgRememberSession(String(chatId), tgSingleSid);
|
|
6447
|
+
if (dirty) saveTgChats();
|
|
6448
|
+
return tgSingleSid;
|
|
6374
6449
|
}
|
|
6375
6450
|
function ensureDcSession(channelId) {
|
|
6376
|
-
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6451
|
+
if (!dcSingleSid || !sessionFileAlive(dcSingleSid)) {
|
|
6452
|
+
let best = '';
|
|
6453
|
+
let bestTs = '';
|
|
6454
|
+
for (const c of new Set([...dcChats.values(), dcSingleSid])) {
|
|
6455
|
+
if (!c || !sessionFileAlive(c)) continue;
|
|
6456
|
+
let ts = '';
|
|
6457
|
+
try {
|
|
6458
|
+
const s = engine.cache.get(c) || engine._load(c);
|
|
6459
|
+
ts = String((s && s.updatedAt) || '');
|
|
6460
|
+
} catch {}
|
|
6461
|
+
if (!best || ts > bestTs) {
|
|
6462
|
+
best = c;
|
|
6463
|
+
bestTs = ts;
|
|
6464
|
+
}
|
|
6465
|
+
}
|
|
6466
|
+
dcSingleSid = best || engine.createSession().id;
|
|
6382
6467
|
saveDcChats();
|
|
6383
6468
|
}
|
|
6384
|
-
|
|
6469
|
+
let dirty = false;
|
|
6470
|
+
for (const [c, s] of dcChats.entries()) {
|
|
6471
|
+
if (s !== dcSingleSid) {
|
|
6472
|
+
dcChats.set(c, dcSingleSid);
|
|
6473
|
+
dirty = true;
|
|
6474
|
+
}
|
|
6475
|
+
}
|
|
6476
|
+
if (channelId != null && dcChats.get(String(channelId)) !== dcSingleSid) {
|
|
6477
|
+
dcChats.set(String(channelId), dcSingleSid);
|
|
6478
|
+
dirty = true;
|
|
6479
|
+
}
|
|
6480
|
+
dcRememberSession(String(channelId), dcSingleSid);
|
|
6481
|
+
if (dirty) saveDcChats();
|
|
6482
|
+
return dcSingleSid;
|
|
6385
6483
|
}
|
|
6386
6484
|
|
|
6387
6485
|
/* Masaüstü yedeği: en güncel (bg/bot-DM'siz, meşgul olmayan) sohbet — yoksa yeni */
|