@mtcute/core 0.29.6 → 0.30.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/client.cjs +8 -0
- package/client.js +8 -0
- package/highlevel/client.d.cts +23 -7
- package/highlevel/client.d.ts +23 -7
- package/highlevel/methods/bots/answer-bot-guest-chat-query.cjs +26 -0
- package/highlevel/methods/bots/answer-bot-guest-chat-query.d.cts +12 -0
- package/highlevel/methods/bots/answer-bot-guest-chat-query.d.ts +12 -0
- package/highlevel/methods/bots/answer-bot-guest-chat-query.js +21 -0
- package/highlevel/methods/chats/join-chat.cjs +38 -16
- package/highlevel/methods/chats/join-chat.d.cts +20 -6
- package/highlevel/methods/chats/join-chat.d.ts +20 -6
- package/highlevel/methods/chats/join-chat.js +38 -16
- package/highlevel/methods/chats/save-draft.d.cts +4 -1
- package/highlevel/methods/chats/save-draft.d.ts +4 -1
- package/highlevel/methods/messages/send-copy-group.cjs +5 -9
- package/highlevel/methods/messages/send-copy-group.js +5 -9
- package/highlevel/methods.d.cts +3 -0
- package/highlevel/methods.d.ts +3 -0
- package/highlevel/storage/service/peers.cjs +2 -0
- package/highlevel/storage/service/peers.js +2 -0
- package/highlevel/types/files/utils.d.cts +1 -1
- package/highlevel/types/files/utils.d.ts +1 -1
- package/highlevel/types/media/poll.cjs +14 -0
- package/highlevel/types/media/poll.d.cts +6 -0
- package/highlevel/types/media/poll.d.ts +6 -0
- package/highlevel/types/media/poll.js +14 -0
- package/highlevel/types/messages/index.d.cts +1 -0
- package/highlevel/types/messages/index.d.ts +1 -0
- package/highlevel/types/messages/message.cjs +15 -1
- package/highlevel/types/messages/message.d.cts +8 -0
- package/highlevel/types/messages/message.d.ts +8 -0
- package/highlevel/types/messages/message.js +15 -1
- package/highlevel/types/messages/rich-message.cjs +50 -0
- package/highlevel/types/messages/rich-message.d.cts +18 -0
- package/highlevel/types/messages/rich-message.d.ts +18 -0
- package/highlevel/types/messages/rich-message.js +45 -0
- package/highlevel/types/peers/chat-permissions.cjs +6 -0
- package/highlevel/types/peers/chat-permissions.d.cts +4 -0
- package/highlevel/types/peers/chat-permissions.d.ts +4 -0
- package/highlevel/types/peers/chat-permissions.js +6 -0
- package/highlevel/types/peers/full-chat.cjs +6 -0
- package/highlevel/types/peers/full-chat.d.cts +2 -0
- package/highlevel/types/peers/full-chat.d.ts +2 -0
- package/highlevel/types/peers/full-chat.js +6 -0
- package/highlevel/types/peers/user.cjs +8 -0
- package/highlevel/types/peers/user.d.cts +4 -0
- package/highlevel/types/peers/user.d.ts +4 -0
- package/highlevel/types/peers/user.js +8 -0
- package/highlevel/types/updates/bot-guest-chat-query.cjs +39 -0
- package/highlevel/types/updates/bot-guest-chat-query.d.cts +21 -0
- package/highlevel/types/updates/bot-guest-chat-query.d.ts +21 -0
- package/highlevel/types/updates/bot-guest-chat-query.js +34 -0
- package/highlevel/types/updates/index.d.cts +5 -1
- package/highlevel/types/updates/index.d.ts +5 -1
- package/highlevel/types/updates/parse-update.cjs +3 -0
- package/highlevel/types/updates/parse-update.js +3 -0
- package/highlevel/types/updates/user-typing-update.cjs +2 -0
- package/highlevel/types/updates/user-typing-update.js +2 -0
- package/highlevel/updates/manager.cjs +214 -3
- package/highlevel/updates/manager.d.cts +1 -0
- package/highlevel/updates/manager.d.ts +1 -0
- package/highlevel/updates/manager.js +214 -3
- package/highlevel/utils/inspectable.cjs +1 -0
- package/highlevel/utils/inspectable.d.cts +1 -0
- package/highlevel/utils/inspectable.d.ts +1 -0
- package/highlevel/utils/inspectable.js +1 -0
- package/index.cjs +4 -0
- package/index.js +4 -0
- package/methods.cjs +2 -0
- package/methods.js +2 -0
- package/network/flood-control.cjs +149 -0
- package/network/flood-control.d.cts +79 -0
- package/network/flood-control.d.ts +79 -0
- package/network/flood-control.js +144 -0
- package/network/flood-control.test.d.cts +1 -0
- package/network/flood-control.test.d.ts +1 -0
- package/network/mtproto-session.cjs +1 -21
- package/network/mtproto-session.d.cts +1 -5
- package/network/mtproto-session.d.ts +1 -5
- package/network/mtproto-session.js +2 -22
- package/network/multi-session-connection.cjs +26 -16
- package/network/multi-session-connection.d.cts +1 -1
- package/network/multi-session-connection.d.ts +1 -1
- package/network/multi-session-connection.js +26 -16
- package/network/multi-session-connection.test.d.cts +1 -0
- package/network/multi-session-connection.test.d.ts +1 -0
- package/network/network-manager.cjs +3 -2
- package/network/network-manager.d.cts +12 -0
- package/network/network-manager.d.ts +12 -0
- package/network/network-manager.js +3 -2
- package/network/persistent-connection.cjs +25 -1
- package/network/persistent-connection.d.cts +5 -0
- package/network/persistent-connection.d.ts +5 -0
- package/network/persistent-connection.js +25 -1
- package/network/session-connection.cjs +5 -10
- package/network/session-connection.d.cts +0 -2
- package/network/session-connection.d.ts +0 -2
- package/network/session-connection.js +5 -10
- package/package.json +1 -1
- package/tl/api-schema.json +1 -1
- package/tl/binary/reader.cjs +257 -62
- package/tl/binary/reader.js +257 -62
- package/tl/binary/writer.cjs +837 -212
- package/tl/binary/writer.js +837 -212
- package/tl/compat/reader.cjs +31 -0
- package/tl/compat/reader.js +31 -0
- package/tl/index.d.cts +2478 -186
- package/tl/index.d.ts +2478 -186
- package/tl/inner-tl.cjs +34 -10
- package/tl/inner-tl.js +34 -10
- package/utils/binary/compat.cjs +84 -0
- package/utils/binary/compat.js +84 -0
- package/utils/index.d.cts +1 -0
- package/utils/index.d.ts +1 -0
- package/utils/long-utils.cjs +10 -0
- package/utils/long-utils.js +10 -0
- package/utils.cjs +7 -0
- package/utils.js +8 -1
|
@@ -14,6 +14,178 @@ import { RpcError } from "../../tl/inner-tl.js";
|
|
|
14
14
|
const WARN_EVERY = 100;
|
|
15
15
|
const KEEP_ALIVE_INTERVAL = 15 * 60 * 1e3;
|
|
16
16
|
const UPDATES_TOO_LONG = { _: "updatesTooLong" };
|
|
17
|
+
function collectRichTextPeerIds(text, peers) {
|
|
18
|
+
if (!text) return;
|
|
19
|
+
switch (text._) {
|
|
20
|
+
case "textEmpty":
|
|
21
|
+
case "textPlain":
|
|
22
|
+
case "textEmail":
|
|
23
|
+
case "textPhone":
|
|
24
|
+
case "textImage":
|
|
25
|
+
case "textMath":
|
|
26
|
+
case "textCustomEmoji":
|
|
27
|
+
break;
|
|
28
|
+
case "textBold":
|
|
29
|
+
case "textItalic":
|
|
30
|
+
case "textUnderline":
|
|
31
|
+
case "textStrike":
|
|
32
|
+
case "textFixed":
|
|
33
|
+
case "textUrl":
|
|
34
|
+
case "textSubscript":
|
|
35
|
+
case "textSuperscript":
|
|
36
|
+
case "textMarked":
|
|
37
|
+
case "textAnchor":
|
|
38
|
+
case "textSpoiler":
|
|
39
|
+
case "textMention":
|
|
40
|
+
case "textHashtag":
|
|
41
|
+
case "textBotCommand":
|
|
42
|
+
case "textCashtag":
|
|
43
|
+
case "textAutoUrl":
|
|
44
|
+
case "textAutoEmail":
|
|
45
|
+
case "textAutoPhone":
|
|
46
|
+
case "textBankCard":
|
|
47
|
+
case "textDate":
|
|
48
|
+
collectRichTextPeerIds(text.text, peers);
|
|
49
|
+
break;
|
|
50
|
+
case "textConcat":
|
|
51
|
+
for (const child of text.texts) collectRichTextPeerIds(child, peers);
|
|
52
|
+
break;
|
|
53
|
+
case "textMentionName":
|
|
54
|
+
peers.add(text.userId);
|
|
55
|
+
collectRichTextPeerIds(text.text, peers);
|
|
56
|
+
break;
|
|
57
|
+
default:
|
|
58
|
+
assertNever();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function collectPageCaptionPeerIds(caption, peers) {
|
|
62
|
+
if (!caption) return;
|
|
63
|
+
collectRichTextPeerIds(caption.text, peers);
|
|
64
|
+
collectRichTextPeerIds(caption.credit, peers);
|
|
65
|
+
}
|
|
66
|
+
function collectPageBlockPeerIds(block, peers) {
|
|
67
|
+
if (!block) return;
|
|
68
|
+
switch (block._) {
|
|
69
|
+
case "pageBlockUnsupported":
|
|
70
|
+
case "pageBlockDivider":
|
|
71
|
+
case "pageBlockAnchor":
|
|
72
|
+
case "pageBlockMath":
|
|
73
|
+
break;
|
|
74
|
+
case "pageBlockTitle":
|
|
75
|
+
case "pageBlockSubtitle":
|
|
76
|
+
case "pageBlockHeader":
|
|
77
|
+
case "pageBlockSubheader":
|
|
78
|
+
case "pageBlockParagraph":
|
|
79
|
+
case "pageBlockPreformatted":
|
|
80
|
+
case "pageBlockFooter":
|
|
81
|
+
case "pageBlockKicker":
|
|
82
|
+
case "pageBlockThinking":
|
|
83
|
+
case "pageBlockHeading1":
|
|
84
|
+
case "pageBlockHeading2":
|
|
85
|
+
case "pageBlockHeading3":
|
|
86
|
+
case "pageBlockHeading4":
|
|
87
|
+
case "pageBlockHeading5":
|
|
88
|
+
case "pageBlockHeading6":
|
|
89
|
+
collectRichTextPeerIds(block.text, peers);
|
|
90
|
+
break;
|
|
91
|
+
case "pageBlockAuthorDate":
|
|
92
|
+
collectRichTextPeerIds(block.author, peers);
|
|
93
|
+
break;
|
|
94
|
+
case "pageBlockList":
|
|
95
|
+
for (const item of block.items) collectPageListItemPeerIds(item, peers);
|
|
96
|
+
break;
|
|
97
|
+
case "pageBlockOrderedList":
|
|
98
|
+
for (const item of block.items) collectPageListOrderedItemPeerIds(item, peers);
|
|
99
|
+
break;
|
|
100
|
+
case "pageBlockBlockquote":
|
|
101
|
+
case "pageBlockPullquote":
|
|
102
|
+
collectRichTextPeerIds(block.text, peers);
|
|
103
|
+
collectRichTextPeerIds(block.caption, peers);
|
|
104
|
+
break;
|
|
105
|
+
case "pageBlockPhoto":
|
|
106
|
+
case "pageBlockVideo":
|
|
107
|
+
case "pageBlockEmbed":
|
|
108
|
+
case "pageBlockAudio":
|
|
109
|
+
case "pageBlockMap":
|
|
110
|
+
case "inputPageBlockMap":
|
|
111
|
+
collectPageCaptionPeerIds(block.caption, peers);
|
|
112
|
+
break;
|
|
113
|
+
case "pageBlockCover":
|
|
114
|
+
collectPageBlockPeerIds(block.cover, peers);
|
|
115
|
+
break;
|
|
116
|
+
case "pageBlockEmbedPost":
|
|
117
|
+
for (const child of block.blocks) collectPageBlockPeerIds(child, peers);
|
|
118
|
+
collectPageCaptionPeerIds(block.caption, peers);
|
|
119
|
+
break;
|
|
120
|
+
case "pageBlockCollage":
|
|
121
|
+
case "pageBlockSlideshow":
|
|
122
|
+
for (const child of block.items) collectPageBlockPeerIds(child, peers);
|
|
123
|
+
collectPageCaptionPeerIds(block.caption, peers);
|
|
124
|
+
break;
|
|
125
|
+
case "pageBlockChannel":
|
|
126
|
+
switch (block.channel._) {
|
|
127
|
+
case "chatEmpty":
|
|
128
|
+
case "chat":
|
|
129
|
+
case "chatForbidden":
|
|
130
|
+
peers.add(getMarkedPeerId(block.channel.id, "chat"));
|
|
131
|
+
break;
|
|
132
|
+
case "channel":
|
|
133
|
+
case "channelForbidden":
|
|
134
|
+
peers.add(getMarkedPeerId(block.channel.id, "channel"));
|
|
135
|
+
break;
|
|
136
|
+
default:
|
|
137
|
+
assertNever(block.channel);
|
|
138
|
+
}
|
|
139
|
+
break;
|
|
140
|
+
case "pageBlockTable":
|
|
141
|
+
collectRichTextPeerIds(block.title, peers);
|
|
142
|
+
for (const row of block.rows) {
|
|
143
|
+
for (const cell of row.cells) collectRichTextPeerIds(cell.text, peers);
|
|
144
|
+
}
|
|
145
|
+
break;
|
|
146
|
+
case "pageBlockDetails":
|
|
147
|
+
for (const child of block.blocks) collectPageBlockPeerIds(child, peers);
|
|
148
|
+
collectRichTextPeerIds(block.title, peers);
|
|
149
|
+
break;
|
|
150
|
+
case "pageBlockRelatedArticles":
|
|
151
|
+
collectRichTextPeerIds(block.title, peers);
|
|
152
|
+
break;
|
|
153
|
+
case "pageBlockBlockquoteBlocks":
|
|
154
|
+
for (const child of block.blocks) collectPageBlockPeerIds(child, peers);
|
|
155
|
+
collectRichTextPeerIds(block.caption, peers);
|
|
156
|
+
break;
|
|
157
|
+
default:
|
|
158
|
+
assertNever();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function collectPageListItemPeerIds(item, peers) {
|
|
162
|
+
switch (item._) {
|
|
163
|
+
case "pageListItemText":
|
|
164
|
+
collectRichTextPeerIds(item.text, peers);
|
|
165
|
+
break;
|
|
166
|
+
case "pageListItemBlocks":
|
|
167
|
+
for (const block of item.blocks) collectPageBlockPeerIds(block, peers);
|
|
168
|
+
break;
|
|
169
|
+
default:
|
|
170
|
+
assertNever();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function collectPageListOrderedItemPeerIds(item, peers) {
|
|
174
|
+
switch (item._) {
|
|
175
|
+
case "pageListOrderedItemText":
|
|
176
|
+
collectRichTextPeerIds(item.text, peers);
|
|
177
|
+
break;
|
|
178
|
+
case "pageListOrderedItemBlocks":
|
|
179
|
+
for (const block of item.blocks) collectPageBlockPeerIds(block, peers);
|
|
180
|
+
break;
|
|
181
|
+
default:
|
|
182
|
+
assertNever();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function collectRichMessagePeerIds(richMessage, peers) {
|
|
186
|
+
if (!richMessage) return;
|
|
187
|
+
for (const block of richMessage.blocks) collectPageBlockPeerIds(block, peers);
|
|
188
|
+
}
|
|
17
189
|
class UpdatesManager {
|
|
18
190
|
constructor(client, params = {}) {
|
|
19
191
|
this.client = client;
|
|
@@ -86,6 +258,9 @@ class UpdatesManager {
|
|
|
86
258
|
cptsMod = /* @__PURE__ */ new Map();
|
|
87
259
|
channelDiffTimeouts = /* @__PURE__ */ new Map();
|
|
88
260
|
channelsOpened = /* @__PURE__ */ new Map();
|
|
261
|
+
// channels we got CHANNEL_PRIVATE for when fetching diff — skip gap handling.
|
|
262
|
+
// invalidated when an updateChannel for that channel arrives
|
|
263
|
+
inaccessibleChannels = /* @__PURE__ */ new Set();
|
|
89
264
|
log;
|
|
90
265
|
_onCatchingUp = () => {
|
|
91
266
|
};
|
|
@@ -107,6 +282,7 @@ class UpdatesManager {
|
|
|
107
282
|
this.stopLoop();
|
|
108
283
|
this.cpts.clear();
|
|
109
284
|
this.cptsMod.clear();
|
|
285
|
+
this.inaccessibleChannels.clear();
|
|
110
286
|
this.pts = this.qts = this.date = this.seq = void 0;
|
|
111
287
|
}
|
|
112
288
|
async prepare() {
|
|
@@ -482,6 +658,7 @@ class UpdatesManager {
|
|
|
482
658
|
return missing;
|
|
483
659
|
}
|
|
484
660
|
if (!await fetchPeer(msg.viaBotId)) return missing;
|
|
661
|
+
if (!await fetchPeer(msg.guestchatViaFrom)) return missing;
|
|
485
662
|
if (msg.entities) {
|
|
486
663
|
for (const ent of msg.entities) {
|
|
487
664
|
if (ent._ === "messageEntityMentionName") {
|
|
@@ -489,6 +666,13 @@ class UpdatesManager {
|
|
|
489
666
|
}
|
|
490
667
|
}
|
|
491
668
|
}
|
|
669
|
+
if (msg.richMessage) {
|
|
670
|
+
const richMessagePeers = /* @__PURE__ */ new Set();
|
|
671
|
+
collectRichMessagePeerIds(msg.richMessage, richMessagePeers);
|
|
672
|
+
for (const peer of richMessagePeers) {
|
|
673
|
+
if (!await fetchPeer(peer)) return missing;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
492
676
|
if (msg.media) {
|
|
493
677
|
switch (msg.media._) {
|
|
494
678
|
case "messageMediaContact":
|
|
@@ -538,6 +722,13 @@ class UpdatesManager {
|
|
|
538
722
|
}
|
|
539
723
|
}
|
|
540
724
|
}
|
|
725
|
+
if ("richMessage" in upd.draft && upd.draft.richMessage) {
|
|
726
|
+
const richMessagePeers = /* @__PURE__ */ new Set();
|
|
727
|
+
collectRichMessagePeerIds(upd.draft.richMessage, richMessagePeers);
|
|
728
|
+
for (const peer of richMessagePeers) {
|
|
729
|
+
if (!await fetchPeer(peer)) return missing;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
541
732
|
}
|
|
542
733
|
return missing;
|
|
543
734
|
}
|
|
@@ -560,7 +751,13 @@ class UpdatesManager {
|
|
|
560
751
|
store(msg.fromId);
|
|
561
752
|
if (msg._ === "message") {
|
|
562
753
|
store(msg.viaBotId);
|
|
754
|
+
store(msg.guestchatViaFrom);
|
|
563
755
|
store(msg.fwdFrom?.fromId);
|
|
756
|
+
if (msg.richMessage) {
|
|
757
|
+
const richMessagePeers = /* @__PURE__ */ new Set();
|
|
758
|
+
collectRichMessagePeerIds(msg.richMessage, richMessagePeers);
|
|
759
|
+
store([...richMessagePeers]);
|
|
760
|
+
}
|
|
564
761
|
if (msg.media) {
|
|
565
762
|
switch (msg.media._) {
|
|
566
763
|
case "messageMediaWebPage":
|
|
@@ -725,14 +922,20 @@ class UpdatesManager {
|
|
|
725
922
|
channelId,
|
|
726
923
|
this._fetchChannelDifference(channelId, fallbackPts).catch((err) => {
|
|
727
924
|
this.log.warn("error fetching difference for %d: %e", channelId, err);
|
|
728
|
-
if (RpcError.is("PERSISTENT_TIMESTAMP_INVALID")) {
|
|
925
|
+
if (RpcError.is(err, "PERSISTENT_TIMESTAMP_INVALID")) {
|
|
729
926
|
this.log.warn("received PERSISTENT_TIMESTAMP_INVALID, resetting channel pts value");
|
|
730
927
|
this.cpts.delete(channelId);
|
|
731
928
|
this.cptsMod.delete(channelId);
|
|
732
929
|
}
|
|
930
|
+
if (RpcError.is(err, "CHANNEL_PRIVATE") || RpcError.is(err, "CHANNEL_INVALID")) {
|
|
931
|
+
this.log.debug("channel %d is inaccessible, skipping gap fills until updateChannel", channelId);
|
|
932
|
+
this.inaccessibleChannels.add(channelId);
|
|
933
|
+
this.cpts.delete(channelId);
|
|
934
|
+
this.cptsMod.delete(channelId);
|
|
935
|
+
}
|
|
733
936
|
}).then((ok) => {
|
|
734
937
|
requestedDiff.delete(channelId);
|
|
735
|
-
if (!ok) {
|
|
938
|
+
if (!ok && !this.inaccessibleChannels.has(channelId)) {
|
|
736
939
|
this.log.debug("channel difference for %d failed, falling back to common diff", channelId);
|
|
737
940
|
this._fetchDifferenceLater(requestedDiff);
|
|
738
941
|
}
|
|
@@ -933,6 +1136,13 @@ class UpdatesManager {
|
|
|
933
1136
|
}
|
|
934
1137
|
break;
|
|
935
1138
|
}
|
|
1139
|
+
case "updateChannel": {
|
|
1140
|
+
const channel = pending.peers.chat(upd.channelId);
|
|
1141
|
+
if (channel._ !== "channelForbidden") {
|
|
1142
|
+
this.inaccessibleChannels.delete(upd.channelId);
|
|
1143
|
+
}
|
|
1144
|
+
break;
|
|
1145
|
+
}
|
|
936
1146
|
case "updateConfig":
|
|
937
1147
|
client.mt.network.config.update(true).catch((err) => client.onError.emit(unknownToError(err)));
|
|
938
1148
|
break;
|
|
@@ -1250,7 +1460,8 @@ class UpdatesManager {
|
|
|
1250
1460
|
);
|
|
1251
1461
|
continue;
|
|
1252
1462
|
}
|
|
1253
|
-
|
|
1463
|
+
const isInaccessibleChannel = pending.channelId && this.inaccessibleChannels.has(pending.channelId);
|
|
1464
|
+
if (diff < 0 && !isInaccessibleChannel) {
|
|
1254
1465
|
if (diff > -3) {
|
|
1255
1466
|
log.debug(
|
|
1256
1467
|
"postponing %s for 0.5s (cid = %d) because small gap detected (by pts: exp %d, got %d, diff=%d)",
|
package/index.cjs
CHANGED
|
@@ -56,6 +56,7 @@ const messageReactions = require("./highlevel/types/messages/message-reactions.c
|
|
|
56
56
|
const messageReplies = require("./highlevel/types/messages/message-replies.cjs");
|
|
57
57
|
const message = require("./highlevel/types/messages/message.cjs");
|
|
58
58
|
const repliedMessage = require("./highlevel/types/messages/replied-message.cjs");
|
|
59
|
+
const richMessage = require("./highlevel/types/messages/rich-message.cjs");
|
|
59
60
|
const searchFilters = require("./highlevel/types/messages/search-filters.cjs");
|
|
60
61
|
const suggestedPost = require("./highlevel/types/messages/suggested-post.cjs");
|
|
61
62
|
const collectibleInfo = require("./highlevel/types/misc/collectible-info.cjs");
|
|
@@ -118,6 +119,7 @@ const storyInteractions = require("./highlevel/types/stories/story-interactions.
|
|
|
118
119
|
const storyViewer = require("./highlevel/types/stories/story-viewer.cjs");
|
|
119
120
|
const story$1 = require("./highlevel/types/stories/story.cjs");
|
|
120
121
|
const botChatJoinRequest = require("./highlevel/types/updates/bot-chat-join-request.cjs");
|
|
122
|
+
const botGuestChatQuery = require("./highlevel/types/updates/bot-guest-chat-query.cjs");
|
|
121
123
|
const botReaction = require("./highlevel/types/updates/bot-reaction.cjs");
|
|
122
124
|
const botStopped = require("./highlevel/types/updates/bot-stopped.cjs");
|
|
123
125
|
const callbackQuery = require("./highlevel/types/updates/callback-query.cjs");
|
|
@@ -224,6 +226,7 @@ exports.MessageReactions = messageReactions.MessageReactions;
|
|
|
224
226
|
exports.MessageRepliesInfo = messageReplies.MessageRepliesInfo;
|
|
225
227
|
exports.Message = message.Message;
|
|
226
228
|
exports.RepliedMessageInfo = repliedMessage.RepliedMessageInfo;
|
|
229
|
+
exports.RichMessage = richMessage.RichMessage;
|
|
227
230
|
exports.SearchFilters = searchFilters.SearchFilters;
|
|
228
231
|
exports.SuggestedPostInfo = suggestedPost.SuggestedPostInfo;
|
|
229
232
|
exports.CollectibleInfo = collectibleInfo.CollectibleInfo;
|
|
@@ -297,6 +300,7 @@ exports.StoryViewer = storyViewer.StoryViewer;
|
|
|
297
300
|
exports.StoryViewersList = storyViewer.StoryViewersList;
|
|
298
301
|
exports.Story = story$1.Story;
|
|
299
302
|
exports.BotChatJoinRequestUpdate = botChatJoinRequest.BotChatJoinRequestUpdate;
|
|
303
|
+
exports.BotGuestChatQuery = botGuestChatQuery.BotGuestChatQuery;
|
|
300
304
|
exports.BotReactionCountUpdate = botReaction.BotReactionCountUpdate;
|
|
301
305
|
exports.BotReactionUpdate = botReaction.BotReactionUpdate;
|
|
302
306
|
exports.BotStoppedUpdate = botStopped.BotStoppedUpdate;
|
package/index.js
CHANGED
|
@@ -49,6 +49,7 @@ import { MessageReactions } from "./highlevel/types/messages/message-reactions.j
|
|
|
49
49
|
import { MessageRepliesInfo } from "./highlevel/types/messages/message-replies.js";
|
|
50
50
|
import { Message } from "./highlevel/types/messages/message.js";
|
|
51
51
|
import { RepliedMessageInfo } from "./highlevel/types/messages/replied-message.js";
|
|
52
|
+
import { RichMessage } from "./highlevel/types/messages/rich-message.js";
|
|
52
53
|
import { SearchFilters } from "./highlevel/types/messages/search-filters.js";
|
|
53
54
|
import { SuggestedPostInfo } from "./highlevel/types/messages/suggested-post.js";
|
|
54
55
|
import { CollectibleInfo } from "./highlevel/types/misc/collectible-info.js";
|
|
@@ -111,6 +112,7 @@ import { StoryInteractions } from "./highlevel/types/stories/story-interactions.
|
|
|
111
112
|
import { StoryRepost, StoryViewer, StoryViewersList } from "./highlevel/types/stories/story-viewer.js";
|
|
112
113
|
import { Story } from "./highlevel/types/stories/story.js";
|
|
113
114
|
import { BotChatJoinRequestUpdate } from "./highlevel/types/updates/bot-chat-join-request.js";
|
|
115
|
+
import { BotGuestChatQuery } from "./highlevel/types/updates/bot-guest-chat-query.js";
|
|
114
116
|
import { BotReactionCountUpdate, BotReactionUpdate } from "./highlevel/types/updates/bot-reaction.js";
|
|
115
117
|
import { BotStoppedUpdate } from "./highlevel/types/updates/bot-stopped.js";
|
|
116
118
|
import { BusinessCallbackQuery, CallbackQuery, InlineCallbackQuery } from "./highlevel/types/updates/callback-query.js";
|
|
@@ -163,6 +165,7 @@ export {
|
|
|
163
165
|
BoostStats,
|
|
164
166
|
BotChatJoinRequestUpdate,
|
|
165
167
|
inner as BotCommands,
|
|
168
|
+
BotGuestChatQuery,
|
|
166
169
|
BotInfo,
|
|
167
170
|
factories$1 as BotInline,
|
|
168
171
|
factories as BotInlineMessage,
|
|
@@ -269,6 +272,7 @@ export {
|
|
|
269
272
|
RawUpdateInfo,
|
|
270
273
|
ReactionCount,
|
|
271
274
|
RepliedMessageInfo,
|
|
275
|
+
RichMessage,
|
|
272
276
|
SavedStarGift,
|
|
273
277
|
SearchFilters,
|
|
274
278
|
SentCode,
|
package/methods.cjs
CHANGED
|
@@ -18,6 +18,7 @@ const signIn = require("./highlevel/methods/auth/sign-in.cjs");
|
|
|
18
18
|
const startTest = require("./highlevel/methods/auth/start-test.cjs");
|
|
19
19
|
const start = require("./highlevel/methods/auth/start.cjs");
|
|
20
20
|
const utils = require("./highlevel/methods/auth/utils.cjs");
|
|
21
|
+
const answerBotGuestChatQuery = require("./highlevel/methods/bots/answer-bot-guest-chat-query.cjs");
|
|
21
22
|
const answerCallbackQuery = require("./highlevel/methods/bots/answer-callback-query.cjs");
|
|
22
23
|
const answerInlineQuery = require("./highlevel/methods/bots/answer-inline-query.cjs");
|
|
23
24
|
const answerPreCheckoutQuery = require("./highlevel/methods/bots/answer-pre-checkout-query.cjs");
|
|
@@ -299,6 +300,7 @@ exports.signIn = signIn.signIn;
|
|
|
299
300
|
exports.startTest = startTest.startTest;
|
|
300
301
|
exports.start = start.start;
|
|
301
302
|
exports.isSelfPeer = utils.isSelfPeer;
|
|
303
|
+
exports.answerBotGuestChatQuery = answerBotGuestChatQuery.answerBotGuestChatQuery;
|
|
302
304
|
exports.answerCallbackQuery = answerCallbackQuery.answerCallbackQuery;
|
|
303
305
|
exports.answerInlineQuery = answerInlineQuery.answerInlineQuery;
|
|
304
306
|
exports.answerPreCheckoutQuery = answerPreCheckoutQuery.answerPreCheckoutQuery;
|
package/methods.js
CHANGED
|
@@ -11,6 +11,7 @@ import { signIn } from "./highlevel/methods/auth/sign-in.js";
|
|
|
11
11
|
import { startTest } from "./highlevel/methods/auth/start-test.js";
|
|
12
12
|
import { start } from "./highlevel/methods/auth/start.js";
|
|
13
13
|
import { isSelfPeer } from "./highlevel/methods/auth/utils.js";
|
|
14
|
+
import { answerBotGuestChatQuery } from "./highlevel/methods/bots/answer-bot-guest-chat-query.js";
|
|
14
15
|
import { answerCallbackQuery } from "./highlevel/methods/bots/answer-callback-query.js";
|
|
15
16
|
import { answerInlineQuery } from "./highlevel/methods/bots/answer-inline-query.js";
|
|
16
17
|
import { answerPreCheckoutQuery } from "./highlevel/methods/bots/answer-pre-checkout-query.js";
|
|
@@ -289,6 +290,7 @@ export {
|
|
|
289
290
|
addChatMembers,
|
|
290
291
|
addContact,
|
|
291
292
|
addStickerToSet,
|
|
293
|
+
answerBotGuestChatQuery,
|
|
292
294
|
answerCallbackQuery,
|
|
293
295
|
answerInlineQuery,
|
|
294
296
|
answerMedia,
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WARNED) {
|
|
2
|
+
globalThis._MTCUTE_CJS_DEPRECATION_WARNED = true;
|
|
3
|
+
console.warn("[@mtcute/core] CommonJS bundles are deprecated. They will be removed completely in one of the upcoming releases. No support is provided for CommonJS users. Please consider switching to ESM, it's " + (/* @__PURE__ */ new Date()).getFullYear() + " already.");
|
|
4
|
+
console.warn("[@mtcute/core] Learn more about switching to ESM: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c");
|
|
5
|
+
}
|
|
6
|
+
"use strict";
|
|
7
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
8
|
+
const utils = require("@fuman/utils");
|
|
9
|
+
class FloodControl {
|
|
10
|
+
_rules;
|
|
11
|
+
_maxWindow;
|
|
12
|
+
_events = [];
|
|
13
|
+
constructor(rules) {
|
|
14
|
+
if (rules.length === 0) throw new Error("FloodControl needs at least one rule");
|
|
15
|
+
this._rules = rules;
|
|
16
|
+
this._maxWindow = rules.reduce((m, r) => Math.max(m, r.windowMs), 0);
|
|
17
|
+
}
|
|
18
|
+
/** Earliest absolute perf-now ms at which a new event is permitted. */
|
|
19
|
+
getWakeupAt(now) {
|
|
20
|
+
let wakeup = 0;
|
|
21
|
+
for (const { count, windowMs } of this._rules) {
|
|
22
|
+
const cutoff = now - windowMs;
|
|
23
|
+
let inWindow = 0;
|
|
24
|
+
let oldestInWindowIdx = -1;
|
|
25
|
+
for (let i = this._events.length - 1; i >= 0; i--) {
|
|
26
|
+
if (this._events[i] <= cutoff) break;
|
|
27
|
+
inWindow++;
|
|
28
|
+
oldestInWindowIdx = i;
|
|
29
|
+
}
|
|
30
|
+
if (inWindow >= count) {
|
|
31
|
+
const t = this._events[oldestInWindowIdx] + windowMs;
|
|
32
|
+
if (t > wakeup) wakeup = t;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return wakeup;
|
|
36
|
+
}
|
|
37
|
+
addEvent(now) {
|
|
38
|
+
this._events.push(now);
|
|
39
|
+
this._prune(now);
|
|
40
|
+
}
|
|
41
|
+
_prune(now) {
|
|
42
|
+
const cutoff = now - this._maxWindow;
|
|
43
|
+
let i = 0;
|
|
44
|
+
while (i < this._events.length && this._events[i] < cutoff) i++;
|
|
45
|
+
if (i > 0) this._events.splice(0, i);
|
|
46
|
+
}
|
|
47
|
+
reset() {
|
|
48
|
+
this._events = [];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const DEFAULT_SANITY_LIMITS = [
|
|
52
|
+
{ count: 5, windowMs: 1e4 }
|
|
53
|
+
];
|
|
54
|
+
const DEFAULT_FLOOD_LIMITS = [
|
|
55
|
+
{ count: 1, windowMs: 1e3 },
|
|
56
|
+
{ count: 4, windowMs: 2e3 },
|
|
57
|
+
{ count: 8, windowMs: 3e3 }
|
|
58
|
+
];
|
|
59
|
+
const DEFAULT_MTPROTO_ERROR_LIMITS = [
|
|
60
|
+
{ count: 1, windowMs: 1e3 },
|
|
61
|
+
{ count: 4, windowMs: 2e3 },
|
|
62
|
+
{ count: 8, windowMs: 3e3 }
|
|
63
|
+
];
|
|
64
|
+
class ConnectionFloodController {
|
|
65
|
+
sanity;
|
|
66
|
+
flood;
|
|
67
|
+
mtprotoError;
|
|
68
|
+
_log;
|
|
69
|
+
constructor(limits = {}) {
|
|
70
|
+
this.sanity = new FloodControl(limits.sanity ?? DEFAULT_SANITY_LIMITS);
|
|
71
|
+
this.flood = new FloodControl(limits.flood ?? DEFAULT_FLOOD_LIMITS);
|
|
72
|
+
this.mtprotoError = new FloodControl(limits.mtprotoError ?? DEFAULT_MTPROTO_ERROR_LIMITS);
|
|
73
|
+
}
|
|
74
|
+
setLogger(log) {
|
|
75
|
+
this._log = log;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Notify a network-up transition.
|
|
79
|
+
*
|
|
80
|
+
* TDLib clears sanity + online-regime flood + backoff on
|
|
81
|
+
* `ConnectionCreator::on_network(true)`. We don't model the online regime,
|
|
82
|
+
* and our transport layer owns its own reconnect backoff, so only the
|
|
83
|
+
* sanity limiter is reset here.
|
|
84
|
+
*/
|
|
85
|
+
notifyNetworkUp() {
|
|
86
|
+
this._log?.debug("network up, resetting sanity limiter");
|
|
87
|
+
this.sanity.reset();
|
|
88
|
+
}
|
|
89
|
+
/** Record an MTProto-level error (transport 429; per TDLib, other codes don't tick this). */
|
|
90
|
+
addMtprotoError(now = performance.now()) {
|
|
91
|
+
this._log?.debug("recording mtproto error");
|
|
92
|
+
this.mtprotoError.addEvent(now);
|
|
93
|
+
}
|
|
94
|
+
/** Earliest perf-now ms at which a new connection attempt is permitted. */
|
|
95
|
+
getWakeupAt(now) {
|
|
96
|
+
return Math.max(
|
|
97
|
+
this.sanity.getWakeupAt(now),
|
|
98
|
+
this.flood.getWakeupAt(now),
|
|
99
|
+
this.mtprotoError.getWakeupAt(now)
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Block until a connection attempt is permitted under all applicable
|
|
104
|
+
* limiters, then record the attempt. Concurrent waiters serialize fairly
|
|
105
|
+
* because the first to wake records its event before the next checks state.
|
|
106
|
+
*
|
|
107
|
+
* If `signal` aborts, the pending timer is cleared and the promise rejects
|
|
108
|
+
* with the signal's reason.
|
|
109
|
+
*/
|
|
110
|
+
async wait(signal) {
|
|
111
|
+
let waited = false;
|
|
112
|
+
while (true) {
|
|
113
|
+
signal?.throwIfAborted();
|
|
114
|
+
const now = performance.now();
|
|
115
|
+
const wakeup = this.getWakeupAt(now);
|
|
116
|
+
if (wakeup <= now) {
|
|
117
|
+
this.sanity.addEvent(now);
|
|
118
|
+
this.flood.addEvent(now);
|
|
119
|
+
if (waited) this._log?.debug("admitted connect after waiting");
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const delay = wakeup - now;
|
|
123
|
+
this._log?.debug("connect throttled (waiting %dms)", Math.round(delay));
|
|
124
|
+
waited = true;
|
|
125
|
+
await new Promise((resolve, reject) => {
|
|
126
|
+
const handle = utils.timers.setTimeout(() => {
|
|
127
|
+
signal?.removeEventListener("abort", onAbort);
|
|
128
|
+
resolve();
|
|
129
|
+
}, delay);
|
|
130
|
+
const onAbort = () => {
|
|
131
|
+
utils.timers.clearTimeout(handle);
|
|
132
|
+
reject(signal.reason);
|
|
133
|
+
};
|
|
134
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/** Reset all internal state. Mainly for tests. */
|
|
139
|
+
reset() {
|
|
140
|
+
this.sanity.reset();
|
|
141
|
+
this.flood.reset();
|
|
142
|
+
this.mtprotoError.reset();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
exports.ConnectionFloodController = ConnectionFloodController;
|
|
146
|
+
exports.DEFAULT_FLOOD_LIMITS = DEFAULT_FLOOD_LIMITS;
|
|
147
|
+
exports.DEFAULT_MTPROTO_ERROR_LIMITS = DEFAULT_MTPROTO_ERROR_LIMITS;
|
|
148
|
+
exports.DEFAULT_SANITY_LIMITS = DEFAULT_SANITY_LIMITS;
|
|
149
|
+
exports.FloodControl = FloodControl;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Logger } from '../utils/logger.js';
|
|
2
|
+
export interface FloodLimit {
|
|
3
|
+
/** maximum events allowed within `windowMs` */
|
|
4
|
+
count: number;
|
|
5
|
+
/** window size in ms */
|
|
6
|
+
windowMs: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Sliding-window flood control. Port of TDLib's `FloodControlStrict`
|
|
10
|
+
* (tdutils/td/utils/FloodControlStrict.h).
|
|
11
|
+
*/
|
|
12
|
+
export declare class FloodControl {
|
|
13
|
+
private readonly _rules;
|
|
14
|
+
private readonly _maxWindow;
|
|
15
|
+
private _events;
|
|
16
|
+
constructor(rules: readonly FloodLimit[]);
|
|
17
|
+
/** Earliest absolute perf-now ms at which a new event is permitted. */
|
|
18
|
+
getWakeupAt(now: number): number;
|
|
19
|
+
addEvent(now: number): void;
|
|
20
|
+
private _prune;
|
|
21
|
+
reset(): void;
|
|
22
|
+
}
|
|
23
|
+
export declare const DEFAULT_SANITY_LIMITS: readonly FloodLimit[];
|
|
24
|
+
export declare const DEFAULT_FLOOD_LIMITS: readonly FloodLimit[];
|
|
25
|
+
export declare const DEFAULT_MTPROTO_ERROR_LIMITS: readonly FloodLimit[];
|
|
26
|
+
export interface ConnectionFloodLimits {
|
|
27
|
+
sanity?: readonly FloodLimit[];
|
|
28
|
+
flood?: readonly FloodLimit[];
|
|
29
|
+
mtprotoError?: readonly FloodLimit[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Per-connection-slot flood control bundle modeled after TDLib's
|
|
33
|
+
* `ConnectionCreator` client state (`ConnectionCreator.cpp`) — TDLib keys
|
|
34
|
+
* its flood control by pool slot (the `SessionProxy#i` hash), so each
|
|
35
|
+
* socket's connect history is throttled independently.
|
|
36
|
+
*
|
|
37
|
+
* Three limiters compose:
|
|
38
|
+
* - `sanity` — absolute ceiling, always applied
|
|
39
|
+
* - `flood` — burst limit on connection attempts, always applied
|
|
40
|
+
* - `mtprotoError` — ticks only on MTProto-level errors, always applied
|
|
41
|
+
*
|
|
42
|
+
* TDLib additionally has a stricter "online" regime keyed to app foreground
|
|
43
|
+
* state — we have no such signal, so only the permissive regime is modeled.
|
|
44
|
+
*
|
|
45
|
+
* `wait()` blocks until all limiters allow a fresh connection and records
|
|
46
|
+
* the event atomically (sanity + flood).
|
|
47
|
+
*/
|
|
48
|
+
export declare class ConnectionFloodController {
|
|
49
|
+
readonly sanity: FloodControl;
|
|
50
|
+
readonly flood: FloodControl;
|
|
51
|
+
readonly mtprotoError: FloodControl;
|
|
52
|
+
private _log?;
|
|
53
|
+
constructor(limits?: ConnectionFloodLimits);
|
|
54
|
+
setLogger(log: Logger): void;
|
|
55
|
+
/**
|
|
56
|
+
* Notify a network-up transition.
|
|
57
|
+
*
|
|
58
|
+
* TDLib clears sanity + online-regime flood + backoff on
|
|
59
|
+
* `ConnectionCreator::on_network(true)`. We don't model the online regime,
|
|
60
|
+
* and our transport layer owns its own reconnect backoff, so only the
|
|
61
|
+
* sanity limiter is reset here.
|
|
62
|
+
*/
|
|
63
|
+
notifyNetworkUp(): void;
|
|
64
|
+
/** Record an MTProto-level error (transport 429; per TDLib, other codes don't tick this). */
|
|
65
|
+
addMtprotoError(now?: number): void;
|
|
66
|
+
/** Earliest perf-now ms at which a new connection attempt is permitted. */
|
|
67
|
+
getWakeupAt(now: number): number;
|
|
68
|
+
/**
|
|
69
|
+
* Block until a connection attempt is permitted under all applicable
|
|
70
|
+
* limiters, then record the attempt. Concurrent waiters serialize fairly
|
|
71
|
+
* because the first to wake records its event before the next checks state.
|
|
72
|
+
*
|
|
73
|
+
* If `signal` aborts, the pending timer is cleared and the promise rejects
|
|
74
|
+
* with the signal's reason.
|
|
75
|
+
*/
|
|
76
|
+
wait(signal?: AbortSignal): Promise<void>;
|
|
77
|
+
/** Reset all internal state. Mainly for tests. */
|
|
78
|
+
reset(): void;
|
|
79
|
+
}
|