@imessaging/telegram-mtproto 0.8.0 → 0.8.2
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 +2 -0
- package/src/telegram-mtproto-transport.ts +64 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@imessaging/telegram-mtproto",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
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.8.
|
|
34
|
+
"@imessaging/core": "^0.8.2",
|
|
35
35
|
"big-integer": "^1.6.52"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
package/src/incoming.ts
CHANGED
|
@@ -18,6 +18,7 @@ export type MtprotoMessageLike = {
|
|
|
18
18
|
date?: number | null;
|
|
19
19
|
editDate?: number | null;
|
|
20
20
|
groupedId?: { toString(): string } | null;
|
|
21
|
+
mentioned?: boolean | null;
|
|
21
22
|
peerId?: MtprotoPeerLike;
|
|
22
23
|
fromId?: MtprotoPeerLike;
|
|
23
24
|
media?: MtprotoMediaLike;
|
|
@@ -298,6 +299,7 @@ export function toIncomingMessage(
|
|
|
298
299
|
editedAt: message.editDate ? new Date(message.editDate * 1000) : undefined,
|
|
299
300
|
attachments: collectAttachments(message, chatId),
|
|
300
301
|
links: collectLinks(message),
|
|
302
|
+
mentionsMe: typeof message.mentioned === "boolean" ? message.mentioned : undefined,
|
|
301
303
|
replyToMessageId,
|
|
302
304
|
threadId,
|
|
303
305
|
forwardedFrom: toForwardedFrom(message.fwdFrom),
|
|
@@ -8,8 +8,10 @@ import type {
|
|
|
8
8
|
EditableMessage,
|
|
9
9
|
EditableMessageTransport,
|
|
10
10
|
EditResult,
|
|
11
|
+
MessageReaction,
|
|
11
12
|
MessageRecipient,
|
|
12
13
|
OutboundMessage,
|
|
14
|
+
ReactionTransport,
|
|
13
15
|
ResolvedPeer,
|
|
14
16
|
SendResult,
|
|
15
17
|
TelegramPeerStore,
|
|
@@ -43,6 +45,7 @@ export type TelegramChatSummary = {
|
|
|
43
45
|
title: string;
|
|
44
46
|
username?: string;
|
|
45
47
|
unreadCount: number;
|
|
48
|
+
unreadMentions: number;
|
|
46
49
|
};
|
|
47
50
|
|
|
48
51
|
export type TelegramMtprotoTransportOptions = {
|
|
@@ -88,6 +91,7 @@ export class TelegramMtprotoTransport
|
|
|
88
91
|
EditableMessageTransport,
|
|
89
92
|
ButtonPressTransport,
|
|
90
93
|
IncomingMessageTransport,
|
|
94
|
+
ReactionTransport,
|
|
91
95
|
ReadReceiptTransport,
|
|
92
96
|
TypingTransport
|
|
93
97
|
{
|
|
@@ -325,6 +329,29 @@ export class TelegramMtprotoTransport
|
|
|
325
329
|
);
|
|
326
330
|
}
|
|
327
331
|
|
|
332
|
+
async react(reaction: MessageReaction): Promise<void> {
|
|
333
|
+
this.assertConnected();
|
|
334
|
+
if (!isTelegramRecipient(reaction.recipient)) {
|
|
335
|
+
if (reaction.recipient.type === "email") {
|
|
336
|
+
throw new Error("Telegram MTProto cannot react to an email");
|
|
337
|
+
}
|
|
338
|
+
throw new Error(`Telegram MTProto cannot react to ${reaction.recipient.type}`);
|
|
339
|
+
}
|
|
340
|
+
const messageId = Number(reaction.messageId);
|
|
341
|
+
if (!Number.isSafeInteger(messageId) || messageId <= 0) {
|
|
342
|
+
throw new Error(`Telegram message id must be a positive integer: ${reaction.messageId}`);
|
|
343
|
+
}
|
|
344
|
+
const peer = await this.getInputPeer(reaction.recipient);
|
|
345
|
+
await this.client.invoke(
|
|
346
|
+
new Api.messages.SendReaction({
|
|
347
|
+
peer,
|
|
348
|
+
msgId: messageId,
|
|
349
|
+
reaction: reaction.emoji ? [new Api.ReactionEmoji({ emoticon: reaction.emoji })] : [],
|
|
350
|
+
}),
|
|
351
|
+
);
|
|
352
|
+
this.lastActivityAt = new Date();
|
|
353
|
+
}
|
|
354
|
+
|
|
328
355
|
async disconnect(): Promise<void> {
|
|
329
356
|
await this.client.disconnect();
|
|
330
357
|
this.connected = false;
|
|
@@ -408,7 +435,14 @@ export class TelegramMtprotoTransport
|
|
|
408
435
|
);
|
|
409
436
|
}
|
|
410
437
|
|
|
411
|
-
summaries.push({
|
|
438
|
+
summaries.push({
|
|
439
|
+
chatId,
|
|
440
|
+
chatType,
|
|
441
|
+
title,
|
|
442
|
+
username,
|
|
443
|
+
unreadCount: dialog.unreadCount,
|
|
444
|
+
unreadMentions: dialog.unreadMentionsCount ?? 0,
|
|
445
|
+
});
|
|
412
446
|
if (summaries.length >= limit) break;
|
|
413
447
|
}
|
|
414
448
|
return summaries;
|
|
@@ -417,16 +451,21 @@ export class TelegramMtprotoTransport
|
|
|
417
451
|
/**
|
|
418
452
|
* Последние `limit` сообщений чата, от старых к новым, ВКЛЮЧАЯ свои — это чтение истории, а не приём.
|
|
419
453
|
* Служебные события (вход в группу, закреп) пропускаются: текста и вложений у них нет.
|
|
454
|
+
*
|
|
455
|
+
* @param options.mentionsOnly Только упоминания аккаунта. Фильтр работает на уровне всего чата;
|
|
456
|
+
* вызывающий код должен сам отфильтровать результат по `threadId`.
|
|
420
457
|
*/
|
|
421
458
|
async history(
|
|
422
459
|
recipient: TelegramRecipient,
|
|
423
|
-
options?: { limit?: number; threadId?: number },
|
|
460
|
+
options?: { limit?: number; threadId?: number; mentionsOnly?: boolean },
|
|
424
461
|
): Promise<IncomingMessage[]> {
|
|
425
462
|
this.assertConnected();
|
|
426
463
|
const peer = await this.getInputPeer(recipient);
|
|
464
|
+
// gramjs игнорирует filter, если передан replyTo, поэтому для mentionsOnly replyTo не передаём
|
|
427
465
|
const messages = await this.client.getMessages(peer, {
|
|
428
466
|
limit: options?.limit ?? 30,
|
|
429
|
-
replyTo: options?.threadId,
|
|
467
|
+
replyTo: options?.mentionsOnly ? undefined : options?.threadId,
|
|
468
|
+
filter: options?.mentionsOnly ? new Api.InputMessagesFilterMyMentions() : undefined,
|
|
430
469
|
});
|
|
431
470
|
return [...messages]
|
|
432
471
|
.reverse()
|
|
@@ -440,6 +479,28 @@ export class TelegramMtprotoTransport
|
|
|
440
479
|
);
|
|
441
480
|
}
|
|
442
481
|
|
|
482
|
+
/**
|
|
483
|
+
* Запросить конкретные сообщения по их номерам.
|
|
484
|
+
* Контекст для упоминаний, то есть сообщение, на которое кто-то ответил.
|
|
485
|
+
* Если запросить пустой список, вернёт `[]` без сетевых вызовов (но после проверки соединения).
|
|
486
|
+
*/
|
|
487
|
+
async messagesByIds(recipient: TelegramRecipient, ids: number[]): Promise<IncomingMessage[]> {
|
|
488
|
+
this.assertConnected();
|
|
489
|
+
if (ids.length === 0) return [];
|
|
490
|
+
const peer = await this.getInputPeer(recipient);
|
|
491
|
+
const messages = await this.client.getMessages(peer, { ids });
|
|
492
|
+
return messages
|
|
493
|
+
.filter((message) => message && message.className === "Message")
|
|
494
|
+
.map((message) =>
|
|
495
|
+
toIncomingMessage(
|
|
496
|
+
message as unknown as MtprotoMessageLike,
|
|
497
|
+
this.id,
|
|
498
|
+
this.options.accountId,
|
|
499
|
+
),
|
|
500
|
+
)
|
|
501
|
+
.sort((a, b) => Number(a.messageId) - Number(b.messageId));
|
|
502
|
+
}
|
|
503
|
+
|
|
443
504
|
private async sendWithRetry(message: OutboundMessage, retried: boolean): Promise<SendResult> {
|
|
444
505
|
try {
|
|
445
506
|
const peer = await this.getInputPeer(message.recipient);
|