@imessaging/telegram-mtproto 0.6.6 → 0.7.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 +2 -2
- package/src/incoming.ts +5 -2
- package/src/telegram-mtproto-transport.ts +15 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@imessaging/telegram-mtproto",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Telegram MTProto user-account transport for imessaging",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"messaging",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"test": "bun test"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@imessaging/core": "0.
|
|
34
|
+
"@imessaging/core": "0.7.0",
|
|
35
35
|
"big-integer": "^1.6.52"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
package/src/incoming.ts
CHANGED
|
@@ -31,7 +31,9 @@ export type MtprotoMessageLike = {
|
|
|
31
31
|
* Без него ответить по одному номеру нельзя: клиент знает только тех, кого уже разрешал, а
|
|
32
32
|
* `accessHash` из обновления больше нигде не хранится.
|
|
33
33
|
*/
|
|
34
|
-
getInputSender?: () => Promise<
|
|
34
|
+
getInputSender?: () => Promise<
|
|
35
|
+
{ userId?: { toString(): string }; accessHash?: { toString(): string } } | undefined
|
|
36
|
+
>;
|
|
35
37
|
/** Отправитель целиком. Обращение к сущностям обновления, а не поход в сеть. */
|
|
36
38
|
getSender?: () => Promise<{ username?: string } | undefined>;
|
|
37
39
|
};
|
|
@@ -64,7 +66,8 @@ export function peerToChat(peer: MtprotoPeerLike | undefined): {
|
|
|
64
66
|
} {
|
|
65
67
|
if (peer?.channelId !== undefined)
|
|
66
68
|
return { chatId: `-100${peer.channelId.toString()}`, chatType: "channel" };
|
|
67
|
-
if (peer?.chatId !== undefined)
|
|
69
|
+
if (peer?.chatId !== undefined)
|
|
70
|
+
return { chatId: `-${peer.chatId.toString()}`, chatType: "group" };
|
|
68
71
|
if (peer?.userId !== undefined) return { chatId: peer.userId.toString(), chatType: "user" };
|
|
69
72
|
throw new Error("MTProto peer without userId, chatId or channelId");
|
|
70
73
|
}
|
|
@@ -243,8 +243,15 @@ export class TelegramMtprotoTransport
|
|
|
243
243
|
* Повторы неизбежны и это нормально: потребитель обязан отсеивать по идентификатору сообщения,
|
|
244
244
|
* а не полагаться на то, что канал не повторится. Он и так повторяется в обычной жизни.
|
|
245
245
|
*/
|
|
246
|
-
async catchUp(
|
|
246
|
+
async catchUp(
|
|
247
|
+
options: { limit?: number; dialogs?: number; sinceMs?: number } = {},
|
|
248
|
+
): Promise<number> {
|
|
247
249
|
const limit = options.limit ?? 20;
|
|
250
|
+
// ГРАНИЦА ПО ВРЕМЕНИ ОБЯЗАТЕЛЬНА ПО СМЫСЛУ: без неё первый же опрос поднимает всю доступную
|
|
251
|
+
// историю каждого диалога и отдаёт её потребителю как новьё. Замер 07.09.2026 — сотни старых
|
|
252
|
+
// сообщений уехали продукту, который их давно разобрал. Догрузка чинит пропажу последних
|
|
253
|
+
// минут, а не восстанавливает архив.
|
|
254
|
+
const since = options.sinceMs ?? Date.now() - 6 * 60 * 60 * 1000;
|
|
248
255
|
const dialogs = await this.client.getDialogs({ limit: options.dialogs ?? 200 });
|
|
249
256
|
let dispatched = 0;
|
|
250
257
|
for (const dialog of dialogs) {
|
|
@@ -254,6 +261,8 @@ export class TelegramMtprotoTransport
|
|
|
254
261
|
const messages = await this.client.getMessages(entity, { limit }).catch(() => []);
|
|
255
262
|
// От старых к новым: порядок обработки должен совпадать с тем, в каком они пришли бы живьём.
|
|
256
263
|
for (const message of [...messages].reverse()) {
|
|
264
|
+
const at = (message as { date?: number }).date;
|
|
265
|
+
if (typeof at === "number" && at * 1000 < since) continue;
|
|
257
266
|
const delivered = await this.incoming.dispatch(
|
|
258
267
|
message as unknown as MtprotoMessageLike,
|
|
259
268
|
this.id,
|
|
@@ -395,7 +404,7 @@ export class TelegramMtprotoTransport
|
|
|
395
404
|
* «мы этому человеку ещё не писали и он нам тоже», а не поломку.
|
|
396
405
|
*/
|
|
397
406
|
private async knownInputPeer(recipient: MessageRecipient): Promise<Api.TypeInputPeer | null> {
|
|
398
|
-
if (recipient
|
|
407
|
+
if (!isTelegramRecipient(recipient) || recipient.type === "username") return null;
|
|
399
408
|
// Обычной группе ни клиент, ни хранилище не нужны: `InputPeerChat` строится из одного номера.
|
|
400
409
|
if (recipient.type === "group") {
|
|
401
410
|
return new Api.InputPeerChat({ chatId: bigInt(unmarkPeerId(recipient.id)) });
|
|
@@ -411,7 +420,10 @@ export class TelegramMtprotoTransport
|
|
|
411
420
|
// Почтовый получатель сюда доходить не должен: разрешать адрес как @username бессмысленно, а
|
|
412
421
|
// сообщение об отказе тогда врало бы про Telegram.
|
|
413
422
|
if (!isTelegramRecipient(recipient)) {
|
|
414
|
-
|
|
423
|
+
if (recipient.type === "email") {
|
|
424
|
+
throw new Error("Telegram MTProto cannot send email");
|
|
425
|
+
}
|
|
426
|
+
throw new Error(`Telegram MTProto cannot address ${recipient.type}`);
|
|
415
427
|
}
|
|
416
428
|
if (recipient.type !== "username" && !recipient.username) {
|
|
417
429
|
throw new Error(
|