@mtkruto/browser 0.119.0 → 0.120.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/README.md +1 -1
- package/esm/0_errors.d.ts.map +1 -1
- package/esm/0_errors.js +9 -31
- package/esm/3_errors.js +2 -12
- package/esm/4_errors.js +2 -12
- package/esm/_dnt.polyfills.d.ts +0 -99
- package/esm/_dnt.polyfills.d.ts.map +1 -1
- package/esm/_dnt.polyfills.js +1 -127
- package/esm/client/0_abortable_loop.js +26 -39
- package/esm/client/0_storage_operations.js +179 -218
- package/esm/client/1_client_plain.js +4 -22
- package/esm/client/2_account_manager.js +140 -149
- package/esm/client/2_bot_info_manager.js +26 -38
- package/esm/client/2_business_connection_manager.js +10 -23
- package/esm/client/2_client_encrypted.js +198 -215
- package/esm/client/2_file_manager.js +255 -262
- package/esm/client/2_network_statistics_manager.js +31 -44
- package/esm/client/2_payment_manager.js +7 -20
- package/esm/client/2_reaction_manager.js +7 -20
- package/esm/client/2_translations_manager.js +101 -111
- package/esm/client/2_update_manager.js +750 -745
- package/esm/client/3_client_encrypted_pool.js +10 -26
- package/esm/client/3_message_manager.js +503 -508
- package/esm/client/3_video_chat_manager.js +57 -68
- package/esm/client/4_callback_query_manager.js +18 -30
- package/esm/client/4_chat_list_manager.js +140 -146
- package/esm/client/4_chat_manager.js +161 -169
- package/esm/client/4_checklist_manager.js +26 -39
- package/esm/client/4_context.js +244 -259
- package/esm/client/4_forum_manager.js +67 -73
- package/esm/client/4_gift_manager.js +22 -35
- package/esm/client/4_inline_query_manager.js +16 -28
- package/esm/client/4_link_preview_manager.js +6 -19
- package/esm/client/4_poll_manager.js +44 -57
- package/esm/client/4_story_manager.js +41 -53
- package/esm/client/5_composer.js +13 -26
- package/esm/client/6_client.js +866 -896
- package/esm/client/6_client_dispatcher.js +308 -325
- package/esm/client/7_client_worker.js +16 -29
- package/esm/connection/1_connection_tcp.js +55 -82
- package/esm/connection/1_connection_web_socket.js +75 -91
- package/esm/deps/jsr.io/@roj/tgcrypto/1.0.1/dist/tgcrypto.js +3 -11
- package/esm/deps/jsr.io/@std/async/1.2.0/mux_async_iterator.js +31 -47
- package/esm/deps/jsr.io/@std/async/1.2.0/tee.js +11 -34
- package/esm/deps/jsr.io/@std/cache/0.2.2/lru_cache.js +30 -47
- package/esm/deps/jsr.io/@std/datetime/0.225.7/_date_time_formatter.js +4 -17
- package/esm/session/0_session_state.js +12 -38
- package/esm/session/1_session.js +49 -72
- package/esm/session/2_session_encrypted.js +422 -420
- package/esm/storage/2_storage_indexed_db.js +26 -44
- package/esm/storage/2_storage_local_storage.js +3 -16
- package/esm/storage/2_storage_memory.js +24 -41
- package/esm/storage/2_storage_session_storage.js +3 -16
- package/esm/tl/1_tl_reader.d.ts +1 -1
- package/esm/tl/1_tl_reader.d.ts.map +1 -1
- package/esm/tl/1_tl_reader.js +95 -103
- package/esm/tl/1_tl_writer.js +169 -178
- package/esm/transport/0_transport.js +1 -8
- package/esm/transport/1_transport_abridged.js +11 -24
- package/esm/transport/1_transport_intermediate.js +10 -23
- package/esm/utilities/0_mutex.js +4 -19
- package/esm/utilities/0_part_stream.js +11 -25
- package/esm/utilities/1_crypto.js +42 -53
- package/esm/utilities/2_queue.js +29 -47
- package/package.json +1 -1
- package/script/0_errors.d.ts.map +1 -1
- package/script/0_errors.js +9 -31
- package/script/3_errors.js +2 -12
- package/script/4_errors.js +2 -12
- package/script/_dnt.polyfills.d.ts +0 -99
- package/script/_dnt.polyfills.d.ts.map +1 -1
- package/script/_dnt.polyfills.js +0 -128
- package/script/client/0_abortable_loop.js +27 -40
- package/script/client/0_storage_operations.js +179 -218
- package/script/client/1_client_plain.js +4 -22
- package/script/client/2_account_manager.js +140 -149
- package/script/client/2_bot_info_manager.js +26 -38
- package/script/client/2_business_connection_manager.js +10 -23
- package/script/client/2_client_encrypted.js +199 -216
- package/script/client/2_file_manager.js +255 -262
- package/script/client/2_network_statistics_manager.js +32 -45
- package/script/client/2_payment_manager.js +7 -20
- package/script/client/2_reaction_manager.js +7 -20
- package/script/client/2_translations_manager.js +102 -112
- package/script/client/2_update_manager.js +750 -745
- package/script/client/3_client_encrypted_pool.js +10 -26
- package/script/client/3_message_manager.js +503 -508
- package/script/client/3_video_chat_manager.js +57 -68
- package/script/client/4_callback_query_manager.js +18 -30
- package/script/client/4_chat_list_manager.js +140 -146
- package/script/client/4_chat_manager.js +161 -169
- package/script/client/4_checklist_manager.js +26 -39
- package/script/client/4_context.js +244 -259
- package/script/client/4_forum_manager.js +67 -73
- package/script/client/4_gift_manager.js +22 -35
- package/script/client/4_inline_query_manager.js +16 -28
- package/script/client/4_link_preview_manager.js +6 -19
- package/script/client/4_poll_manager.js +44 -57
- package/script/client/4_story_manager.js +41 -53
- package/script/client/5_composer.js +13 -26
- package/script/client/6_client.js +866 -896
- package/script/client/6_client_dispatcher.js +308 -325
- package/script/client/7_client_worker.js +16 -29
- package/script/connection/1_connection_tcp.js +55 -82
- package/script/connection/1_connection_web_socket.js +75 -91
- package/script/deps/jsr.io/@roj/tgcrypto/1.0.1/dist/tgcrypto.js +3 -11
- package/script/deps/jsr.io/@std/async/1.2.0/mux_async_iterator.js +31 -47
- package/script/deps/jsr.io/@std/async/1.2.0/tee.js +11 -34
- package/script/deps/jsr.io/@std/cache/0.2.2/lru_cache.js +30 -47
- package/script/deps/jsr.io/@std/datetime/0.225.7/_date_time_formatter.js +4 -17
- package/script/session/0_session_state.js +12 -38
- package/script/session/1_session.js +49 -72
- package/script/session/2_session_encrypted.js +423 -421
- package/script/storage/2_storage_indexed_db.js +26 -44
- package/script/storage/2_storage_local_storage.js +3 -16
- package/script/storage/2_storage_memory.js +24 -41
- package/script/storage/2_storage_session_storage.js +3 -16
- package/script/tl/1_tl_reader.d.ts +1 -1
- package/script/tl/1_tl_reader.d.ts.map +1 -1
- package/script/tl/1_tl_reader.js +96 -104
- package/script/tl/1_tl_writer.js +170 -179
- package/script/transport/0_transport.js +1 -8
- package/script/transport/1_transport_abridged.js +11 -24
- package/script/transport/1_transport_intermediate.js +10 -23
- package/script/utilities/0_mutex.js +4 -19
- package/script/utilities/0_part_stream.js +11 -25
- package/script/utilities/1_crypto.js +43 -54
- package/script/utilities/2_queue.js +30 -48
|
@@ -17,18 +17,6 @@
|
|
|
17
17
|
* You should have received a copy of the GNU Lesser General Public License
|
|
18
18
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
19
19
|
*/
|
|
20
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
21
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
22
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
23
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
24
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
25
|
-
};
|
|
26
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
27
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
28
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
29
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
30
|
-
};
|
|
31
|
-
var _MessageManager_instances, _a, _MessageManager_c, _MessageManager_LresolveFileId, _MessageManager_checkParams, _MessageManager_constructReplyMarkup, _MessageManager_resolveSendAs, _MessageManager_constructReplyTo, _MessageManager_isM4a, _MessageManager_sendDocumentInner, _MessageManager_sendMedia, _MessageManager_CAPTIONABLE_MESSAGE_TYPES, _MessageManager_editInlineMessageTextInner, _MessageManager_resolveInputMediaInner, _MessageManager_resolveInputMedia, _MessageManager_resolveInputMediaUpload, _MessageManager_sendReaction, _MessageManager_getCachedVoiceTranscription, _MessageManager_cacheVoiceTranscription;
|
|
32
20
|
import { contentType, equals, startsWith, unreachable } from "../0_deps.js";
|
|
33
21
|
import { InputError } from "../0_errors.js";
|
|
34
22
|
import { encodeText, fromUnixTimestamp, getLogger, getRandomId } from "../1_utilities.js";
|
|
@@ -62,31 +50,21 @@ const messageManagerUpdates = [
|
|
|
62
50
|
"updateTranscribedAudio",
|
|
63
51
|
];
|
|
64
52
|
export class MessageManager {
|
|
53
|
+
#c;
|
|
54
|
+
#LresolveFileId;
|
|
65
55
|
constructor(c) {
|
|
66
|
-
|
|
67
|
-
_MessageManager_c.set(this, void 0);
|
|
68
|
-
_MessageManager_LresolveFileId.set(this, void 0);
|
|
69
|
-
Object.defineProperty(this, "usernameResolver", {
|
|
70
|
-
enumerable: true,
|
|
71
|
-
configurable: true,
|
|
72
|
-
writable: true,
|
|
73
|
-
value: async (v) => {
|
|
74
|
-
const inputPeer = await __classPrivateFieldGet(this, _MessageManager_c, "f").getInputPeer(v).then((v) => Api.as("inputPeerUser", v));
|
|
75
|
-
return { ...inputPeer, _: "inputUser" };
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
__classPrivateFieldSet(this, _MessageManager_c, c, "f");
|
|
56
|
+
this.#c = c;
|
|
79
57
|
const L = getLogger("MessageManager").client(c.id);
|
|
80
|
-
|
|
58
|
+
this.#LresolveFileId = L.branch("resolveFileId");
|
|
81
59
|
}
|
|
82
60
|
async getMessages(chatId, messageIds) {
|
|
83
61
|
checkArray(messageIds, checkMessageId);
|
|
84
|
-
const peer = await
|
|
62
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
85
63
|
let messages_ = new Array();
|
|
86
|
-
const chatId_ = await
|
|
64
|
+
const chatId_ = await this.#c.getInputPeerChatId(peer);
|
|
87
65
|
let shouldFetch = false;
|
|
88
66
|
for (const messageId of messageIds) {
|
|
89
|
-
const message = await
|
|
67
|
+
const message = await this.#c.messageStorage.getMessage(chatId_, messageId);
|
|
90
68
|
if (message === null) {
|
|
91
69
|
messages_ = [];
|
|
92
70
|
shouldFetch = true;
|
|
@@ -98,10 +76,10 @@ export class MessageManager {
|
|
|
98
76
|
}
|
|
99
77
|
if (shouldFetch) {
|
|
100
78
|
if (canBeInputChannel(peer)) {
|
|
101
|
-
messages_ = await
|
|
79
|
+
messages_ = await this.#c.invoke({ _: "channels.getMessages", channel: toInputChannel(peer), id: messageIds.map((v) => ({ _: "inputMessageID", id: v })) }).then((v) => Api.as("messages.channelMessages", v).messages);
|
|
102
80
|
}
|
|
103
81
|
else {
|
|
104
|
-
messages_ = await
|
|
82
|
+
messages_ = await this.#c.invoke({
|
|
105
83
|
_: "messages.getMessages",
|
|
106
84
|
id: messageIds.map((v) => ({ _: "inputMessageID", id: v })),
|
|
107
85
|
}).then((v) => Api.as("messages.messages", v).messages);
|
|
@@ -164,9 +142,23 @@ export class MessageManager {
|
|
|
164
142
|
}
|
|
165
143
|
return [text, entities];
|
|
166
144
|
}
|
|
145
|
+
#checkParams(params) {
|
|
146
|
+
if (params && "replyMarkup" in params && params.replyMarkup !== undefined) {
|
|
147
|
+
this.#c.storage.assertBot("replyMarkup");
|
|
148
|
+
}
|
|
149
|
+
if (params && "businessConnectionId" in params && params.businessConnectionId !== undefined) {
|
|
150
|
+
this.#c.storage.assertBot("businessConnectionId");
|
|
151
|
+
}
|
|
152
|
+
if (params && "sendAs" in params && params.sendAs !== undefined) {
|
|
153
|
+
this.#c.storage.assertUser("sendAs");
|
|
154
|
+
}
|
|
155
|
+
if (params && "sendAt" in params && params.sendAt !== undefined) {
|
|
156
|
+
this.#c.storage.assertUser("businessConsendAtnectionId");
|
|
157
|
+
}
|
|
158
|
+
}
|
|
167
159
|
parseText(text_, params) {
|
|
168
|
-
const [text, entities_] =
|
|
169
|
-
const entities = entities_?.length > 0 ? entities_.map((v) => messageEntityToTlObject(v,
|
|
160
|
+
const [text, entities_] = MessageManager.parseText(text_, params?.entities ?? [], params?.parseMode ?? this.#c.parseMode);
|
|
161
|
+
const entities = entities_?.length > 0 ? entities_.map((v) => messageEntityToTlObject(v, this.#c.getPeer)) : undefined;
|
|
170
162
|
return [text, entities];
|
|
171
163
|
}
|
|
172
164
|
async updatesToMessages(chatId, updates, businessConnectionId) {
|
|
@@ -208,24 +200,24 @@ export class MessageManager {
|
|
|
208
200
|
let poll = null;
|
|
209
201
|
let pollResults = null;
|
|
210
202
|
if (pollId) {
|
|
211
|
-
[poll, pollResults] = await Promise.all([
|
|
203
|
+
[poll, pollResults] = await Promise.all([this.#c.messageStorage.getPoll(pollId), this.#c.messageStorage.getPollResults(pollId)]);
|
|
212
204
|
}
|
|
213
|
-
const message = await constructMessage_(message_,
|
|
205
|
+
const message = await constructMessage_(message_, this.#c.getPeer, this.getMessage.bind(this), this.#c.fileManager.getStickerSetName.bind(this.#c.fileManager), r, business, poll ?? undefined, pollResults ?? undefined);
|
|
214
206
|
if (!poll && mediaPoll) {
|
|
215
|
-
await
|
|
207
|
+
await this.#c.messageStorage.setPoll(mediaPoll.poll.id, mediaPoll.poll);
|
|
216
208
|
}
|
|
217
209
|
if (!pollResults && mediaPoll) {
|
|
218
|
-
await
|
|
210
|
+
await this.#c.messageStorage.setPollResults(mediaPoll.poll.id, mediaPoll.results);
|
|
219
211
|
}
|
|
220
212
|
return message;
|
|
221
213
|
}
|
|
222
214
|
async forwardMessages(from, to, messageIds, params) {
|
|
223
215
|
checkArray(messageIds, checkMessageId);
|
|
224
|
-
const result = await
|
|
216
|
+
const result = await this.#c.invoke({ _: "messages.forwardMessages", from_peer: await this.#c.getInputPeer(from), to_peer: await this.#c.getInputPeer(to), id: messageIds, random_id: messageIds.map(() => getRandomId()), silent: params?.isSilent || undefined, top_msg_id: params?.messageThreadId, noforwards: params?.isSilent || undefined, send_as: params?.sendAs ? await this.#c.getInputPeer(params.sendAs) : undefined, drop_author: params?.dropSenderName || undefined, drop_media_captions: params?.dropCaption || undefined });
|
|
225
217
|
return await this.updatesToMessages(to, result);
|
|
226
218
|
}
|
|
227
219
|
async getHistory(chatId, params) {
|
|
228
|
-
|
|
220
|
+
this.#c.storage.assertUser("getHistory");
|
|
229
221
|
const limit = getLimit(params?.limit);
|
|
230
222
|
let offsetId = params?.offsetId ?? 0;
|
|
231
223
|
if (offsetId < 0) {
|
|
@@ -235,12 +227,12 @@ export class MessageManager {
|
|
|
235
227
|
if (offsetDate < 0) {
|
|
236
228
|
offsetDate = 0;
|
|
237
229
|
}
|
|
238
|
-
const peer = await
|
|
230
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
239
231
|
const messages = new Array();
|
|
240
232
|
if (messages.length > 0) {
|
|
241
233
|
offsetId = messages[messages.length - 1].id; // TODO: track id of oldest message and don't send requests for it
|
|
242
234
|
}
|
|
243
|
-
const result = await
|
|
235
|
+
const result = await this.#c.invoke({
|
|
244
236
|
_: "messages.getHistory",
|
|
245
237
|
peer: peer,
|
|
246
238
|
offset_id: offsetId,
|
|
@@ -260,11 +252,28 @@ export class MessageManager {
|
|
|
260
252
|
}
|
|
261
253
|
return messages;
|
|
262
254
|
}
|
|
255
|
+
usernameResolver = async (v) => {
|
|
256
|
+
const inputPeer = await this.#c.getInputPeer(v).then((v) => Api.as("inputPeerUser", v));
|
|
257
|
+
return { ...inputPeer, _: "inputUser" };
|
|
258
|
+
};
|
|
259
|
+
async #constructReplyMarkup(params) {
|
|
260
|
+
if (params?.replyMarkup) {
|
|
261
|
+
this.#c.storage.assertBot("replyMarkup");
|
|
262
|
+
return await replyMarkupToTlObject(params.replyMarkup, this.usernameResolver.bind(this));
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
async #resolveSendAs(params) {
|
|
266
|
+
const sendAs = params?.sendAs;
|
|
267
|
+
if (sendAs !== undefined) {
|
|
268
|
+
this.#c.storage.assertUser("sendAs");
|
|
269
|
+
return sendAs ? await this.#c.getInputPeer(sendAs) : undefined;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
263
272
|
async sendMessageDraft(chatId, draftId, text, params) {
|
|
264
|
-
|
|
273
|
+
this.#c.storage.assertBot("sendMessageDraft");
|
|
265
274
|
const [message, entities] = this.parseText(text, params);
|
|
266
|
-
const peer = await
|
|
267
|
-
await
|
|
275
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
276
|
+
await this.#c.invoke({
|
|
268
277
|
_: "messages.setTyping",
|
|
269
278
|
peer,
|
|
270
279
|
action: { _: "sendMessageTextDraftAction", random_id: BigInt(draftId), text: { _: "textWithEntities", text: message, entities: entities ?? [] } },
|
|
@@ -272,22 +281,22 @@ export class MessageManager {
|
|
|
272
281
|
});
|
|
273
282
|
}
|
|
274
283
|
async sendMessage(chatId, text, params) {
|
|
275
|
-
|
|
284
|
+
this.#checkParams(params);
|
|
276
285
|
const [message, entities] = this.parseText(text, params);
|
|
277
|
-
const replyMarkup = await
|
|
278
|
-
const peer = await
|
|
286
|
+
const replyMarkup = await this.#constructReplyMarkup(params);
|
|
287
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
279
288
|
const randomId = getRandomId();
|
|
280
289
|
const noWebpage = params?.linkPreview?.isDisabled ? true : undefined;
|
|
281
290
|
const invertMedia = params?.linkPreview?.isAboveText ? true : undefined;
|
|
282
291
|
const silent = params?.isSilent ? true : undefined;
|
|
283
292
|
const noforwards = params?.isContentProtected ? true : undefined;
|
|
284
|
-
const sendAs = await
|
|
293
|
+
const sendAs = await this.#resolveSendAs(params);
|
|
285
294
|
const effect = params?.effectId ? BigInt(params.effectId) : undefined;
|
|
286
295
|
const schedule_date = params?.sendAt;
|
|
287
296
|
const allow_paid_floodskip = params?.isPaidBroadcast ? true : undefined;
|
|
288
297
|
let result;
|
|
289
298
|
if (!noWebpage && params?.linkPreview?.url) {
|
|
290
|
-
result = await
|
|
299
|
+
result = await this.#c.invoke({
|
|
291
300
|
_: "messages.sendMedia",
|
|
292
301
|
peer,
|
|
293
302
|
random_id: randomId,
|
|
@@ -302,7 +311,7 @@ export class MessageManager {
|
|
|
302
311
|
invert_media: invertMedia,
|
|
303
312
|
silent,
|
|
304
313
|
noforwards,
|
|
305
|
-
reply_to: await
|
|
314
|
+
reply_to: await this.#constructReplyTo(params),
|
|
306
315
|
send_as: sendAs,
|
|
307
316
|
entities,
|
|
308
317
|
reply_markup: replyMarkup,
|
|
@@ -312,7 +321,7 @@ export class MessageManager {
|
|
|
312
321
|
}, { businessConnectionId: params?.businessConnectionId });
|
|
313
322
|
}
|
|
314
323
|
else {
|
|
315
|
-
result = await
|
|
324
|
+
result = await this.#c.invoke({
|
|
316
325
|
_: "messages.sendMessage",
|
|
317
326
|
peer,
|
|
318
327
|
random_id: randomId,
|
|
@@ -321,7 +330,7 @@ export class MessageManager {
|
|
|
321
330
|
invert_media: invertMedia,
|
|
322
331
|
silent,
|
|
323
332
|
noforwards,
|
|
324
|
-
reply_to: await
|
|
333
|
+
reply_to: await this.#constructReplyTo(params),
|
|
325
334
|
send_as: sendAs,
|
|
326
335
|
entities,
|
|
327
336
|
reply_markup: replyMarkup,
|
|
@@ -333,21 +342,38 @@ export class MessageManager {
|
|
|
333
342
|
const message_ = (await this.updatesToMessages(chatId, result, params?.businessConnectionId))[0];
|
|
334
343
|
return assertMessageType(message_, "text");
|
|
335
344
|
}
|
|
345
|
+
async #constructReplyTo(params) {
|
|
346
|
+
const topMsgId = params?.messageThreadId;
|
|
347
|
+
if (!params?.replyTo) {
|
|
348
|
+
if (topMsgId) {
|
|
349
|
+
return { _: "inputReplyToMessage", reply_to_msg_id: topMsgId, top_msg_id: topMsgId };
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
return undefined;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if ("messageId" in params.replyTo) {
|
|
356
|
+
return { _: "inputReplyToMessage", reply_to_msg_id: params.replyTo.messageId, top_msg_id: topMsgId, quote_text: params.replyTo.quote?.text, quote_entities: await Promise.all(params.replyTo.quote?.entities.map((v) => messageEntityToTlObject(v, this.#c.getPeer)) ?? []), quote_offset: params.replyTo.quote?.offset };
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
return { _: "inputReplyToStory", peer: await this.#c.getInputPeer(params.replyTo.chatId), story_id: params.replyTo.storyId };
|
|
360
|
+
}
|
|
361
|
+
}
|
|
336
362
|
async sendVenue(chatId, latitude, longitude, title, address, params) {
|
|
337
|
-
|
|
338
|
-
const peer = await
|
|
363
|
+
this.#checkParams(params);
|
|
364
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
339
365
|
const randomId = getRandomId();
|
|
340
366
|
const silent = params?.isSilent ? true : undefined;
|
|
341
367
|
const noforwards = params?.isContentProtected ? true : undefined;
|
|
342
|
-
const sendAs = params?.sendAs ? await
|
|
343
|
-
const replyMarkup = await
|
|
344
|
-
const result = await
|
|
368
|
+
const sendAs = params?.sendAs ? await this.#c.getInputPeer(params.sendAs) : undefined;
|
|
369
|
+
const replyMarkup = await this.#constructReplyMarkup(params);
|
|
370
|
+
const result = await this.#c.invoke({
|
|
345
371
|
_: "messages.sendMedia",
|
|
346
372
|
peer,
|
|
347
373
|
random_id: randomId,
|
|
348
374
|
silent,
|
|
349
375
|
noforwards,
|
|
350
|
-
reply_to: await
|
|
376
|
+
reply_to: await this.#constructReplyTo(params),
|
|
351
377
|
send_as: sendAs,
|
|
352
378
|
reply_markup: replyMarkup,
|
|
353
379
|
media: {
|
|
@@ -372,20 +398,20 @@ export class MessageManager {
|
|
|
372
398
|
return assertMessageType(message, "venue");
|
|
373
399
|
}
|
|
374
400
|
async sendContact(chatId, firstName, number, params) {
|
|
375
|
-
|
|
376
|
-
const peer = await
|
|
401
|
+
this.#checkParams(params);
|
|
402
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
377
403
|
const randomId = getRandomId();
|
|
378
404
|
const silent = params?.isSilent ? true : undefined;
|
|
379
405
|
const noforwards = params?.isContentProtected ? true : undefined;
|
|
380
|
-
const sendAs = params?.sendAs ? await
|
|
381
|
-
const replyMarkup = await
|
|
382
|
-
const result = await
|
|
406
|
+
const sendAs = params?.sendAs ? await this.#c.getInputPeer(params.sendAs) : undefined;
|
|
407
|
+
const replyMarkup = await this.#constructReplyMarkup(params);
|
|
408
|
+
const result = await this.#c.invoke({
|
|
383
409
|
_: "messages.sendMedia",
|
|
384
410
|
peer,
|
|
385
411
|
random_id: randomId,
|
|
386
412
|
silent,
|
|
387
413
|
noforwards,
|
|
388
|
-
reply_to: await
|
|
414
|
+
reply_to: await this.#constructReplyTo(params),
|
|
389
415
|
send_as: sendAs,
|
|
390
416
|
reply_markup: replyMarkup,
|
|
391
417
|
media: {
|
|
@@ -404,20 +430,20 @@ export class MessageManager {
|
|
|
404
430
|
return assertMessageType(message, "contact");
|
|
405
431
|
}
|
|
406
432
|
async sendDice(chatId, params) {
|
|
407
|
-
|
|
408
|
-
const peer = await
|
|
433
|
+
this.#checkParams(params);
|
|
434
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
409
435
|
const randomId = getRandomId();
|
|
410
436
|
const silent = params?.isSilent ? true : undefined;
|
|
411
437
|
const noforwards = params?.isContentProtected ? true : undefined;
|
|
412
|
-
const sendAs = params?.sendAs ? await
|
|
413
|
-
const replyMarkup = await
|
|
414
|
-
const result = await
|
|
438
|
+
const sendAs = params?.sendAs ? await this.#c.getInputPeer(params.sendAs) : undefined;
|
|
439
|
+
const replyMarkup = await this.#constructReplyMarkup(params);
|
|
440
|
+
const result = await this.#c.invoke({
|
|
415
441
|
_: "messages.sendMedia",
|
|
416
442
|
peer,
|
|
417
443
|
random_id: randomId,
|
|
418
444
|
silent,
|
|
419
445
|
noforwards,
|
|
420
|
-
reply_to: await
|
|
446
|
+
reply_to: await this.#constructReplyTo(params),
|
|
421
447
|
send_as: sendAs,
|
|
422
448
|
reply_markup: replyMarkup,
|
|
423
449
|
media: {
|
|
@@ -433,20 +459,20 @@ export class MessageManager {
|
|
|
433
459
|
return assertMessageType(message, "dice");
|
|
434
460
|
}
|
|
435
461
|
async sendLocation(chatId, latitude, longitude, params) {
|
|
436
|
-
|
|
437
|
-
const peer = await
|
|
462
|
+
this.#checkParams(params);
|
|
463
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
438
464
|
const randomId = getRandomId();
|
|
439
465
|
const silent = params?.isSilent ? true : undefined;
|
|
440
466
|
const noforwards = params?.isContentProtected ? true : undefined;
|
|
441
|
-
const sendAs = params?.sendAs ? await
|
|
442
|
-
const replyMarkup = await
|
|
443
|
-
const result = await
|
|
467
|
+
const sendAs = params?.sendAs ? await this.#c.getInputPeer(params.sendAs) : undefined;
|
|
468
|
+
const replyMarkup = await this.#constructReplyMarkup(params);
|
|
469
|
+
const result = await this.#c.invoke({
|
|
444
470
|
_: "messages.sendMedia",
|
|
445
471
|
peer,
|
|
446
472
|
random_id: randomId,
|
|
447
473
|
silent,
|
|
448
474
|
noforwards,
|
|
449
|
-
reply_to: await
|
|
475
|
+
reply_to: await this.#constructReplyTo(params),
|
|
450
476
|
send_as: sendAs,
|
|
451
477
|
reply_markup: replyMarkup,
|
|
452
478
|
media: params?.livePeriod !== undefined
|
|
@@ -480,18 +506,18 @@ export class MessageManager {
|
|
|
480
506
|
return assertMessageType(message, "location");
|
|
481
507
|
}
|
|
482
508
|
async sendVideoNote(chatId, audio, params) {
|
|
483
|
-
|
|
484
|
-
const message = await
|
|
509
|
+
this.#checkParams(params);
|
|
510
|
+
const message = await this.#sendDocumentInner(chatId, audio, params, FileType.VideoNote, [
|
|
485
511
|
{ _: "documentAttributeVideo", round_message: true, w: params?.length ?? 0, h: params?.length ?? 0, duration: params?.duration ?? 0 },
|
|
486
512
|
], false, VIDEO_NOTE_MIME_TYPES, () => "video_note.mp4");
|
|
487
513
|
return assertMessageType(message, "videoNote");
|
|
488
514
|
}
|
|
489
515
|
async sendAudio(chatId, audio, params) {
|
|
490
|
-
|
|
491
|
-
const message = await
|
|
516
|
+
this.#checkParams(params);
|
|
517
|
+
const message = await this.#sendDocumentInner(chatId, audio, params, FileType.Audio, [
|
|
492
518
|
{ _: "documentAttributeAudio", duration: params?.duration ?? 0, performer: params?.performer, title: params?.title },
|
|
493
519
|
], undefined, AUDIO_MIME_TYPES, (firstPart) => {
|
|
494
|
-
if (
|
|
520
|
+
if (MessageManager.#isM4a(firstPart)) {
|
|
495
521
|
return "audio.m4a";
|
|
496
522
|
}
|
|
497
523
|
else {
|
|
@@ -500,15 +526,18 @@ export class MessageManager {
|
|
|
500
526
|
});
|
|
501
527
|
return assertMessageType(message, "audio");
|
|
502
528
|
}
|
|
529
|
+
static #isM4a(firstPart) {
|
|
530
|
+
return firstPart.length >= 10 && startsWith(firstPart.subarray(4), new Uint8Array([0x66, 0x74, 0x79, 0x70, 0x4D, 0x34]));
|
|
531
|
+
}
|
|
503
532
|
async sendVoice(chatId, voice, params) {
|
|
504
|
-
|
|
505
|
-
const message = await
|
|
533
|
+
this.#checkParams(params);
|
|
534
|
+
const message = await this.#sendDocumentInner(chatId, voice, params, FileType.VoiceNote, [
|
|
506
535
|
{ _: "documentAttributeAudio", voice: true, duration: params?.duration ?? 0 },
|
|
507
536
|
], undefined, VOICE_MIME_TYPES, (firstPart) => {
|
|
508
537
|
if (startsWith(firstPart, new Uint8Array([0x4F, 0x67, 0x67]))) {
|
|
509
538
|
return "voice.ogg";
|
|
510
539
|
}
|
|
511
|
-
else if (
|
|
540
|
+
else if (MessageManager.#isM4a(firstPart)) {
|
|
512
541
|
return "voice.m4a";
|
|
513
542
|
}
|
|
514
543
|
else {
|
|
@@ -518,8 +547,8 @@ export class MessageManager {
|
|
|
518
547
|
return assertMessageType(message, "voice");
|
|
519
548
|
}
|
|
520
549
|
async sendAnimation(chatId, animation, params) {
|
|
521
|
-
|
|
522
|
-
const message = await
|
|
550
|
+
this.#checkParams(params);
|
|
551
|
+
const message = await this.#sendDocumentInner(chatId, animation, params, FileType.Animation, [
|
|
523
552
|
{ _: "documentAttributeAnimated" },
|
|
524
553
|
{ _: "documentAttributeVideo", supports_streaming: true, w: params?.width ?? 0, h: params?.height ?? 0, duration: params?.duration ?? 0 },
|
|
525
554
|
], undefined, ANIMATION_MIME_TYPES, (firstPart) => {
|
|
@@ -533,20 +562,66 @@ export class MessageManager {
|
|
|
533
562
|
return assertMessageType(message, "animation");
|
|
534
563
|
}
|
|
535
564
|
async sendVideo(chatId, video, params) {
|
|
536
|
-
|
|
537
|
-
const message = await
|
|
565
|
+
this.#checkParams(params);
|
|
566
|
+
const message = await this.#sendDocumentInner(chatId, video, params, FileType.Video, [
|
|
538
567
|
{ _: "documentAttributeVideo", supports_streaming: params?.supportsStreaming ? true : undefined, w: params?.width ?? 0, h: params?.height ?? 0, duration: params?.duration ?? 0 },
|
|
539
568
|
], undefined, VIDEO_MIME_TYPES, () => "video.mp4");
|
|
540
569
|
return assertMessageType(message, "video");
|
|
541
570
|
}
|
|
571
|
+
async #sendDocumentInner(chatId, document, params, fileType, otherAttribs, urlSupported = true, expectedMimeTypes, createName) {
|
|
572
|
+
let media = null;
|
|
573
|
+
const spoiler = params?.hasSpoiler ? true : undefined;
|
|
574
|
+
const ttl_seconds = params && "selfDestruct" in params && typeof params.selfDestruct !== undefined ? selfDestructOptionToInt(params.selfDestruct) : undefined;
|
|
575
|
+
if (typeof document === "string") {
|
|
576
|
+
const fileId = this.resolveFileId(document, fileType);
|
|
577
|
+
if (fileId !== null) {
|
|
578
|
+
media = { _: "inputMediaDocument", id: { ...fileId, _: "inputDocument" }, spoiler, query: otherAttribs.find((v) => Api.is("documentAttributeSticker", v))?.alt || undefined, ttl_seconds };
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
if (media === null) {
|
|
582
|
+
if (typeof document === "string" && isHttpUrl(document)) {
|
|
583
|
+
if (!urlSupported) {
|
|
584
|
+
throw new InputError("URL not supported.");
|
|
585
|
+
}
|
|
586
|
+
media = { _: "inputMediaDocumentExternal", url: document, spoiler, ttl_seconds };
|
|
587
|
+
}
|
|
588
|
+
else {
|
|
589
|
+
let mimeType;
|
|
590
|
+
const file = await this.#c.fileManager.upload(document, params, (name, firstPart) => {
|
|
591
|
+
if (!params?.fileName && firstPart && createName) {
|
|
592
|
+
name = createName(firstPart);
|
|
593
|
+
}
|
|
594
|
+
mimeType = params?.mimeType ?? contentType(name.split(".").slice(-1)[0]);
|
|
595
|
+
if (name.endsWith(".tgs") && fileType === FileType.Document) {
|
|
596
|
+
name += "-";
|
|
597
|
+
}
|
|
598
|
+
return name;
|
|
599
|
+
});
|
|
600
|
+
mimeType ??= FALLBACK_MIME_TYPE;
|
|
601
|
+
if (mimeType && expectedMimeTypes && !expectedMimeTypes.includes(mimeType)) {
|
|
602
|
+
unreachable();
|
|
603
|
+
}
|
|
604
|
+
if (Api.is("inputFileStoryDocument", file)) {
|
|
605
|
+
unreachable();
|
|
606
|
+
}
|
|
607
|
+
let thumb = undefined;
|
|
608
|
+
if (params?.thumbnail) {
|
|
609
|
+
thumb = await this.#c.fileManager.upload(params.thumbnail, { chunkSize: params?.chunkSize, signal: params?.signal });
|
|
610
|
+
}
|
|
611
|
+
media = { _: "inputMediaUploadedDocument", file, thumb, spoiler, attributes: [{ _: "documentAttributeFilename", file_name: file.name }, ...otherAttribs], mime_type: mimeType, force_file: fileType === FileType.Document ? true : undefined, ttl_seconds };
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
const message = await this.#sendMedia(chatId, media, params);
|
|
615
|
+
return message;
|
|
616
|
+
}
|
|
542
617
|
async sendDocument(chatId, document, params) {
|
|
543
|
-
|
|
544
|
-
const message = await
|
|
618
|
+
this.#checkParams(params);
|
|
619
|
+
const message = await this.#sendDocumentInner(chatId, document, params, FileType.Document, []);
|
|
545
620
|
return assertMessageType(message, "document");
|
|
546
621
|
}
|
|
547
622
|
async sendSticker(chatId, sticker, params) {
|
|
548
|
-
|
|
549
|
-
const message = await
|
|
623
|
+
this.#checkParams(params);
|
|
624
|
+
const message = await this.#sendDocumentInner(chatId, sticker, params, FileType.Sticker, [{ _: "documentAttributeSticker", alt: params?.emoji || "", stickerset: { _: "inputStickerSetEmpty" } }], undefined, STICKER_MIME_TYPES, (firstPart) => {
|
|
550
625
|
if (startsWith(firstPart, new Uint8Array([0x1F, 0x8B]))) {
|
|
551
626
|
return "file.tgs";
|
|
552
627
|
}
|
|
@@ -560,7 +635,7 @@ export class MessageManager {
|
|
|
560
635
|
return assertMessageType(message, "sticker");
|
|
561
636
|
}
|
|
562
637
|
async sendPhoto(chatId, photo, params) {
|
|
563
|
-
|
|
638
|
+
this.#checkParams(params);
|
|
564
639
|
let media = null;
|
|
565
640
|
const spoiler = params?.hasSpoiler ? true : undefined;
|
|
566
641
|
const ttl_seconds = params && "selfDestruct" in params && params.selfDestruct !== undefined ? selfDestructOptionToInt(params.selfDestruct) : undefined;
|
|
@@ -575,7 +650,7 @@ export class MessageManager {
|
|
|
575
650
|
media = { _: "inputMediaPhotoExternal", url: photo, spoiler, ttl_seconds: (params && "selfDestruct" in params && params.selfDestruct !== undefined) ? selfDestructOptionToInt(params.selfDestruct) : undefined };
|
|
576
651
|
}
|
|
577
652
|
else {
|
|
578
|
-
const file = await
|
|
653
|
+
const file = await this.#c.fileManager.upload(photo, params, (name, firstPart) => {
|
|
579
654
|
if (params?.fileName || !firstPart || name.includes(".")) {
|
|
580
655
|
return name;
|
|
581
656
|
}
|
|
@@ -589,9 +664,44 @@ export class MessageManager {
|
|
|
589
664
|
media = { _: "inputMediaUploadedPhoto", file, spoiler, ttl_seconds: (params && "selfDestruct" in params && params.selfDestruct !== undefined) ? selfDestructOptionToInt(params.selfDestruct) : undefined };
|
|
590
665
|
}
|
|
591
666
|
}
|
|
592
|
-
const message = await
|
|
667
|
+
const message = await this.#sendMedia(chatId, media, params);
|
|
593
668
|
return assertMessageType(message, "photo");
|
|
594
669
|
}
|
|
670
|
+
async #sendMedia(chatId, media, params) {
|
|
671
|
+
if (params?.starCount !== undefined) {
|
|
672
|
+
if (params.starCount <= 0) {
|
|
673
|
+
throw new InputError("starCount cannot be zero or negative");
|
|
674
|
+
}
|
|
675
|
+
media = { _: "inputMediaPaidMedia", stars_amount: BigInt(params.starCount), extended_media: [media] };
|
|
676
|
+
}
|
|
677
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
678
|
+
const randomId = getRandomId();
|
|
679
|
+
const silent = params?.isSilent ? true : undefined;
|
|
680
|
+
const noforwards = params?.isContentProtected ? true : undefined;
|
|
681
|
+
const sendAs = params?.sendAs ? await this.#c.getInputPeer(params.sendAs) : undefined;
|
|
682
|
+
const replyMarkup = await this.#constructReplyMarkup(params);
|
|
683
|
+
const caption_ = params?.caption;
|
|
684
|
+
const parseResult = caption_ !== undefined ? this.parseText(caption_, { parseMode: params?.parseMode, entities: params?.captionEntities }) : undefined;
|
|
685
|
+
const caption = parseResult === undefined ? undefined : parseResult[0];
|
|
686
|
+
const captionEntities = parseResult === undefined ? undefined : parseResult[1];
|
|
687
|
+
const result = await this.#c.invoke({
|
|
688
|
+
_: "messages.sendMedia",
|
|
689
|
+
peer,
|
|
690
|
+
random_id: randomId,
|
|
691
|
+
silent,
|
|
692
|
+
noforwards,
|
|
693
|
+
reply_markup: replyMarkup,
|
|
694
|
+
reply_to: await this.#constructReplyTo(params),
|
|
695
|
+
send_as: sendAs,
|
|
696
|
+
media,
|
|
697
|
+
message: caption ?? "",
|
|
698
|
+
entities: captionEntities,
|
|
699
|
+
effect: params?.effectId ? BigInt(params.effectId) : undefined,
|
|
700
|
+
schedule_date: params?.sendAt,
|
|
701
|
+
allow_paid_floodskip: params?.isPaidBroadcast ? true : undefined,
|
|
702
|
+
}, { businessConnectionId: params?.businessConnectionId });
|
|
703
|
+
return (await this.updatesToMessages(chatId, result, params?.businessConnectionId))[0];
|
|
704
|
+
}
|
|
595
705
|
resolveFileId(maybeFileId, expectedFileType) {
|
|
596
706
|
expectedFileType = Array.isArray(expectedFileType) ? expectedFileType : [expectedFileType];
|
|
597
707
|
let fileId = null;
|
|
@@ -599,7 +709,7 @@ export class MessageManager {
|
|
|
599
709
|
fileId = deserializeFileId(maybeFileId);
|
|
600
710
|
}
|
|
601
711
|
catch (err) {
|
|
602
|
-
|
|
712
|
+
this.#LresolveFileId.warning(err);
|
|
603
713
|
}
|
|
604
714
|
if (fileId !== null) {
|
|
605
715
|
if (!expectedFileType.includes(fileId.type)) {
|
|
@@ -614,7 +724,7 @@ export class MessageManager {
|
|
|
614
724
|
return null;
|
|
615
725
|
}
|
|
616
726
|
async sendPoll(chatId, question, options, params) {
|
|
617
|
-
|
|
727
|
+
this.#checkParams(params);
|
|
618
728
|
question = question?.trim();
|
|
619
729
|
if (!question) {
|
|
620
730
|
throw new Error("Question must not be empty.");
|
|
@@ -622,12 +732,12 @@ export class MessageManager {
|
|
|
622
732
|
if (!Array.isArray(options) || options.length < 2) {
|
|
623
733
|
throw new Error("There must be at least two options.");
|
|
624
734
|
}
|
|
625
|
-
const peer = await
|
|
735
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
626
736
|
const randomId = getRandomId();
|
|
627
737
|
const silent = params?.isSilent ? true : undefined;
|
|
628
738
|
const noforwards = params?.isContentProtected ? true : undefined;
|
|
629
|
-
const sendAs = params?.sendAs ? await
|
|
630
|
-
const replyMarkup = await
|
|
739
|
+
const sendAs = params?.sendAs ? await this.#c.getInputPeer(params.sendAs) : undefined;
|
|
740
|
+
const replyMarkup = await this.#constructReplyMarkup(params);
|
|
631
741
|
const explanation = params?.explanation;
|
|
632
742
|
const parseResult = explanation !== undefined ? this.parseText(explanation, { parseMode: params?.explanationParseMode, entities: params?.explanationEntities }) : undefined;
|
|
633
743
|
const solution = parseResult === undefined ? undefined : parseResult[0];
|
|
@@ -641,14 +751,14 @@ export class MessageManager {
|
|
|
641
751
|
const questionParseResult = this.parseText(question, { parseMode: params?.questionParseMode, entities: params?.questionEntities });
|
|
642
752
|
const poll = { _: "poll", id: getRandomId(), answers, question: { _: "textWithEntities", text: questionParseResult[0], entities: questionParseResult[1] ?? [] }, closed: params?.isClosed ? true : undefined, close_date: params?.closeDate, close_period: params?.openPeriod ? params.openPeriod : undefined, multiple_choice: params?.allowMultipleAnswers ? true : undefined, public_voters: params?.isAnonymous === false ? true : undefined, quiz: params?.type === "quiz" ? true : undefined };
|
|
643
753
|
const media = { _: "inputMediaPoll", poll, correct_answers: params?.correctOptionIndex !== undefined ? [encodeText(String(params.correctOptionIndex))] : undefined, solution, solution_entities: solutionEntities };
|
|
644
|
-
const result = await
|
|
754
|
+
const result = await this.#c.invoke({
|
|
645
755
|
_: "messages.sendMedia",
|
|
646
756
|
peer,
|
|
647
757
|
random_id: randomId,
|
|
648
758
|
silent,
|
|
649
759
|
noforwards,
|
|
650
760
|
reply_markup: replyMarkup,
|
|
651
|
-
reply_to: await
|
|
761
|
+
reply_to: await this.#constructReplyTo(params),
|
|
652
762
|
send_as: sendAs,
|
|
653
763
|
media,
|
|
654
764
|
message: "",
|
|
@@ -660,8 +770,8 @@ export class MessageManager {
|
|
|
660
770
|
return assertMessageType(message, "poll");
|
|
661
771
|
}
|
|
662
772
|
async sendChecklist(chatId, title, items, params) {
|
|
663
|
-
|
|
664
|
-
|
|
773
|
+
this.#c.storage.assertUser("sendChecklist");
|
|
774
|
+
this.#checkParams(params);
|
|
665
775
|
title = title?.trim();
|
|
666
776
|
if (!title) {
|
|
667
777
|
throw new Error("Title must not be empty.");
|
|
@@ -669,11 +779,11 @@ export class MessageManager {
|
|
|
669
779
|
if (!Array.isArray(items) || items.length < 1) {
|
|
670
780
|
throw new Error("There must be at least one item.");
|
|
671
781
|
}
|
|
672
|
-
const peer = await
|
|
782
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
673
783
|
const randomId = getRandomId();
|
|
674
784
|
const silent = params?.isSilent ? true : undefined;
|
|
675
785
|
const noforwards = params?.isContentProtected ? true : undefined;
|
|
676
|
-
const sendAs = params?.sendAs ? await
|
|
786
|
+
const sendAs = params?.sendAs ? await this.#c.getInputPeer(params.sendAs) : undefined;
|
|
677
787
|
const list = items.map((v, i) => {
|
|
678
788
|
const text = v.text;
|
|
679
789
|
const entities = v.entities;
|
|
@@ -689,13 +799,13 @@ export class MessageManager {
|
|
|
689
799
|
others_can_complete: params?.isCompletableByOthers ? true : undefined,
|
|
690
800
|
};
|
|
691
801
|
const media = { _: "inputMediaTodo", todo };
|
|
692
|
-
const result = await
|
|
802
|
+
const result = await this.#c.invoke({
|
|
693
803
|
_: "messages.sendMedia",
|
|
694
804
|
peer,
|
|
695
805
|
random_id: randomId,
|
|
696
806
|
silent,
|
|
697
807
|
noforwards,
|
|
698
|
-
reply_to: await
|
|
808
|
+
reply_to: await this.#constructReplyTo(params),
|
|
699
809
|
send_as: sendAs,
|
|
700
810
|
media,
|
|
701
811
|
message: "",
|
|
@@ -707,26 +817,26 @@ export class MessageManager {
|
|
|
707
817
|
return assertMessageType(message, "checklist");
|
|
708
818
|
}
|
|
709
819
|
async editMessageReplyMarkup(chatId, messageId, params) {
|
|
710
|
-
|
|
711
|
-
const result = await
|
|
820
|
+
this.#checkParams(params);
|
|
821
|
+
const result = await this.#c.invoke({
|
|
712
822
|
_: "messages.editMessage",
|
|
713
823
|
id: checkMessageId(messageId),
|
|
714
|
-
peer: await
|
|
715
|
-
reply_markup: await
|
|
824
|
+
peer: await this.#c.getInputPeer(chatId),
|
|
825
|
+
reply_markup: await this.#constructReplyMarkup(params),
|
|
716
826
|
}, { businessConnectionId: params?.businessConnectionId });
|
|
717
827
|
const message_ = (await this.updatesToMessages(chatId, result))[0];
|
|
718
828
|
return message_;
|
|
719
829
|
}
|
|
720
830
|
async editInlineMessageReplyMarkup(inlineMessageId, params) {
|
|
721
831
|
const id = await deserializeInlineMessageId(inlineMessageId);
|
|
722
|
-
await
|
|
832
|
+
await this.#c.invoke({
|
|
723
833
|
_: "messages.editInlineBotMessage",
|
|
724
834
|
id,
|
|
725
|
-
reply_markup: await
|
|
835
|
+
reply_markup: await this.#constructReplyMarkup(params),
|
|
726
836
|
}, { dc: getDc(id.dc_id) });
|
|
727
837
|
}
|
|
728
838
|
async editMessageText(chatId, messageId, text, params) {
|
|
729
|
-
|
|
839
|
+
this.#checkParams(params);
|
|
730
840
|
{
|
|
731
841
|
const message = await this.getMessage(chatId, messageId);
|
|
732
842
|
if (!message) {
|
|
@@ -749,27 +859,28 @@ export class MessageManager {
|
|
|
749
859
|
if (!noWebpage && params?.linkPreview?.url) {
|
|
750
860
|
media = { _: "inputMediaWebPage", url: params.linkPreview.url, force_large_media: params.linkPreview.mediaSize === "large" ? true : undefined, force_small_media: params.linkPreview.mediaSize === "small" ? true : undefined, optional: message.length ? undefined : true };
|
|
751
861
|
}
|
|
752
|
-
const result = await
|
|
862
|
+
const result = await this.#c.invoke({
|
|
753
863
|
_: "messages.editMessage",
|
|
754
864
|
id: checkMessageId(messageId),
|
|
755
|
-
peer: await
|
|
865
|
+
peer: await this.#c.getInputPeer(chatId),
|
|
756
866
|
entities,
|
|
757
867
|
message,
|
|
758
868
|
media,
|
|
759
869
|
no_webpage: noWebpage,
|
|
760
870
|
invert_media: invertMedia,
|
|
761
|
-
reply_markup: await
|
|
871
|
+
reply_markup: await this.#constructReplyMarkup(params),
|
|
762
872
|
}, { businessConnectionId: params?.businessConnectionId });
|
|
763
873
|
const message_ = (await this.updatesToMessages(chatId, result))[0];
|
|
764
874
|
return assertMessageType(message_, "text");
|
|
765
875
|
}
|
|
876
|
+
static #CAPTIONABLE_MESSAGE_TYPES = ["photo", "document", "video", "animation", "voice", "audio", "video"];
|
|
766
877
|
async editMessageCaption(chatId, messageId, params) {
|
|
767
878
|
let canHaveCaption = false;
|
|
768
879
|
const message_ = await this.getMessage(chatId, messageId);
|
|
769
880
|
if (!message_) {
|
|
770
881
|
throw new InputError("Message not found.");
|
|
771
882
|
}
|
|
772
|
-
for (const type of
|
|
883
|
+
for (const type of MessageManager.#CAPTIONABLE_MESSAGE_TYPES) {
|
|
773
884
|
if (isMessageType(message_, type)) {
|
|
774
885
|
canHaveCaption = true;
|
|
775
886
|
}
|
|
@@ -778,24 +889,167 @@ export class MessageManager {
|
|
|
778
889
|
throw new InputError("The referenced message cannot have a caption.");
|
|
779
890
|
}
|
|
780
891
|
const [message, entities] = this.parseText(params?.caption ?? "", params);
|
|
781
|
-
const result = await
|
|
892
|
+
const result = await this.#c.invoke({
|
|
782
893
|
_: "messages.editMessage",
|
|
783
894
|
id: checkMessageId(messageId),
|
|
784
|
-
peer: await
|
|
895
|
+
peer: await this.#c.getInputPeer(chatId),
|
|
785
896
|
entities: message ? entities : [],
|
|
786
897
|
message,
|
|
787
|
-
reply_markup: await
|
|
898
|
+
reply_markup: await this.#constructReplyMarkup(params),
|
|
788
899
|
}, { businessConnectionId: params?.businessConnectionId });
|
|
789
900
|
return (await this.updatesToMessages(chatId, result))[0];
|
|
790
901
|
}
|
|
902
|
+
async #editInlineMessageTextInner(inlineMessageId, text, params, allowEmpty = true) {
|
|
903
|
+
this.#checkParams(params);
|
|
904
|
+
const [message, entities] = this.parseText(text, params);
|
|
905
|
+
if (!allowEmpty && !message) {
|
|
906
|
+
throw new InputError("Message text cannot be empty.");
|
|
907
|
+
}
|
|
908
|
+
const id = await deserializeInlineMessageId(inlineMessageId);
|
|
909
|
+
if (params?.linkPreview && params.linkPreview.type !== "input") {
|
|
910
|
+
throw new InputError("Expected link preview of type input.");
|
|
911
|
+
}
|
|
912
|
+
const noWebpage = params?.linkPreview && params.linkPreview.type === "input" && params.linkPreview.isDisabled ? true : undefined;
|
|
913
|
+
const invertMedia = params?.linkPreview?.isAboveText ? true : undefined;
|
|
914
|
+
let media = undefined;
|
|
915
|
+
if (!noWebpage && params?.linkPreview?.url) {
|
|
916
|
+
media = { _: "inputMediaWebPage", url: params.linkPreview.url, force_large_media: params.linkPreview.mediaSize === "large" ? true : undefined, force_small_media: params.linkPreview.mediaSize === "small" ? true : undefined, optional: message.length ? undefined : true };
|
|
917
|
+
}
|
|
918
|
+
await this.#c.invoke({
|
|
919
|
+
_: "messages.editInlineBotMessage",
|
|
920
|
+
id,
|
|
921
|
+
entities,
|
|
922
|
+
message,
|
|
923
|
+
media,
|
|
924
|
+
no_webpage: noWebpage,
|
|
925
|
+
invert_media: invertMedia,
|
|
926
|
+
reply_markup: await this.#constructReplyMarkup(params),
|
|
927
|
+
}, { dc: getDc(id.dc_id) });
|
|
928
|
+
}
|
|
791
929
|
async editInlineMessageText(inlineMessageId, text, params) {
|
|
792
|
-
await
|
|
930
|
+
await this.#editInlineMessageTextInner(inlineMessageId, text, params, false);
|
|
793
931
|
}
|
|
794
932
|
async editInlineMessageCaption(inlineMessageId, params) {
|
|
795
|
-
await
|
|
933
|
+
await this.#editInlineMessageTextInner(inlineMessageId, params?.caption ?? "", params);
|
|
934
|
+
}
|
|
935
|
+
async #resolveInputMediaInner(document, media, fileType, otherAttribs) {
|
|
936
|
+
let media_ = null;
|
|
937
|
+
const spoiler = "hasSpoiler" in media && media.hasSpoiler ? true : undefined;
|
|
938
|
+
if (typeof document === "string") {
|
|
939
|
+
const fileId = this.resolveFileId(document, fileType);
|
|
940
|
+
if (fileId !== null) {
|
|
941
|
+
media_ = { _: "inputMediaDocument", id: { ...fileId, _: "inputDocument" }, spoiler, query: otherAttribs.find((v) => Api.is("documentAttributeSticker", v))?.alt || undefined };
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
if (media_ === null) {
|
|
945
|
+
if (typeof document === "string" && isHttpUrl(document)) {
|
|
946
|
+
media_ = { _: "inputMediaDocumentExternal", url: document, spoiler };
|
|
947
|
+
}
|
|
948
|
+
else {
|
|
949
|
+
let mimeType;
|
|
950
|
+
const file = await this.#c.fileManager.upload(document, media, (name) => {
|
|
951
|
+
mimeType = media?.mimeType ?? contentType(name.split(".").slice(-1)[0]) ?? FALLBACK_MIME_TYPE;
|
|
952
|
+
if (name.endsWith(".tgs") && fileType === FileType.Document) {
|
|
953
|
+
name += "-";
|
|
954
|
+
}
|
|
955
|
+
return name;
|
|
956
|
+
});
|
|
957
|
+
if (Api.is("inputFileStoryDocument", file)) {
|
|
958
|
+
unreachable();
|
|
959
|
+
}
|
|
960
|
+
let thumb = undefined;
|
|
961
|
+
if ("thumbnail" in media && media.thumbnail) {
|
|
962
|
+
thumb = await this.#c.fileManager.upload(media.thumbnail, { chunkSize: media?.chunkSize, signal: media?.signal });
|
|
963
|
+
}
|
|
964
|
+
media_ = { _: "inputMediaUploadedDocument", file, thumb, spoiler, attributes: [{ _: "documentAttributeFilename", file_name: file.name }, ...otherAttribs], mime_type: mimeType, force_file: fileType === FileType.Document ? true : undefined };
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
return media_;
|
|
968
|
+
}
|
|
969
|
+
async #resolveInputMedia(media) {
|
|
970
|
+
if ("animation" in media) {
|
|
971
|
+
return await this.#resolveInputMediaInner(media.animation, media, FileType.Animation, [
|
|
972
|
+
{ _: "documentAttributeAnimated" },
|
|
973
|
+
{ _: "documentAttributeVideo", supports_streaming: true, w: media?.width ?? 0, h: media?.height ?? 0, duration: media?.duration ?? 0 },
|
|
974
|
+
]);
|
|
975
|
+
}
|
|
976
|
+
else if ("audio" in media) {
|
|
977
|
+
return await this.#resolveInputMediaInner(media.audio, media, FileType.Audio, [
|
|
978
|
+
{ _: "documentAttributeAudio", duration: media?.duration ?? 0, performer: media?.performer, title: media?.title },
|
|
979
|
+
]);
|
|
980
|
+
}
|
|
981
|
+
else if ("document" in media) {
|
|
982
|
+
return await this.#resolveInputMediaInner(media.document, media, FileType.Document, []);
|
|
983
|
+
}
|
|
984
|
+
else if ("photo" in media) {
|
|
985
|
+
let media_ = null;
|
|
986
|
+
const spoiler = media.hasSpoiler ? true : undefined;
|
|
987
|
+
const ttl_seconds = "selfDestruct" in media && media.selfDestruct !== undefined ? selfDestructOptionToInt(media.selfDestruct) : undefined;
|
|
988
|
+
if (typeof media.photo === "string") {
|
|
989
|
+
const fileId = this.resolveFileId(media.photo, [FileType.Photo, FileType.ProfilePhoto]);
|
|
990
|
+
if (fileId !== null) {
|
|
991
|
+
media_ = { _: "inputMediaPhoto", id: { ...fileId, _: "inputPhoto" }, spoiler, ttl_seconds };
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
if (media_ === null) {
|
|
995
|
+
if (typeof media.photo === "string" && isHttpUrl(media.photo)) {
|
|
996
|
+
media_ = { _: "inputMediaPhotoExternal", url: media.photo, spoiler };
|
|
997
|
+
}
|
|
998
|
+
else {
|
|
999
|
+
const file = await this.#c.fileManager.upload(media.photo, media, null, false);
|
|
1000
|
+
media_ = { _: "inputMediaUploadedPhoto", file, spoiler, ttl_seconds };
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
return media_;
|
|
1004
|
+
}
|
|
1005
|
+
else if ("video" in media) {
|
|
1006
|
+
const ttl_seconds = "selfDestruct" in media && media.selfDestruct !== undefined ? selfDestructOptionToInt(media.selfDestruct) : undefined;
|
|
1007
|
+
const media_ = await this.#resolveInputMediaInner(media.video, media, FileType.Video, [
|
|
1008
|
+
{ _: "documentAttributeVideo", supports_streaming: media?.supportsStreaming ? true : undefined, w: media?.width ?? 0, h: media?.height ?? 0, duration: media?.duration ?? 0 },
|
|
1009
|
+
]);
|
|
1010
|
+
media_.ttl_seconds = ttl_seconds;
|
|
1011
|
+
return media_;
|
|
1012
|
+
}
|
|
1013
|
+
else {
|
|
1014
|
+
unreachable();
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
async #resolveInputMediaUpload(media, businessConnectionId) {
|
|
1018
|
+
const inputMedia = await this.#resolveInputMedia(media);
|
|
1019
|
+
if (Api.is("inputMediaUploadedPhoto", inputMedia) || Api.is("inputMediaUploadedDocument", inputMedia)) {
|
|
1020
|
+
const messageMedia = await this.#c.invoke({
|
|
1021
|
+
_: "messages.uploadMedia",
|
|
1022
|
+
peer: { _: "inputPeerSelf" },
|
|
1023
|
+
media: inputMedia,
|
|
1024
|
+
business_connection_id: businessConnectionId,
|
|
1025
|
+
});
|
|
1026
|
+
if (("photo" in messageMedia) && Api.is("photo", messageMedia.photo)) {
|
|
1027
|
+
return {
|
|
1028
|
+
_: "inputMediaPhoto",
|
|
1029
|
+
id: {
|
|
1030
|
+
_: "inputPhoto",
|
|
1031
|
+
id: messageMedia.photo.id,
|
|
1032
|
+
access_hash: messageMedia.photo.access_hash,
|
|
1033
|
+
file_reference: messageMedia.photo.file_reference,
|
|
1034
|
+
},
|
|
1035
|
+
spoiler: "hasSpoiler" in media && media.hasSpoiler ? true : undefined,
|
|
1036
|
+
};
|
|
1037
|
+
}
|
|
1038
|
+
else if ("document" in messageMedia && Api.is("document", messageMedia.document)) {
|
|
1039
|
+
return {
|
|
1040
|
+
_: "inputMediaDocument",
|
|
1041
|
+
id: { _: "inputDocument", id: messageMedia.document.id, access_hash: messageMedia.document.access_hash, file_reference: messageMedia.document.file_reference },
|
|
1042
|
+
spoiler: "hasSpoiler" in media && media.hasSpoiler ? true : undefined,
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
1045
|
+
else {
|
|
1046
|
+
unreachable();
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
return inputMedia;
|
|
796
1050
|
}
|
|
797
1051
|
async editMessageMedia(chatId, messageId, media, params) {
|
|
798
|
-
|
|
1052
|
+
this.#checkParams(params);
|
|
799
1053
|
const message = await this.getMessage(chatId, messageId);
|
|
800
1054
|
if (!message) {
|
|
801
1055
|
throw new InputError("Message not found.");
|
|
@@ -804,12 +1058,12 @@ export class MessageManager {
|
|
|
804
1058
|
throw new InputError("Unexpected message type.");
|
|
805
1059
|
}
|
|
806
1060
|
const [text, entities] = media.caption !== undefined ? this.parseText(media.caption, { entities: media.captionEntities, parseMode: media.parseMode }) : ["", []];
|
|
807
|
-
const result = await
|
|
1061
|
+
const result = await this.#c.invoke({
|
|
808
1062
|
_: "messages.editMessage",
|
|
809
|
-
peer: await
|
|
1063
|
+
peer: await this.#c.getInputPeer(chatId),
|
|
810
1064
|
id: messageId,
|
|
811
|
-
media: await
|
|
812
|
-
reply_markup: await
|
|
1065
|
+
media: await this.#resolveInputMedia(media),
|
|
1066
|
+
reply_markup: await this.#constructReplyMarkup(params),
|
|
813
1067
|
message: text,
|
|
814
1068
|
entities,
|
|
815
1069
|
}, { businessConnectionId: params?.businessConnectionId });
|
|
@@ -817,70 +1071,73 @@ export class MessageManager {
|
|
|
817
1071
|
return message_;
|
|
818
1072
|
}
|
|
819
1073
|
async editInlineMessageMedia(inlineMessageId, media, params) {
|
|
820
|
-
|
|
821
|
-
|
|
1074
|
+
this.#checkParams(params);
|
|
1075
|
+
this.#c.storage.assertBot("editInlineMessageMedia");
|
|
822
1076
|
const id = await deserializeInlineMessageId(inlineMessageId);
|
|
823
|
-
await
|
|
1077
|
+
await this.#c.invoke({
|
|
824
1078
|
_: "messages.editInlineBotMessage",
|
|
825
1079
|
id,
|
|
826
|
-
media: await
|
|
827
|
-
reply_markup: await
|
|
1080
|
+
media: await this.#resolveInputMediaUpload(media),
|
|
1081
|
+
reply_markup: await this.#constructReplyMarkup(params),
|
|
828
1082
|
}, { dc: getDc(id.dc_id) });
|
|
829
1083
|
}
|
|
830
1084
|
async deleteMessages(chatId, messageIds, params) {
|
|
831
1085
|
checkArray(messageIds, checkMessageId);
|
|
832
|
-
const peer = await
|
|
1086
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
833
1087
|
if (canBeInputChannel(peer)) {
|
|
834
|
-
await
|
|
1088
|
+
await this.#c.invoke({ _: "channels.deleteMessages", channel: toInputChannel(peer), id: messageIds });
|
|
835
1089
|
}
|
|
836
1090
|
else {
|
|
837
|
-
await
|
|
1091
|
+
await this.#c.invoke({ _: "messages.deleteMessages", id: messageIds, revoke: params?.onlyForMe ? undefined : true });
|
|
838
1092
|
}
|
|
839
1093
|
}
|
|
840
1094
|
async deleteScheduledMessages(chatId, messageIds) {
|
|
841
|
-
|
|
1095
|
+
this.#c.storage.assertUser("sendScheduledMessage");
|
|
842
1096
|
checkArray(messageIds, checkMessageId);
|
|
843
|
-
const peer = await
|
|
844
|
-
await
|
|
1097
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
1098
|
+
await this.#c.invoke({ _: "messages.deleteScheduledMessages", peer, id: messageIds });
|
|
845
1099
|
}
|
|
846
1100
|
async deleteScheduledMessage(chatId, messageId) {
|
|
847
|
-
|
|
1101
|
+
this.#c.storage.assertUser("deleteScheduledMessage");
|
|
848
1102
|
return await this.deleteScheduledMessages(chatId, [messageId]);
|
|
849
1103
|
}
|
|
850
1104
|
async sendScheduledMessages(chatId, messageIds) {
|
|
851
|
-
|
|
1105
|
+
this.#c.storage.assertUser("sendScheduledMessages");
|
|
852
1106
|
checkArray(messageIds, checkMessageId);
|
|
853
|
-
const peer = await
|
|
854
|
-
const result = await
|
|
1107
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
1108
|
+
const result = await this.#c.invoke({ _: "messages.sendScheduledMessages", peer, id: messageIds });
|
|
855
1109
|
return await this.updatesToMessages(chatId, result);
|
|
856
1110
|
}
|
|
857
1111
|
async sendScheduledMessage(chatId, messageId) {
|
|
858
|
-
|
|
1112
|
+
this.#c.storage.assertUser("sendScheduledMessage");
|
|
859
1113
|
return (await this.sendScheduledMessages(chatId, [messageId]))[0];
|
|
860
1114
|
}
|
|
861
1115
|
async deleteChatMemberMessages(chatId, memberId) {
|
|
862
|
-
|
|
863
|
-
const channel = await
|
|
864
|
-
const participant = await
|
|
865
|
-
await
|
|
1116
|
+
this.#c.storage.assertUser("deleteChatMemberMessages");
|
|
1117
|
+
const channel = await this.#c.getInputChannel(chatId);
|
|
1118
|
+
const participant = await this.#c.getInputPeer(memberId);
|
|
1119
|
+
await this.#c.invoke({ _: "channels.deleteParticipantHistory", channel, participant });
|
|
866
1120
|
}
|
|
867
1121
|
async pinMessage(chatId, messageId, params) {
|
|
868
|
-
|
|
869
|
-
await
|
|
1122
|
+
this.#checkParams(params);
|
|
1123
|
+
await this.#c.invoke({ _: "messages.updatePinnedMessage", peer: await this.#c.getInputPeer(chatId), id: checkMessageId(messageId), silent: params?.isSilent ? true : undefined, pm_oneside: params?.bothSides ? undefined : true });
|
|
870
1124
|
}
|
|
871
1125
|
async unpinMessage(chatId, messageId, params) {
|
|
872
|
-
|
|
873
|
-
await
|
|
1126
|
+
this.#checkParams(params);
|
|
1127
|
+
await this.#c.invoke({ _: "messages.updatePinnedMessage", peer: await this.#c.getInputPeer(chatId), id: checkMessageId(messageId), unpin: true }, { businessConnectionId: params?.businessConnectionId });
|
|
874
1128
|
}
|
|
875
1129
|
async unpinMessages(chatId, params) {
|
|
876
|
-
await
|
|
1130
|
+
await this.#c.invoke({
|
|
877
1131
|
_: "messages.unpinAllMessages",
|
|
878
|
-
peer: await
|
|
1132
|
+
peer: await this.#c.getInputPeer(chatId),
|
|
879
1133
|
top_msg_id: params?.topicId,
|
|
880
1134
|
});
|
|
881
1135
|
}
|
|
1136
|
+
async #sendReaction(chatId, messageId, reactions, params) {
|
|
1137
|
+
await this.#c.invoke({ _: "messages.sendReaction", peer: await this.#c.getInputPeer(chatId), msg_id: checkMessageId(messageId), reaction: reactions.map((v) => reactionToTlObject(v)), big: params?.isBig ? true : undefined, add_to_recent: params?.addToRecents ? true : undefined });
|
|
1138
|
+
}
|
|
882
1139
|
async setReactions(chatId, messageId, reactions, params) {
|
|
883
|
-
await
|
|
1140
|
+
await this.#sendReaction(chatId, messageId, reactions, params);
|
|
884
1141
|
}
|
|
885
1142
|
async addReaction(chatId, messageId, reaction, params) {
|
|
886
1143
|
const message = await this.getMessage(chatId, messageId);
|
|
@@ -917,7 +1174,7 @@ export class MessageManager {
|
|
|
917
1174
|
if (Api.is("updateNewMessage", update) || Api.is("updateNewChannelMessage", update) || Api.is("updateEditMessage", update) || Api.is("updateEditChannelMessage", update)) {
|
|
918
1175
|
if (Api.is("message", update.message) || Api.is("messageService", update.message)) {
|
|
919
1176
|
const chatId = Api.peerToChatId(update.message.peer_id);
|
|
920
|
-
await
|
|
1177
|
+
await this.#c.messageStorage.setMessage(chatId, update.message.id, update.message);
|
|
921
1178
|
}
|
|
922
1179
|
}
|
|
923
1180
|
if (Api.isOneOf([
|
|
@@ -937,7 +1194,7 @@ export class MessageManager {
|
|
|
937
1194
|
shouldIgnore = true;
|
|
938
1195
|
}
|
|
939
1196
|
else {
|
|
940
|
-
shouldIgnore = !
|
|
1197
|
+
shouldIgnore = !this.#c.outgoingMessages;
|
|
941
1198
|
}
|
|
942
1199
|
}
|
|
943
1200
|
if (!shouldIgnore) {
|
|
@@ -959,7 +1216,7 @@ export class MessageManager {
|
|
|
959
1216
|
if (Api.is("updateDeleteMessages", update)) {
|
|
960
1217
|
const deletedMessages = new Array();
|
|
961
1218
|
for (const messageId of update.messages) {
|
|
962
|
-
const chatId = await
|
|
1219
|
+
const chatId = await this.#c.messageStorage.getMessageChat(messageId);
|
|
963
1220
|
if (chatId) {
|
|
964
1221
|
deletedMessages.push({ chatId, messageId });
|
|
965
1222
|
}
|
|
@@ -972,7 +1229,7 @@ export class MessageManager {
|
|
|
972
1229
|
const chatId = Api.getChannelChatId(update.channel_id);
|
|
973
1230
|
const deletedMessages = new Array();
|
|
974
1231
|
for (const messageId of update.messages) {
|
|
975
|
-
const message = await
|
|
1232
|
+
const message = await this.#c.messageStorage.getMessage(chatId, messageId);
|
|
976
1233
|
if (message !== null) {
|
|
977
1234
|
deletedMessages.push({ chatId, messageId });
|
|
978
1235
|
}
|
|
@@ -991,13 +1248,13 @@ export class MessageManager {
|
|
|
991
1248
|
}
|
|
992
1249
|
if (Api.is("updateTranscribedAudio", update)) {
|
|
993
1250
|
const voiceTranscription = constructVoiceTranscription(update);
|
|
994
|
-
await
|
|
1251
|
+
await this.#c.messageStorage.setVoiceTranscription(voiceTranscription);
|
|
995
1252
|
return { voiceTranscription };
|
|
996
1253
|
}
|
|
997
1254
|
return null;
|
|
998
1255
|
}
|
|
999
1256
|
async sendChatAction(chatId, action, params) {
|
|
1000
|
-
|
|
1257
|
+
this.#checkParams(params);
|
|
1001
1258
|
let action_;
|
|
1002
1259
|
switch (action) {
|
|
1003
1260
|
case "type":
|
|
@@ -1036,13 +1293,13 @@ export class MessageManager {
|
|
|
1036
1293
|
default:
|
|
1037
1294
|
throw new InputError(`Invalid chat action: ${action}`);
|
|
1038
1295
|
}
|
|
1039
|
-
await
|
|
1296
|
+
await this.#c.invoke({ _: "messages.setTyping", peer: await this.#c.getInputPeer(chatId), action: action_, top_msg_id: params?.messageThreadId }, { businessConnectionId: params?.businessConnectionId });
|
|
1040
1297
|
}
|
|
1041
1298
|
async searchMessages(params) {
|
|
1042
|
-
|
|
1043
|
-
const peer = params?.chatId === undefined ? { _: "inputPeerEmpty" } : await
|
|
1299
|
+
this.#c.storage.assertUser("searchMessages");
|
|
1300
|
+
const peer = params?.chatId === undefined ? { _: "inputPeerEmpty" } : await this.#c.getInputPeer(params.chatId);
|
|
1044
1301
|
const query = params?.query ?? "";
|
|
1045
|
-
const result = await
|
|
1302
|
+
const result = await this.#c.invoke({
|
|
1046
1303
|
_: "messages.search",
|
|
1047
1304
|
peer,
|
|
1048
1305
|
q: query,
|
|
@@ -1055,7 +1312,7 @@ export class MessageManager {
|
|
|
1055
1312
|
min_date: 0,
|
|
1056
1313
|
min_id: 0,
|
|
1057
1314
|
offset_id: params?.offset ? params.offset : 0,
|
|
1058
|
-
from_id: params?.from ? await
|
|
1315
|
+
from_id: params?.from ? await this.#c.getInputPeer(params.from) : undefined,
|
|
1059
1316
|
});
|
|
1060
1317
|
if (!("messages" in result)) {
|
|
1061
1318
|
unreachable();
|
|
@@ -1069,25 +1326,25 @@ export class MessageManager {
|
|
|
1069
1326
|
return { messages, count };
|
|
1070
1327
|
}
|
|
1071
1328
|
async blockUser(userId) {
|
|
1072
|
-
|
|
1073
|
-
const id = await
|
|
1074
|
-
await
|
|
1329
|
+
this.#c.storage.assertUser("blockUser");
|
|
1330
|
+
const id = await this.#c.getInputPeer(userId);
|
|
1331
|
+
await this.#c.invoke({ _: "contacts.block", id });
|
|
1075
1332
|
}
|
|
1076
1333
|
async unblockUser(userId) {
|
|
1077
|
-
|
|
1078
|
-
const id = await
|
|
1079
|
-
await
|
|
1334
|
+
this.#c.storage.assertUser("unblockUser");
|
|
1335
|
+
const id = await this.#c.getInputPeer(userId);
|
|
1336
|
+
await this.#c.invoke({ _: "contacts.unblock", id });
|
|
1080
1337
|
}
|
|
1081
1338
|
async setChatStickerSet(chatId, setName) {
|
|
1082
|
-
const channel = await
|
|
1083
|
-
await
|
|
1339
|
+
const channel = await this.#c.getInputChannel(chatId);
|
|
1340
|
+
await this.#c.invoke({ _: "channels.setStickers", channel, stickerset: { _: "inputStickerSetShortName", short_name: setName } });
|
|
1084
1341
|
}
|
|
1085
1342
|
async deleteChatStickerSet(chatId) {
|
|
1086
|
-
const channel = await
|
|
1087
|
-
await
|
|
1343
|
+
const channel = await this.#c.getInputChannel(chatId);
|
|
1344
|
+
await this.#c.invoke({ _: "channels.setStickers", channel, stickerset: { _: "inputStickerSetEmpty" } });
|
|
1088
1345
|
}
|
|
1089
1346
|
async stopPoll(chatId, messageId, params) {
|
|
1090
|
-
|
|
1347
|
+
this.#checkParams(params);
|
|
1091
1348
|
const message = await this.getMessage(chatId, messageId);
|
|
1092
1349
|
if (!message) {
|
|
1093
1350
|
throw new InputError("Message not found.");
|
|
@@ -1098,26 +1355,26 @@ export class MessageManager {
|
|
|
1098
1355
|
if (message.poll.isClosed) {
|
|
1099
1356
|
throw new InputError("Poll is already stopped.");
|
|
1100
1357
|
}
|
|
1101
|
-
const result = await
|
|
1358
|
+
const result = await this.#c.invoke({
|
|
1102
1359
|
_: "messages.editMessage",
|
|
1103
|
-
peer: await
|
|
1360
|
+
peer: await this.#c.getInputPeer(chatId),
|
|
1104
1361
|
id: messageId,
|
|
1105
1362
|
media: { _: "inputMediaPoll", poll: { _: "poll", id: BigInt(message.poll.id), closed: true, question: { _: "textWithEntities", text: "", entities: [] }, answers: [] } },
|
|
1106
|
-
reply_markup: await
|
|
1363
|
+
reply_markup: await this.#constructReplyMarkup(params),
|
|
1107
1364
|
}, { businessConnectionId: params?.businessConnectionId });
|
|
1108
1365
|
const message_ = (await this.updatesToMessages(chatId, result))[0];
|
|
1109
1366
|
return assertMessageType(message_, "poll").poll;
|
|
1110
1367
|
}
|
|
1111
1368
|
async editMessageLiveLocation(chatId, messageId, latitude, longitude, params) {
|
|
1112
|
-
|
|
1369
|
+
this.#checkParams(params);
|
|
1113
1370
|
const message = await this.getMessage(chatId, messageId);
|
|
1114
1371
|
if (message && "location" in message && message.location.livePeriod) {
|
|
1115
|
-
const result = await
|
|
1372
|
+
const result = await this.#c.invoke({
|
|
1116
1373
|
_: "messages.editMessage",
|
|
1117
|
-
peer: await
|
|
1374
|
+
peer: await this.#c.getInputPeer(chatId),
|
|
1118
1375
|
id: messageId,
|
|
1119
1376
|
media: { _: "inputMediaGeoLive", geo_point: { _: "inputGeoPoint", lat: latitude, long: longitude, accuracy_radius: params?.horizontalAccuracy }, heading: params?.heading, proximity_notification_radius: params?.proximityAlertRadius },
|
|
1120
|
-
reply_markup: await
|
|
1377
|
+
reply_markup: await this.#constructReplyMarkup(params),
|
|
1121
1378
|
}, { businessConnectionId: params?.businessConnectionId });
|
|
1122
1379
|
const message = (await this.updatesToMessages(chatId, result))[0];
|
|
1123
1380
|
return assertMessageType(message, "location");
|
|
@@ -1125,19 +1382,19 @@ export class MessageManager {
|
|
|
1125
1382
|
unreachable();
|
|
1126
1383
|
}
|
|
1127
1384
|
async editInlineMessageLiveLocation(inlineMessageId, latitude, longitude, params) {
|
|
1128
|
-
|
|
1129
|
-
|
|
1385
|
+
this.#checkParams(params);
|
|
1386
|
+
this.#c.storage.assertBot("editInlineMessageLiveLocation");
|
|
1130
1387
|
const id = await deserializeInlineMessageId(inlineMessageId);
|
|
1131
|
-
await
|
|
1388
|
+
await this.#c.invoke({
|
|
1132
1389
|
_: "messages.editInlineBotMessage",
|
|
1133
1390
|
id,
|
|
1134
1391
|
media: { _: "inputMediaGeoLive", geo_point: { _: "inputGeoPoint", lat: latitude, long: longitude, accuracy_radius: params?.horizontalAccuracy }, heading: params?.heading, proximity_notification_radius: params?.proximityAlertRadius },
|
|
1135
|
-
reply_markup: await
|
|
1392
|
+
reply_markup: await this.#constructReplyMarkup(params),
|
|
1136
1393
|
}, { dc: getDc(id.dc_id) });
|
|
1137
1394
|
}
|
|
1138
1395
|
async sendInvoice(chatId, title, description, payload, currency, prices, params) {
|
|
1139
|
-
|
|
1140
|
-
|
|
1396
|
+
this.#c.storage.assertBot("sendInvoice");
|
|
1397
|
+
this.#checkParams(params);
|
|
1141
1398
|
if (title.length < 1) {
|
|
1142
1399
|
throw new InputError("Invoice title cannot be empty.");
|
|
1143
1400
|
}
|
|
@@ -1164,7 +1421,7 @@ export class MessageManager {
|
|
|
1164
1421
|
phone_to_provider: params?.sendPhoneNumberToProvider || undefined,
|
|
1165
1422
|
flexible: params?.isFlexible || undefined,
|
|
1166
1423
|
};
|
|
1167
|
-
const message = await
|
|
1424
|
+
const message = await this.#sendMedia(chatId, {
|
|
1168
1425
|
_: "inputMediaInvoice",
|
|
1169
1426
|
title,
|
|
1170
1427
|
description,
|
|
@@ -1190,7 +1447,7 @@ export class MessageManager {
|
|
|
1190
1447
|
return assertMessageType(message, "invoice");
|
|
1191
1448
|
}
|
|
1192
1449
|
async sendMediaGroup(chatId, media, params) {
|
|
1193
|
-
|
|
1450
|
+
this.#checkParams(params);
|
|
1194
1451
|
{
|
|
1195
1452
|
if (!Array.isArray(media) || !media.length) {
|
|
1196
1453
|
throw new InputError("Media group must not be empty.");
|
|
@@ -1216,25 +1473,25 @@ export class MessageManager {
|
|
|
1216
1473
|
for (const v of media) {
|
|
1217
1474
|
const randomId = getRandomId();
|
|
1218
1475
|
const [message, entities] = v.caption !== undefined ? this.parseText(v.caption, { entities: v.captionEntities, parseMode: v.parseMode }) : ["", []];
|
|
1219
|
-
multiMedia.push({ _: "inputSingleMedia", message, entities, random_id: randomId, media: await
|
|
1476
|
+
multiMedia.push({ _: "inputSingleMedia", message, entities, random_id: randomId, media: await this.#resolveInputMedia(v) });
|
|
1220
1477
|
}
|
|
1221
|
-
const peer = await
|
|
1478
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
1222
1479
|
for (const [i, media_] of multiMedia.entries()) {
|
|
1223
1480
|
if (Api.is("inputMediaUploadedPhoto", media_.media)) {
|
|
1224
|
-
const result = Api.as("messageMediaPhoto", await
|
|
1481
|
+
const result = Api.as("messageMediaPhoto", await this.#c.invoke({ _: "messages.uploadMedia", media: media_.media, peer }));
|
|
1225
1482
|
const photo = Api.as("photo", result.photo);
|
|
1226
1483
|
multiMedia[i] = { ...media_, media: { _: "inputMediaPhoto", id: { ...photo, _: "inputPhoto" } } };
|
|
1227
1484
|
}
|
|
1228
1485
|
else if (Api.is("inputMediaUploadedDocument", media_.media)) {
|
|
1229
|
-
const result = Api.as("messageMediaDocument", await
|
|
1486
|
+
const result = Api.as("messageMediaDocument", await this.#c.invoke({ _: "messages.uploadMedia", media: media_.media, peer }));
|
|
1230
1487
|
const document = Api.as("document", result.document);
|
|
1231
1488
|
multiMedia[i] = { ...media_, media: { _: "inputMediaDocument", id: { ...document, _: "inputDocument" } } };
|
|
1232
1489
|
}
|
|
1233
1490
|
}
|
|
1234
1491
|
const silent = params?.isSilent ? true : undefined;
|
|
1235
1492
|
const noforwards = params?.isContentProtected ? true : undefined;
|
|
1236
|
-
const sendAs = params?.sendAs ? await
|
|
1237
|
-
const result = await
|
|
1493
|
+
const sendAs = params?.sendAs ? await this.#c.getInputPeer(params.sendAs) : undefined;
|
|
1494
|
+
const result = await this.#c.invoke({
|
|
1238
1495
|
_: "messages.sendMultiMedia",
|
|
1239
1496
|
peer,
|
|
1240
1497
|
multi_media: multiMedia,
|
|
@@ -1242,19 +1499,19 @@ export class MessageManager {
|
|
|
1242
1499
|
noforwards,
|
|
1243
1500
|
silent,
|
|
1244
1501
|
send_as: sendAs,
|
|
1245
|
-
reply_to: await
|
|
1502
|
+
reply_to: await this.#constructReplyTo(params),
|
|
1246
1503
|
allow_paid_floodskip: params?.isPaidBroadcast ? true : undefined,
|
|
1247
1504
|
});
|
|
1248
1505
|
return await this.updatesToMessages(chatId, result);
|
|
1249
1506
|
}
|
|
1250
1507
|
async readMessages(chatId, untilMessageId) {
|
|
1251
|
-
|
|
1252
|
-
const peer = await
|
|
1508
|
+
this.#c.storage.assertUser("readMessages");
|
|
1509
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
1253
1510
|
const max_id = untilMessageId;
|
|
1254
|
-
await
|
|
1511
|
+
await this.#c.invoke({ _: "messages.readHistory", peer, max_id });
|
|
1255
1512
|
}
|
|
1256
1513
|
async startBot(botId, params) {
|
|
1257
|
-
|
|
1514
|
+
this.#c.storage.assertUser("startBot");
|
|
1258
1515
|
const start_param = params?.deeplink?.trim() || "";
|
|
1259
1516
|
if (params?.chatId !== undefined && !start_param) {
|
|
1260
1517
|
throw new InputError("deeplink cannot be unspecified while chatId is specified.");
|
|
@@ -1262,13 +1519,13 @@ export class MessageManager {
|
|
|
1262
1519
|
if (!params?.deeplink) {
|
|
1263
1520
|
return await this.sendMessage(botId, "/start");
|
|
1264
1521
|
}
|
|
1265
|
-
const bot = await
|
|
1266
|
-
const peer = await
|
|
1267
|
-
const result = await
|
|
1522
|
+
const bot = await this.#c.getInputUser(botId);
|
|
1523
|
+
const peer = await this.#c.getInputPeer(params?.chatId || botId);
|
|
1524
|
+
const result = await this.#c.invoke({ _: "messages.startBot", bot, peer, random_id: getRandomId(), start_param });
|
|
1268
1525
|
return (await this.updatesToMessages(botId, result))[0];
|
|
1269
1526
|
}
|
|
1270
1527
|
async transcribeVoice(chatId, messageId) {
|
|
1271
|
-
|
|
1528
|
+
this.#c.storage.assertUser("transcribeVoice");
|
|
1272
1529
|
const message = await this.getMessage(chatId, messageId);
|
|
1273
1530
|
if (message === null) {
|
|
1274
1531
|
throw new InputError("Message not found.");
|
|
@@ -1276,16 +1533,32 @@ export class MessageManager {
|
|
|
1276
1533
|
if (!isMessageType(message, "voice")) {
|
|
1277
1534
|
throw new InputError("Message not voice.");
|
|
1278
1535
|
}
|
|
1279
|
-
const cachedTranscription = await
|
|
1536
|
+
const cachedTranscription = await this.#getCachedVoiceTranscription(message);
|
|
1280
1537
|
if (cachedTranscription) {
|
|
1281
1538
|
return cachedTranscription;
|
|
1282
1539
|
}
|
|
1283
|
-
const peer = await
|
|
1284
|
-
const result = await
|
|
1285
|
-
return await
|
|
1540
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
1541
|
+
const result = await this.#c.invoke({ _: "messages.transcribeAudio", peer, msg_id: messageId });
|
|
1542
|
+
return await this.#cacheVoiceTranscription(message, constructVoiceTranscription(result));
|
|
1543
|
+
}
|
|
1544
|
+
async #getCachedVoiceTranscription(message) {
|
|
1545
|
+
const reference = await this.#c.messageStorage.getVoiceTranscriptionReference(message.chat.id, message.id, fromUnixTimestamp(message.editDate ?? message.date));
|
|
1546
|
+
if (!reference) {
|
|
1547
|
+
return null;
|
|
1548
|
+
}
|
|
1549
|
+
const voiceTranscription = await this.#c.messageStorage.getVoiceTranscription(reference);
|
|
1550
|
+
if (!voiceTranscription || !voiceTranscription.isCompleted) {
|
|
1551
|
+
return null;
|
|
1552
|
+
}
|
|
1553
|
+
return voiceTranscription;
|
|
1554
|
+
}
|
|
1555
|
+
async #cacheVoiceTranscription(message, voiceTranscription) {
|
|
1556
|
+
await this.#c.messageStorage.setVoiceTranscriptionReference(message.chat.id, message.id, fromUnixTimestamp(message.editDate ?? message.date), BigInt(voiceTranscription.id));
|
|
1557
|
+
await this.#c.messageStorage.setVoiceTranscription(voiceTranscription);
|
|
1558
|
+
return voiceTranscription;
|
|
1286
1559
|
}
|
|
1287
1560
|
async resolveMessageLink(link) {
|
|
1288
|
-
const parseResult =
|
|
1561
|
+
const parseResult = MessageManager.parseMessageLink(link);
|
|
1289
1562
|
if (parseResult === null) {
|
|
1290
1563
|
throw new InputError("Invalid messsage link.");
|
|
1291
1564
|
}
|
|
@@ -1400,24 +1673,24 @@ export class MessageManager {
|
|
|
1400
1673
|
throw new InputError("Invalid sticker set name or link.");
|
|
1401
1674
|
}
|
|
1402
1675
|
}
|
|
1403
|
-
const result = await
|
|
1676
|
+
const result = await this.#c.invoke({ _: "messages.getStickerSet", hash: 0, stickerset: { _: "inputStickerSetShortName", short_name: name } });
|
|
1404
1677
|
return constructStickerSet(result);
|
|
1405
1678
|
}
|
|
1406
1679
|
async openMiniApp(botId, chatId, params) {
|
|
1407
|
-
|
|
1680
|
+
this.#c.storage.assertUser("openMiniApp");
|
|
1408
1681
|
const from_bot_menu = params?.isFromMenu ? true : undefined;
|
|
1409
1682
|
const silent = params?.isSilent ? true : undefined;
|
|
1410
1683
|
const compact = params?.mode === "compact" ? true : undefined;
|
|
1411
1684
|
const fullscreen = params?.mode === "fullscreen" ? true : undefined;
|
|
1412
|
-
const peer = await
|
|
1413
|
-
const bot = await
|
|
1685
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
1686
|
+
const bot = await this.#c.getInputUser(botId);
|
|
1414
1687
|
const url = params?.url;
|
|
1415
1688
|
const start_param = params?.startParameter;
|
|
1416
1689
|
const theme_params = params?.themeParameters ? { _: "dataJSON", data: params.themeParameters } : undefined;
|
|
1417
|
-
const platform =
|
|
1418
|
-
const reply_to = await
|
|
1419
|
-
const send_as = params?.sendAs ? await
|
|
1420
|
-
const result = await
|
|
1690
|
+
const platform = this.#c.langPack ?? "";
|
|
1691
|
+
const reply_to = await this.#constructReplyTo(params);
|
|
1692
|
+
const send_as = params?.sendAs ? await this.#c.getInputPeer(params.sendAs) : undefined;
|
|
1693
|
+
const result = await this.#c.invoke({
|
|
1421
1694
|
_: "messages.requestWebView",
|
|
1422
1695
|
from_bot_menu,
|
|
1423
1696
|
silent,
|
|
@@ -1435,8 +1708,8 @@ export class MessageManager {
|
|
|
1435
1708
|
return constructMiniAppInfo(result);
|
|
1436
1709
|
}
|
|
1437
1710
|
async getSavedMessages(chatId, params) {
|
|
1438
|
-
|
|
1439
|
-
const peer = await
|
|
1711
|
+
this.#c.storage.assertUser("getSavedMessages");
|
|
1712
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
1440
1713
|
const limit = getLimit(params?.limit);
|
|
1441
1714
|
let offsetId = params?.offsetId ?? 0;
|
|
1442
1715
|
if (offsetId < 0) {
|
|
@@ -1446,7 +1719,7 @@ export class MessageManager {
|
|
|
1446
1719
|
if (offsetDate < 0) {
|
|
1447
1720
|
offsetDate = 0;
|
|
1448
1721
|
}
|
|
1449
|
-
const result = await
|
|
1722
|
+
const result = await this.#c.invoke({
|
|
1450
1723
|
_: "messages.getSavedHistory",
|
|
1451
1724
|
peer,
|
|
1452
1725
|
limit,
|
|
@@ -1479,9 +1752,9 @@ export class MessageManager {
|
|
|
1479
1752
|
}
|
|
1480
1753
|
let offsetPeer = { _: "inputPeerEmpty" };
|
|
1481
1754
|
if (params?.offsetChatId !== undefined) {
|
|
1482
|
-
offsetPeer = await
|
|
1755
|
+
offsetPeer = await this.#c.getInputPeer(params.offsetChatId);
|
|
1483
1756
|
}
|
|
1484
|
-
const result = await
|
|
1757
|
+
const result = await this.#c.invoke({
|
|
1485
1758
|
_: "messages.getSavedDialogs",
|
|
1486
1759
|
hash: 0n,
|
|
1487
1760
|
limit,
|
|
@@ -1490,16 +1763,16 @@ export class MessageManager {
|
|
|
1490
1763
|
offset_peer: offsetPeer,
|
|
1491
1764
|
exclude_pinned: params?.excludePinned || undefined,
|
|
1492
1765
|
});
|
|
1493
|
-
return constructSavedChats(result,
|
|
1766
|
+
return constructSavedChats(result, this.#c.getPeer, this.getMessage.bind(this), this.#c.fileManager.getStickerSetName.bind(this.#c.fileManager));
|
|
1494
1767
|
}
|
|
1495
1768
|
async getMessageReactions(chatId, messageId, params) {
|
|
1496
|
-
|
|
1497
|
-
const peer = await
|
|
1769
|
+
this.#c.storage.assertUser("getMessageReactions");
|
|
1770
|
+
const peer = await this.#c.getInputPeer(chatId);
|
|
1498
1771
|
const id = messageId;
|
|
1499
1772
|
const reactions = params?.reaction ? reactionToTlObject(params.reaction) : undefined;
|
|
1500
1773
|
const offset = params?.offset;
|
|
1501
1774
|
const limit = getLimit(params?.limit);
|
|
1502
|
-
const messageReactionsList = await
|
|
1775
|
+
const messageReactionsList = await this.#c.invoke({
|
|
1503
1776
|
_: "messages.getMessageReactionsList",
|
|
1504
1777
|
peer,
|
|
1505
1778
|
id,
|
|
@@ -1510,281 +1783,3 @@ export class MessageManager {
|
|
|
1510
1783
|
return constructMessageReactionList(messageReactionsList);
|
|
1511
1784
|
}
|
|
1512
1785
|
}
|
|
1513
|
-
_a = MessageManager, _MessageManager_c = new WeakMap(), _MessageManager_LresolveFileId = new WeakMap(), _MessageManager_instances = new WeakSet(), _MessageManager_checkParams = function _MessageManager_checkParams(params) {
|
|
1514
|
-
if (params && "replyMarkup" in params && params.replyMarkup !== undefined) {
|
|
1515
|
-
__classPrivateFieldGet(this, _MessageManager_c, "f").storage.assertBot("replyMarkup");
|
|
1516
|
-
}
|
|
1517
|
-
if (params && "businessConnectionId" in params && params.businessConnectionId !== undefined) {
|
|
1518
|
-
__classPrivateFieldGet(this, _MessageManager_c, "f").storage.assertBot("businessConnectionId");
|
|
1519
|
-
}
|
|
1520
|
-
if (params && "sendAs" in params && params.sendAs !== undefined) {
|
|
1521
|
-
__classPrivateFieldGet(this, _MessageManager_c, "f").storage.assertUser("sendAs");
|
|
1522
|
-
}
|
|
1523
|
-
if (params && "sendAt" in params && params.sendAt !== undefined) {
|
|
1524
|
-
__classPrivateFieldGet(this, _MessageManager_c, "f").storage.assertUser("businessConsendAtnectionId");
|
|
1525
|
-
}
|
|
1526
|
-
}, _MessageManager_constructReplyMarkup = async function _MessageManager_constructReplyMarkup(params) {
|
|
1527
|
-
if (params?.replyMarkup) {
|
|
1528
|
-
__classPrivateFieldGet(this, _MessageManager_c, "f").storage.assertBot("replyMarkup");
|
|
1529
|
-
return await replyMarkupToTlObject(params.replyMarkup, this.usernameResolver.bind(this));
|
|
1530
|
-
}
|
|
1531
|
-
}, _MessageManager_resolveSendAs = async function _MessageManager_resolveSendAs(params) {
|
|
1532
|
-
const sendAs = params?.sendAs;
|
|
1533
|
-
if (sendAs !== undefined) {
|
|
1534
|
-
__classPrivateFieldGet(this, _MessageManager_c, "f").storage.assertUser("sendAs");
|
|
1535
|
-
return sendAs ? await __classPrivateFieldGet(this, _MessageManager_c, "f").getInputPeer(sendAs) : undefined;
|
|
1536
|
-
}
|
|
1537
|
-
}, _MessageManager_constructReplyTo = async function _MessageManager_constructReplyTo(params) {
|
|
1538
|
-
const topMsgId = params?.messageThreadId;
|
|
1539
|
-
if (!params?.replyTo) {
|
|
1540
|
-
if (topMsgId) {
|
|
1541
|
-
return { _: "inputReplyToMessage", reply_to_msg_id: topMsgId, top_msg_id: topMsgId };
|
|
1542
|
-
}
|
|
1543
|
-
else {
|
|
1544
|
-
return undefined;
|
|
1545
|
-
}
|
|
1546
|
-
}
|
|
1547
|
-
if ("messageId" in params.replyTo) {
|
|
1548
|
-
return { _: "inputReplyToMessage", reply_to_msg_id: params.replyTo.messageId, top_msg_id: topMsgId, quote_text: params.replyTo.quote?.text, quote_entities: await Promise.all(params.replyTo.quote?.entities.map((v) => messageEntityToTlObject(v, __classPrivateFieldGet(this, _MessageManager_c, "f").getPeer)) ?? []), quote_offset: params.replyTo.quote?.offset };
|
|
1549
|
-
}
|
|
1550
|
-
else {
|
|
1551
|
-
return { _: "inputReplyToStory", peer: await __classPrivateFieldGet(this, _MessageManager_c, "f").getInputPeer(params.replyTo.chatId), story_id: params.replyTo.storyId };
|
|
1552
|
-
}
|
|
1553
|
-
}, _MessageManager_isM4a = function _MessageManager_isM4a(firstPart) {
|
|
1554
|
-
return firstPart.length >= 10 && startsWith(firstPart.subarray(4), new Uint8Array([0x66, 0x74, 0x79, 0x70, 0x4D, 0x34]));
|
|
1555
|
-
}, _MessageManager_sendDocumentInner = async function _MessageManager_sendDocumentInner(chatId, document, params, fileType, otherAttribs, urlSupported = true, expectedMimeTypes, createName) {
|
|
1556
|
-
let media = null;
|
|
1557
|
-
const spoiler = params?.hasSpoiler ? true : undefined;
|
|
1558
|
-
const ttl_seconds = params && "selfDestruct" in params && typeof params.selfDestruct !== undefined ? selfDestructOptionToInt(params.selfDestruct) : undefined;
|
|
1559
|
-
if (typeof document === "string") {
|
|
1560
|
-
const fileId = this.resolveFileId(document, fileType);
|
|
1561
|
-
if (fileId !== null) {
|
|
1562
|
-
media = { _: "inputMediaDocument", id: { ...fileId, _: "inputDocument" }, spoiler, query: otherAttribs.find((v) => Api.is("documentAttributeSticker", v))?.alt || undefined, ttl_seconds };
|
|
1563
|
-
}
|
|
1564
|
-
}
|
|
1565
|
-
if (media === null) {
|
|
1566
|
-
if (typeof document === "string" && isHttpUrl(document)) {
|
|
1567
|
-
if (!urlSupported) {
|
|
1568
|
-
throw new InputError("URL not supported.");
|
|
1569
|
-
}
|
|
1570
|
-
media = { _: "inputMediaDocumentExternal", url: document, spoiler, ttl_seconds };
|
|
1571
|
-
}
|
|
1572
|
-
else {
|
|
1573
|
-
let mimeType;
|
|
1574
|
-
const file = await __classPrivateFieldGet(this, _MessageManager_c, "f").fileManager.upload(document, params, (name, firstPart) => {
|
|
1575
|
-
if (!params?.fileName && firstPart && createName) {
|
|
1576
|
-
name = createName(firstPart);
|
|
1577
|
-
}
|
|
1578
|
-
mimeType = params?.mimeType ?? contentType(name.split(".").slice(-1)[0]);
|
|
1579
|
-
if (name.endsWith(".tgs") && fileType === FileType.Document) {
|
|
1580
|
-
name += "-";
|
|
1581
|
-
}
|
|
1582
|
-
return name;
|
|
1583
|
-
});
|
|
1584
|
-
mimeType ??= FALLBACK_MIME_TYPE;
|
|
1585
|
-
if (mimeType && expectedMimeTypes && !expectedMimeTypes.includes(mimeType)) {
|
|
1586
|
-
unreachable();
|
|
1587
|
-
}
|
|
1588
|
-
if (Api.is("inputFileStoryDocument", file)) {
|
|
1589
|
-
unreachable();
|
|
1590
|
-
}
|
|
1591
|
-
let thumb = undefined;
|
|
1592
|
-
if (params?.thumbnail) {
|
|
1593
|
-
thumb = await __classPrivateFieldGet(this, _MessageManager_c, "f").fileManager.upload(params.thumbnail, { chunkSize: params?.chunkSize, signal: params?.signal });
|
|
1594
|
-
}
|
|
1595
|
-
media = { _: "inputMediaUploadedDocument", file, thumb, spoiler, attributes: [{ _: "documentAttributeFilename", file_name: file.name }, ...otherAttribs], mime_type: mimeType, force_file: fileType === FileType.Document ? true : undefined, ttl_seconds };
|
|
1596
|
-
}
|
|
1597
|
-
}
|
|
1598
|
-
const message = await __classPrivateFieldGet(this, _MessageManager_instances, "m", _MessageManager_sendMedia).call(this, chatId, media, params);
|
|
1599
|
-
return message;
|
|
1600
|
-
}, _MessageManager_sendMedia = async function _MessageManager_sendMedia(chatId, media, params) {
|
|
1601
|
-
if (params?.starCount !== undefined) {
|
|
1602
|
-
if (params.starCount <= 0) {
|
|
1603
|
-
throw new InputError("starCount cannot be zero or negative");
|
|
1604
|
-
}
|
|
1605
|
-
media = { _: "inputMediaPaidMedia", stars_amount: BigInt(params.starCount), extended_media: [media] };
|
|
1606
|
-
}
|
|
1607
|
-
const peer = await __classPrivateFieldGet(this, _MessageManager_c, "f").getInputPeer(chatId);
|
|
1608
|
-
const randomId = getRandomId();
|
|
1609
|
-
const silent = params?.isSilent ? true : undefined;
|
|
1610
|
-
const noforwards = params?.isContentProtected ? true : undefined;
|
|
1611
|
-
const sendAs = params?.sendAs ? await __classPrivateFieldGet(this, _MessageManager_c, "f").getInputPeer(params.sendAs) : undefined;
|
|
1612
|
-
const replyMarkup = await __classPrivateFieldGet(this, _MessageManager_instances, "m", _MessageManager_constructReplyMarkup).call(this, params);
|
|
1613
|
-
const caption_ = params?.caption;
|
|
1614
|
-
const parseResult = caption_ !== undefined ? this.parseText(caption_, { parseMode: params?.parseMode, entities: params?.captionEntities }) : undefined;
|
|
1615
|
-
const caption = parseResult === undefined ? undefined : parseResult[0];
|
|
1616
|
-
const captionEntities = parseResult === undefined ? undefined : parseResult[1];
|
|
1617
|
-
const result = await __classPrivateFieldGet(this, _MessageManager_c, "f").invoke({
|
|
1618
|
-
_: "messages.sendMedia",
|
|
1619
|
-
peer,
|
|
1620
|
-
random_id: randomId,
|
|
1621
|
-
silent,
|
|
1622
|
-
noforwards,
|
|
1623
|
-
reply_markup: replyMarkup,
|
|
1624
|
-
reply_to: await __classPrivateFieldGet(this, _MessageManager_instances, "m", _MessageManager_constructReplyTo).call(this, params),
|
|
1625
|
-
send_as: sendAs,
|
|
1626
|
-
media,
|
|
1627
|
-
message: caption ?? "",
|
|
1628
|
-
entities: captionEntities,
|
|
1629
|
-
effect: params?.effectId ? BigInt(params.effectId) : undefined,
|
|
1630
|
-
schedule_date: params?.sendAt,
|
|
1631
|
-
allow_paid_floodskip: params?.isPaidBroadcast ? true : undefined,
|
|
1632
|
-
}, { businessConnectionId: params?.businessConnectionId });
|
|
1633
|
-
return (await this.updatesToMessages(chatId, result, params?.businessConnectionId))[0];
|
|
1634
|
-
}, _MessageManager_editInlineMessageTextInner = async function _MessageManager_editInlineMessageTextInner(inlineMessageId, text, params, allowEmpty = true) {
|
|
1635
|
-
__classPrivateFieldGet(this, _MessageManager_instances, "m", _MessageManager_checkParams).call(this, params);
|
|
1636
|
-
const [message, entities] = this.parseText(text, params);
|
|
1637
|
-
if (!allowEmpty && !message) {
|
|
1638
|
-
throw new InputError("Message text cannot be empty.");
|
|
1639
|
-
}
|
|
1640
|
-
const id = await deserializeInlineMessageId(inlineMessageId);
|
|
1641
|
-
if (params?.linkPreview && params.linkPreview.type !== "input") {
|
|
1642
|
-
throw new InputError("Expected link preview of type input.");
|
|
1643
|
-
}
|
|
1644
|
-
const noWebpage = params?.linkPreview && params.linkPreview.type === "input" && params.linkPreview.isDisabled ? true : undefined;
|
|
1645
|
-
const invertMedia = params?.linkPreview?.isAboveText ? true : undefined;
|
|
1646
|
-
let media = undefined;
|
|
1647
|
-
if (!noWebpage && params?.linkPreview?.url) {
|
|
1648
|
-
media = { _: "inputMediaWebPage", url: params.linkPreview.url, force_large_media: params.linkPreview.mediaSize === "large" ? true : undefined, force_small_media: params.linkPreview.mediaSize === "small" ? true : undefined, optional: message.length ? undefined : true };
|
|
1649
|
-
}
|
|
1650
|
-
await __classPrivateFieldGet(this, _MessageManager_c, "f").invoke({
|
|
1651
|
-
_: "messages.editInlineBotMessage",
|
|
1652
|
-
id,
|
|
1653
|
-
entities,
|
|
1654
|
-
message,
|
|
1655
|
-
media,
|
|
1656
|
-
no_webpage: noWebpage,
|
|
1657
|
-
invert_media: invertMedia,
|
|
1658
|
-
reply_markup: await __classPrivateFieldGet(this, _MessageManager_instances, "m", _MessageManager_constructReplyMarkup).call(this, params),
|
|
1659
|
-
}, { dc: getDc(id.dc_id) });
|
|
1660
|
-
}, _MessageManager_resolveInputMediaInner = async function _MessageManager_resolveInputMediaInner(document, media, fileType, otherAttribs) {
|
|
1661
|
-
let media_ = null;
|
|
1662
|
-
const spoiler = "hasSpoiler" in media && media.hasSpoiler ? true : undefined;
|
|
1663
|
-
if (typeof document === "string") {
|
|
1664
|
-
const fileId = this.resolveFileId(document, fileType);
|
|
1665
|
-
if (fileId !== null) {
|
|
1666
|
-
media_ = { _: "inputMediaDocument", id: { ...fileId, _: "inputDocument" }, spoiler, query: otherAttribs.find((v) => Api.is("documentAttributeSticker", v))?.alt || undefined };
|
|
1667
|
-
}
|
|
1668
|
-
}
|
|
1669
|
-
if (media_ === null) {
|
|
1670
|
-
if (typeof document === "string" && isHttpUrl(document)) {
|
|
1671
|
-
media_ = { _: "inputMediaDocumentExternal", url: document, spoiler };
|
|
1672
|
-
}
|
|
1673
|
-
else {
|
|
1674
|
-
let mimeType;
|
|
1675
|
-
const file = await __classPrivateFieldGet(this, _MessageManager_c, "f").fileManager.upload(document, media, (name) => {
|
|
1676
|
-
mimeType = media?.mimeType ?? contentType(name.split(".").slice(-1)[0]) ?? FALLBACK_MIME_TYPE;
|
|
1677
|
-
if (name.endsWith(".tgs") && fileType === FileType.Document) {
|
|
1678
|
-
name += "-";
|
|
1679
|
-
}
|
|
1680
|
-
return name;
|
|
1681
|
-
});
|
|
1682
|
-
if (Api.is("inputFileStoryDocument", file)) {
|
|
1683
|
-
unreachable();
|
|
1684
|
-
}
|
|
1685
|
-
let thumb = undefined;
|
|
1686
|
-
if ("thumbnail" in media && media.thumbnail) {
|
|
1687
|
-
thumb = await __classPrivateFieldGet(this, _MessageManager_c, "f").fileManager.upload(media.thumbnail, { chunkSize: media?.chunkSize, signal: media?.signal });
|
|
1688
|
-
}
|
|
1689
|
-
media_ = { _: "inputMediaUploadedDocument", file, thumb, spoiler, attributes: [{ _: "documentAttributeFilename", file_name: file.name }, ...otherAttribs], mime_type: mimeType, force_file: fileType === FileType.Document ? true : undefined };
|
|
1690
|
-
}
|
|
1691
|
-
}
|
|
1692
|
-
return media_;
|
|
1693
|
-
}, _MessageManager_resolveInputMedia = async function _MessageManager_resolveInputMedia(media) {
|
|
1694
|
-
if ("animation" in media) {
|
|
1695
|
-
return await __classPrivateFieldGet(this, _MessageManager_instances, "m", _MessageManager_resolveInputMediaInner).call(this, media.animation, media, FileType.Animation, [
|
|
1696
|
-
{ _: "documentAttributeAnimated" },
|
|
1697
|
-
{ _: "documentAttributeVideo", supports_streaming: true, w: media?.width ?? 0, h: media?.height ?? 0, duration: media?.duration ?? 0 },
|
|
1698
|
-
]);
|
|
1699
|
-
}
|
|
1700
|
-
else if ("audio" in media) {
|
|
1701
|
-
return await __classPrivateFieldGet(this, _MessageManager_instances, "m", _MessageManager_resolveInputMediaInner).call(this, media.audio, media, FileType.Audio, [
|
|
1702
|
-
{ _: "documentAttributeAudio", duration: media?.duration ?? 0, performer: media?.performer, title: media?.title },
|
|
1703
|
-
]);
|
|
1704
|
-
}
|
|
1705
|
-
else if ("document" in media) {
|
|
1706
|
-
return await __classPrivateFieldGet(this, _MessageManager_instances, "m", _MessageManager_resolveInputMediaInner).call(this, media.document, media, FileType.Document, []);
|
|
1707
|
-
}
|
|
1708
|
-
else if ("photo" in media) {
|
|
1709
|
-
let media_ = null;
|
|
1710
|
-
const spoiler = media.hasSpoiler ? true : undefined;
|
|
1711
|
-
const ttl_seconds = "selfDestruct" in media && media.selfDestruct !== undefined ? selfDestructOptionToInt(media.selfDestruct) : undefined;
|
|
1712
|
-
if (typeof media.photo === "string") {
|
|
1713
|
-
const fileId = this.resolveFileId(media.photo, [FileType.Photo, FileType.ProfilePhoto]);
|
|
1714
|
-
if (fileId !== null) {
|
|
1715
|
-
media_ = { _: "inputMediaPhoto", id: { ...fileId, _: "inputPhoto" }, spoiler, ttl_seconds };
|
|
1716
|
-
}
|
|
1717
|
-
}
|
|
1718
|
-
if (media_ === null) {
|
|
1719
|
-
if (typeof media.photo === "string" && isHttpUrl(media.photo)) {
|
|
1720
|
-
media_ = { _: "inputMediaPhotoExternal", url: media.photo, spoiler };
|
|
1721
|
-
}
|
|
1722
|
-
else {
|
|
1723
|
-
const file = await __classPrivateFieldGet(this, _MessageManager_c, "f").fileManager.upload(media.photo, media, null, false);
|
|
1724
|
-
media_ = { _: "inputMediaUploadedPhoto", file, spoiler, ttl_seconds };
|
|
1725
|
-
}
|
|
1726
|
-
}
|
|
1727
|
-
return media_;
|
|
1728
|
-
}
|
|
1729
|
-
else if ("video" in media) {
|
|
1730
|
-
const ttl_seconds = "selfDestruct" in media && media.selfDestruct !== undefined ? selfDestructOptionToInt(media.selfDestruct) : undefined;
|
|
1731
|
-
const media_ = await __classPrivateFieldGet(this, _MessageManager_instances, "m", _MessageManager_resolveInputMediaInner).call(this, media.video, media, FileType.Video, [
|
|
1732
|
-
{ _: "documentAttributeVideo", supports_streaming: media?.supportsStreaming ? true : undefined, w: media?.width ?? 0, h: media?.height ?? 0, duration: media?.duration ?? 0 },
|
|
1733
|
-
]);
|
|
1734
|
-
media_.ttl_seconds = ttl_seconds;
|
|
1735
|
-
return media_;
|
|
1736
|
-
}
|
|
1737
|
-
else {
|
|
1738
|
-
unreachable();
|
|
1739
|
-
}
|
|
1740
|
-
}, _MessageManager_resolveInputMediaUpload = async function _MessageManager_resolveInputMediaUpload(media, businessConnectionId) {
|
|
1741
|
-
const inputMedia = await __classPrivateFieldGet(this, _MessageManager_instances, "m", _MessageManager_resolveInputMedia).call(this, media);
|
|
1742
|
-
if (Api.is("inputMediaUploadedPhoto", inputMedia) || Api.is("inputMediaUploadedDocument", inputMedia)) {
|
|
1743
|
-
const messageMedia = await __classPrivateFieldGet(this, _MessageManager_c, "f").invoke({
|
|
1744
|
-
_: "messages.uploadMedia",
|
|
1745
|
-
peer: { _: "inputPeerSelf" },
|
|
1746
|
-
media: inputMedia,
|
|
1747
|
-
business_connection_id: businessConnectionId,
|
|
1748
|
-
});
|
|
1749
|
-
if (("photo" in messageMedia) && Api.is("photo", messageMedia.photo)) {
|
|
1750
|
-
return {
|
|
1751
|
-
_: "inputMediaPhoto",
|
|
1752
|
-
id: {
|
|
1753
|
-
_: "inputPhoto",
|
|
1754
|
-
id: messageMedia.photo.id,
|
|
1755
|
-
access_hash: messageMedia.photo.access_hash,
|
|
1756
|
-
file_reference: messageMedia.photo.file_reference,
|
|
1757
|
-
},
|
|
1758
|
-
spoiler: "hasSpoiler" in media && media.hasSpoiler ? true : undefined,
|
|
1759
|
-
};
|
|
1760
|
-
}
|
|
1761
|
-
else if ("document" in messageMedia && Api.is("document", messageMedia.document)) {
|
|
1762
|
-
return {
|
|
1763
|
-
_: "inputMediaDocument",
|
|
1764
|
-
id: { _: "inputDocument", id: messageMedia.document.id, access_hash: messageMedia.document.access_hash, file_reference: messageMedia.document.file_reference },
|
|
1765
|
-
spoiler: "hasSpoiler" in media && media.hasSpoiler ? true : undefined,
|
|
1766
|
-
};
|
|
1767
|
-
}
|
|
1768
|
-
else {
|
|
1769
|
-
unreachable();
|
|
1770
|
-
}
|
|
1771
|
-
}
|
|
1772
|
-
return inputMedia;
|
|
1773
|
-
}, _MessageManager_sendReaction = async function _MessageManager_sendReaction(chatId, messageId, reactions, params) {
|
|
1774
|
-
await __classPrivateFieldGet(this, _MessageManager_c, "f").invoke({ _: "messages.sendReaction", peer: await __classPrivateFieldGet(this, _MessageManager_c, "f").getInputPeer(chatId), msg_id: checkMessageId(messageId), reaction: reactions.map((v) => reactionToTlObject(v)), big: params?.isBig ? true : undefined, add_to_recent: params?.addToRecents ? true : undefined });
|
|
1775
|
-
}, _MessageManager_getCachedVoiceTranscription = async function _MessageManager_getCachedVoiceTranscription(message) {
|
|
1776
|
-
const reference = await __classPrivateFieldGet(this, _MessageManager_c, "f").messageStorage.getVoiceTranscriptionReference(message.chat.id, message.id, fromUnixTimestamp(message.editDate ?? message.date));
|
|
1777
|
-
if (!reference) {
|
|
1778
|
-
return null;
|
|
1779
|
-
}
|
|
1780
|
-
const voiceTranscription = await __classPrivateFieldGet(this, _MessageManager_c, "f").messageStorage.getVoiceTranscription(reference);
|
|
1781
|
-
if (!voiceTranscription || !voiceTranscription.isCompleted) {
|
|
1782
|
-
return null;
|
|
1783
|
-
}
|
|
1784
|
-
return voiceTranscription;
|
|
1785
|
-
}, _MessageManager_cacheVoiceTranscription = async function _MessageManager_cacheVoiceTranscription(message, voiceTranscription) {
|
|
1786
|
-
await __classPrivateFieldGet(this, _MessageManager_c, "f").messageStorage.setVoiceTranscriptionReference(message.chat.id, message.id, fromUnixTimestamp(message.editDate ?? message.date), BigInt(voiceTranscription.id));
|
|
1787
|
-
await __classPrivateFieldGet(this, _MessageManager_c, "f").messageStorage.setVoiceTranscription(voiceTranscription);
|
|
1788
|
-
return voiceTranscription;
|
|
1789
|
-
};
|
|
1790
|
-
_MessageManager_CAPTIONABLE_MESSAGE_TYPES = { value: ["photo", "document", "video", "animation", "voice", "audio", "video"] };
|