@mtkruto/node 0.0.978 → 0.0.980
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/esm/client/3_client.d.ts +104 -17
- package/esm/client/3_client.js +187 -138
- package/esm/constants.d.ts +1 -1
- package/esm/constants.js +1 -1
- package/package.json +1 -1
- package/script/client/3_client.d.ts +104 -17
- package/script/client/3_client.js +187 -138
- package/script/constants.d.ts +1 -1
- package/script/constants.js +1 -1
package/esm/client/3_client.d.ts
CHANGED
|
@@ -68,12 +68,69 @@ export interface ClientParams {
|
|
|
68
68
|
*/
|
|
69
69
|
autoStart?: boolean;
|
|
70
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* A chat identifier as provided by MTKruto or a string starting with a @ that is followed by a username.
|
|
73
|
+
*/
|
|
74
|
+
export type ChatID = number | string;
|
|
75
|
+
export interface SendMessagesParams {
|
|
76
|
+
/**
|
|
77
|
+
* The parse mode to use. If not provided, the default parse mode will be used.
|
|
78
|
+
*/
|
|
79
|
+
parseMode?: ParseMode;
|
|
80
|
+
/**
|
|
81
|
+
* The message's entities.
|
|
82
|
+
*/
|
|
83
|
+
entities?: MessageEntity[];
|
|
84
|
+
/**
|
|
85
|
+
* Whether to disable web page previews in the message that is to be sent.
|
|
86
|
+
*/
|
|
87
|
+
disableWebPagePreview?: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Whether to send the message in a silent way without making a sound on the recipients' clients.
|
|
90
|
+
*/
|
|
91
|
+
disableNotification?: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Whether to protect the contents of the message from copying and forwarding.
|
|
94
|
+
*/
|
|
95
|
+
protectContent?: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* The identifier of a message to reply to.
|
|
98
|
+
*/
|
|
99
|
+
replyToMessageId?: number;
|
|
100
|
+
/**
|
|
101
|
+
* The identifier of a thread to send the message to.
|
|
102
|
+
*/
|
|
103
|
+
messageThreadId?: number;
|
|
104
|
+
/**
|
|
105
|
+
* The identifier of the chat to send the message on behalf of.
|
|
106
|
+
*/
|
|
107
|
+
sendAs?: ChatID;
|
|
108
|
+
/**
|
|
109
|
+
* The reply markup of the message.
|
|
110
|
+
*/
|
|
111
|
+
replyMarkup?: InlineKeyboardMarkup | ReplyKeyboardMarkup | ReplyKeyboardRemove | ForceReply;
|
|
112
|
+
}
|
|
71
113
|
export interface ForwardMessagesParams {
|
|
72
114
|
messageThreadId?: number;
|
|
115
|
+
/**
|
|
116
|
+
* Whether to forward the message in a silent way without making a sound on the recipients' clients.
|
|
117
|
+
*/
|
|
73
118
|
disableNotification?: boolean;
|
|
119
|
+
/**
|
|
120
|
+
* Whether to protect the contents of the forwarded message from copying and forwarding.
|
|
121
|
+
*/
|
|
74
122
|
protectContent?: boolean;
|
|
75
|
-
|
|
123
|
+
/**
|
|
124
|
+
* The identifier of the chat to forward the message on behalf of.
|
|
125
|
+
*/
|
|
126
|
+
sendAs?: ChatID;
|
|
127
|
+
/**
|
|
128
|
+
* Whether to not include the original sender of the message that is going to be forwarded.
|
|
129
|
+
*/
|
|
76
130
|
dropSenderName?: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Whether to not include the original caption of the message that is going to be forwarded.
|
|
133
|
+
*/
|
|
77
134
|
dropCaption?: boolean;
|
|
78
135
|
}
|
|
79
136
|
export declare class Client extends ClientAbstract {
|
|
@@ -178,23 +235,53 @@ export declare class Client extends ClientAbstract {
|
|
|
178
235
|
[getEntity](peer: types.PeerChannel): Promise<types.Channel | null>;
|
|
179
236
|
processResult(result: ReadObject): Promise<void>;
|
|
180
237
|
private updatesToMessages;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
238
|
+
/**
|
|
239
|
+
* Send a text message.
|
|
240
|
+
*
|
|
241
|
+
* @param chatId The chat to send the message to.
|
|
242
|
+
* @param text The message's text.
|
|
243
|
+
*/
|
|
244
|
+
sendMessage(chatId: ChatID, text: string, params?: SendMessagesParams): Promise<Message>;
|
|
245
|
+
/**
|
|
246
|
+
* Retrieve multiple messages.
|
|
247
|
+
*
|
|
248
|
+
* @param chatId The identifier of the chat to retrieve the messages from.
|
|
249
|
+
* @param messageIds The identifiers of the messages to retrieve.
|
|
250
|
+
*/
|
|
251
|
+
getMessages(chatId_: ChatID, messageIds: number[]): Promise<Omit<Message, "replyToMessage">[]>;
|
|
252
|
+
/**
|
|
253
|
+
* Retrieve a single message.
|
|
254
|
+
*
|
|
255
|
+
* @param chatId The identifier of the chat to retrieve the message from.
|
|
256
|
+
* @param messageId The identifier of the message to retrieve.
|
|
257
|
+
*/
|
|
258
|
+
getMessage(chatId: ChatID, messageId: number): Promise<Omit<Message, "replyToMessage"> | null>;
|
|
194
259
|
private downloadInner;
|
|
195
|
-
|
|
260
|
+
/**
|
|
261
|
+
* Download a file.
|
|
262
|
+
*
|
|
263
|
+
* @param fileId The identifier of the file to download.
|
|
264
|
+
*/
|
|
265
|
+
download(fileId: string): Promise<AsyncGenerator<Uint8Array, void, unknown>>;
|
|
196
266
|
[getStickerSetName](inputStickerSet: types.InputStickerSetID, hash?: number): Promise<string>;
|
|
197
|
-
|
|
198
|
-
|
|
267
|
+
/**
|
|
268
|
+
* Forward multiple messages.
|
|
269
|
+
*
|
|
270
|
+
* @param from The identifier of the chat to forward the messages from.
|
|
271
|
+
* @param to The identifier of the chat to forward the messages to.
|
|
272
|
+
* @param messageIds The identifiers of the messages to forward.
|
|
273
|
+
*/
|
|
274
|
+
forwardMessages(from: ChatID, to: ChatID, messageIds: number[], params?: ForwardMessagesParams): Promise<Message[]>;
|
|
275
|
+
/**
|
|
276
|
+
* Forward a single message.
|
|
277
|
+
*
|
|
278
|
+
* @param from The identifier of the chat to forward the message from.
|
|
279
|
+
* @param to The identifier of the chat to forward the message to.
|
|
280
|
+
* @param messageId The identifier of the message to forward.
|
|
281
|
+
*/
|
|
282
|
+
forwardMessage(from: ChatID, to: ChatID, messageId: number, params?: ForwardMessagesParams): Promise<Message>;
|
|
283
|
+
/**
|
|
284
|
+
* Get information on the currently authorized user.
|
|
285
|
+
*/
|
|
199
286
|
getMe(): Promise<import("../types/1_user.js").User>;
|
|
200
287
|
}
|
package/esm/client/3_client.js
CHANGED
|
@@ -327,52 +327,23 @@ export class Client extends ClientAbstract {
|
|
|
327
327
|
}
|
|
328
328
|
}
|
|
329
329
|
dAuth("authorizing with %s", typeof params === "string" ? "bot token" : params instanceof types.AuthExportedAuthorization ? "exported authorization" : "AuthorizeUserParams");
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
params = params;
|
|
346
|
-
if (err instanceof types.RPCError && err.errorMessage == "SESSION_PASSWORD_NEEDED") {
|
|
347
|
-
while (true) {
|
|
348
|
-
const ap = await this.invoke(new functions.AccountGetPassword());
|
|
349
|
-
if (ap.currentAlgo instanceof types.PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow) {
|
|
350
|
-
try {
|
|
351
|
-
const password = typeof params.password === "string" ? params.password : await params.password(ap.hint ?? null);
|
|
352
|
-
const input = await checkPassword(password, ap);
|
|
353
|
-
await this.invoke(new functions.AuthCheckPassword({ password: input }));
|
|
354
|
-
await this.storage.setAccountType("user");
|
|
355
|
-
dAuth("authorized as user");
|
|
356
|
-
break;
|
|
357
|
-
}
|
|
358
|
-
catch (err) {
|
|
359
|
-
if (err instanceof types.RPCError && err.errorMessage == "PASSWORD_HASH_INVALID") {
|
|
360
|
-
continue;
|
|
361
|
-
}
|
|
362
|
-
else {
|
|
363
|
-
throw err;
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
else {
|
|
368
|
-
throw new Error(`Handling ${ap.currentAlgo?.constructor.name} not implemented`);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
else {
|
|
373
|
-
throw err;
|
|
374
|
-
}
|
|
330
|
+
const initConnection = async () => {
|
|
331
|
+
await this.invoke(new functions.InitConnection({
|
|
332
|
+
apiId: this.apiId,
|
|
333
|
+
appVersion: this.appVersion,
|
|
334
|
+
deviceModel: this.deviceModel,
|
|
335
|
+
langCode: this.langCode,
|
|
336
|
+
langPack: this.langPack,
|
|
337
|
+
query: new functions.InvokeWithLayer({
|
|
338
|
+
layer: LAYER,
|
|
339
|
+
query: new functions.HelpGetConfig(),
|
|
340
|
+
}),
|
|
341
|
+
systemLangCode: this.systemLangCode,
|
|
342
|
+
systemVersion: this.systemVersion,
|
|
343
|
+
}));
|
|
344
|
+
d("connection inited");
|
|
375
345
|
};
|
|
346
|
+
await initConnection();
|
|
376
347
|
try {
|
|
377
348
|
await this.fetchState("authorize");
|
|
378
349
|
d("already authorized");
|
|
@@ -383,102 +354,129 @@ export class Client extends ClientAbstract {
|
|
|
383
354
|
throw err;
|
|
384
355
|
}
|
|
385
356
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
phoneNumber = typeof params.phone === "string" ? params.phone : await params.phone();
|
|
401
|
-
const sentCode = await this.invoke(new functions.AuthSendCode({
|
|
402
|
-
apiId: this.apiId,
|
|
403
|
-
apiHash: this.apiHash,
|
|
404
|
-
phoneNumber,
|
|
405
|
-
settings: new types.CodeSettings(),
|
|
406
|
-
}));
|
|
407
|
-
dAuth("verification code sent");
|
|
408
|
-
if (sentCode instanceof types.AuthSentCode) {
|
|
409
|
-
while (true) {
|
|
410
|
-
const phoneCode = typeof params.code === "string" ? params.code : await params.code();
|
|
411
|
-
try {
|
|
412
|
-
const auth = await this.invoke(new functions.AuthSignIn({ phoneNumber, phoneCode, phoneCodeHash: sentCode.phoneCodeHash }));
|
|
413
|
-
if (auth instanceof types.AuthAuthorizationSignUpRequired) {
|
|
414
|
-
throw new Error("Sign up not supported");
|
|
415
|
-
}
|
|
416
|
-
else {
|
|
417
|
-
signedIn = true;
|
|
418
|
-
await this.storage.setAccountType("user");
|
|
419
|
-
dAuth("authorized as user");
|
|
420
|
-
break;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
catch (err) {
|
|
424
|
-
if (err instanceof types.RPCError && err.errorMessage == "PHONE_CODE_INVALID") {
|
|
425
|
-
continue;
|
|
426
|
-
}
|
|
427
|
-
else {
|
|
428
|
-
throw err;
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
else {
|
|
434
|
-
throw new Error(`Handling ${sentCode.constructor.name} not implemented`);
|
|
435
|
-
}
|
|
357
|
+
if (typeof params === "string") {
|
|
358
|
+
while (true) {
|
|
359
|
+
try {
|
|
360
|
+
await this.invoke(new functions.AuthImportBotAuthorization({ apiId: this.apiId, apiHash: this.apiHash, botAuthToken: params, flags: 0 }));
|
|
361
|
+
await this.storage.setAccountType("bot");
|
|
362
|
+
break;
|
|
363
|
+
}
|
|
364
|
+
catch (err) {
|
|
365
|
+
if (err instanceof types.RPCError) {
|
|
366
|
+
const match = err.errorMessage.match(/MIGRATE_(\d)$/);
|
|
367
|
+
if (match) {
|
|
368
|
+
await this[handleMigrationError](err);
|
|
369
|
+
await initConnection();
|
|
370
|
+
continue;
|
|
436
371
|
}
|
|
437
|
-
|
|
438
|
-
|
|
372
|
+
else {
|
|
373
|
+
throw err;
|
|
439
374
|
}
|
|
440
375
|
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
376
|
+
else {
|
|
377
|
+
throw err;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
dAuth("authorized as bot");
|
|
382
|
+
await this.fetchState("authorize");
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
if (params instanceof types.AuthExportedAuthorization) {
|
|
386
|
+
await this.invoke(new functions.AuthImportAuthorization({ id: params.id, bytes: params.bytes }));
|
|
387
|
+
dAuth("authorization imported");
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
let phone;
|
|
391
|
+
let sentCode;
|
|
392
|
+
while (true) {
|
|
393
|
+
try {
|
|
394
|
+
phone = typeof params.phone === "string" ? params.phone : await params.phone();
|
|
395
|
+
const sendCode = () => this.invoke(new functions.AuthSendCode({
|
|
396
|
+
phoneNumber: phone,
|
|
397
|
+
apiId: this.apiId,
|
|
398
|
+
apiHash: this.apiHash,
|
|
399
|
+
settings: new types.CodeSettings(),
|
|
400
|
+
})).then((v) => v[as](types.AuthSentCode));
|
|
401
|
+
try {
|
|
402
|
+
sentCode = await sendCode();
|
|
403
|
+
}
|
|
404
|
+
catch (err) {
|
|
405
|
+
if (err instanceof types.RPCError) {
|
|
406
|
+
const match = err.errorMessage.match(/MIGRATE_(\d)$/);
|
|
407
|
+
if (match) {
|
|
408
|
+
await this[handleMigrationError](err);
|
|
409
|
+
await initConnection();
|
|
410
|
+
sentCode = await sendCode();
|
|
444
411
|
}
|
|
445
412
|
else {
|
|
446
413
|
throw err;
|
|
447
414
|
}
|
|
448
415
|
}
|
|
416
|
+
else {
|
|
417
|
+
throw err;
|
|
418
|
+
}
|
|
449
419
|
}
|
|
420
|
+
break;
|
|
450
421
|
}
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
422
|
+
catch (err) {
|
|
423
|
+
if (err instanceof types.RPCError && err.errorMessage == "PHONE_NUMBER_INVALID") {
|
|
424
|
+
continue;
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
throw err;
|
|
428
|
+
}
|
|
455
429
|
}
|
|
456
430
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
431
|
+
dAuth("verification code sent");
|
|
432
|
+
let err;
|
|
433
|
+
while (true) {
|
|
434
|
+
const code = typeof params.code === "string" ? params.code : await params.code();
|
|
435
|
+
try {
|
|
436
|
+
await this.invoke(new functions.AuthSignIn({
|
|
437
|
+
phoneNumber: phone,
|
|
438
|
+
phoneCode: code,
|
|
439
|
+
phoneCodeHash: sentCode.phoneCodeHash,
|
|
440
|
+
}));
|
|
441
|
+
await this.storage.setAccountType("user");
|
|
442
|
+
dAuth("authorized as user");
|
|
443
|
+
await this.fetchState("authorize");
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
catch (err_) {
|
|
447
|
+
if (err_ instanceof types.RPCError && err_.errorMessage == "PHONE_CODE_INVALID") {
|
|
448
|
+
continue;
|
|
467
449
|
}
|
|
468
450
|
else {
|
|
469
|
-
|
|
451
|
+
err = err_;
|
|
452
|
+
break;
|
|
470
453
|
}
|
|
471
454
|
}
|
|
472
|
-
else {
|
|
473
|
-
throw err;
|
|
474
|
-
}
|
|
475
455
|
}
|
|
476
|
-
|
|
456
|
+
if (!(err instanceof types.RPCError && err.errorMessage == "SESSION_PASSWORD_NEEDED")) {
|
|
457
|
+
throw err;
|
|
458
|
+
}
|
|
459
|
+
while (true) {
|
|
460
|
+
const ap = await this.invoke(new functions.AccountGetPassword());
|
|
461
|
+
if (!(ap.currentAlgo instanceof types.PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow)) {
|
|
462
|
+
throw new Error(`Handling ${ap.currentAlgo?.constructor.name} not implemented`);
|
|
463
|
+
}
|
|
477
464
|
try {
|
|
465
|
+
const password = typeof params.password === "string" ? params.password : await params.password(ap.hint ?? null);
|
|
466
|
+
const input = await checkPassword(password, ap);
|
|
467
|
+
await this.invoke(new functions.AuthCheckPassword({ password: input }));
|
|
468
|
+
await this.storage.setAccountType("user");
|
|
469
|
+
dAuth("authorized as user");
|
|
478
470
|
await this.fetchState("authorize");
|
|
471
|
+
break;
|
|
479
472
|
}
|
|
480
|
-
catch (
|
|
481
|
-
|
|
473
|
+
catch (err) {
|
|
474
|
+
if (err instanceof types.RPCError && err.errorMessage == "PASSWORD_HASH_INVALID") {
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
else {
|
|
478
|
+
throw err;
|
|
479
|
+
}
|
|
482
480
|
}
|
|
483
481
|
}
|
|
484
482
|
}
|
|
@@ -487,6 +485,16 @@ export class Client extends ClientAbstract {
|
|
|
487
485
|
*/
|
|
488
486
|
async start(params) {
|
|
489
487
|
await this.connect();
|
|
488
|
+
try {
|
|
489
|
+
await this.fetchState("authorize");
|
|
490
|
+
d("already authorized");
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
catch (err) {
|
|
494
|
+
if (!(err instanceof types.RPCError) || err.errorMessage != "AUTH_KEY_UNREGISTERED") {
|
|
495
|
+
throw err;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
490
498
|
await this.authorize(params);
|
|
491
499
|
}
|
|
492
500
|
async receiveLoop() {
|
|
@@ -558,15 +566,16 @@ export class Client extends ClientAbstract {
|
|
|
558
566
|
this.promises.delete(message.body.msgId);
|
|
559
567
|
}
|
|
560
568
|
}
|
|
561
|
-
else if (message.body instanceof types.
|
|
569
|
+
else if (message.body instanceof types.TypeBadMsgNotification || message.body instanceof types.BadServerSalt) {
|
|
562
570
|
if (message.body instanceof types.BadServerSalt) {
|
|
571
|
+
d("server salt reassigned");
|
|
563
572
|
this.state.salt = message.body.newServerSalt;
|
|
564
573
|
}
|
|
565
|
-
const promise = this.promises.get(message.body.badMsgId);
|
|
566
|
-
if (promise) {
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
}
|
|
574
|
+
// const promise = this.promises.get(message.body.badMsgId);
|
|
575
|
+
// if (promise) {
|
|
576
|
+
// promise.resolve(message.body);
|
|
577
|
+
// this.promises.delete(message.body.badMsgId);
|
|
578
|
+
// }
|
|
570
579
|
}
|
|
571
580
|
this.toAcknowledge.add(message.id);
|
|
572
581
|
}
|
|
@@ -1138,6 +1147,12 @@ export class Client extends ClientAbstract {
|
|
|
1138
1147
|
}
|
|
1139
1148
|
return messages;
|
|
1140
1149
|
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Send a text message.
|
|
1152
|
+
*
|
|
1153
|
+
* @param chatId The chat to send the message to.
|
|
1154
|
+
* @param text The message's text.
|
|
1155
|
+
*/
|
|
1141
1156
|
async sendMessage(chatId, text, params) {
|
|
1142
1157
|
const entities_ = params?.entities ?? [];
|
|
1143
1158
|
const parseMode = params?.parseMode ?? this.parseMode;
|
|
@@ -1197,6 +1212,12 @@ export class Client extends ClientAbstract {
|
|
|
1197
1212
|
}));
|
|
1198
1213
|
return await this.updatesToMessages(chatId, result).then((v) => v[0]);
|
|
1199
1214
|
}
|
|
1215
|
+
/**
|
|
1216
|
+
* Retrieve multiple messages.
|
|
1217
|
+
*
|
|
1218
|
+
* @param chatId The identifier of the chat to retrieve the messages from.
|
|
1219
|
+
* @param messageIds The identifiers of the messages to retrieve.
|
|
1220
|
+
*/
|
|
1200
1221
|
async getMessages(chatId_, messageIds) {
|
|
1201
1222
|
const peer = await this.getInputPeer(chatId_);
|
|
1202
1223
|
let messages_ = new Array();
|
|
@@ -1232,6 +1253,12 @@ export class Client extends ClientAbstract {
|
|
|
1232
1253
|
}
|
|
1233
1254
|
return messages;
|
|
1234
1255
|
}
|
|
1256
|
+
/**
|
|
1257
|
+
* Retrieve a single message.
|
|
1258
|
+
*
|
|
1259
|
+
* @param chatId The identifier of the chat to retrieve the message from.
|
|
1260
|
+
* @param messageId The identifier of the message to retrieve.
|
|
1261
|
+
*/
|
|
1235
1262
|
async getMessage(chatId, messageId) {
|
|
1236
1263
|
const messages = await this.getMessages(chatId, [messageId]);
|
|
1237
1264
|
return messages[0] ?? null;
|
|
@@ -1275,24 +1302,29 @@ export class Client extends ClientAbstract {
|
|
|
1275
1302
|
}
|
|
1276
1303
|
}
|
|
1277
1304
|
}
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1305
|
+
/**
|
|
1306
|
+
* Download a file.
|
|
1307
|
+
*
|
|
1308
|
+
* @param fileId The identifier of the file to download.
|
|
1309
|
+
*/
|
|
1310
|
+
async download(fileId) {
|
|
1311
|
+
const fileId_ = FileID.decode(fileId);
|
|
1312
|
+
switch (fileId_.fileType) {
|
|
1281
1313
|
case FileType.ChatPhoto: {
|
|
1282
|
-
const big =
|
|
1283
|
-
const peer = await this.getInputPeer(
|
|
1284
|
-
const location = new types.InputPeerPhotoFileLocation({ big: big ? true : undefined, peer, photoId:
|
|
1314
|
+
const big = fileId_.params.thumbnailSource == ThumbnailSource.ChatPhotoBig;
|
|
1315
|
+
const peer = await this.getInputPeer(fileId_.params.chatId);
|
|
1316
|
+
const location = new types.InputPeerPhotoFileLocation({ big: big ? true : undefined, peer, photoId: fileId_.params.mediaId });
|
|
1285
1317
|
return this.downloadInner(location);
|
|
1286
1318
|
}
|
|
1287
1319
|
case FileType.Photo: {
|
|
1288
|
-
if (
|
|
1320
|
+
if (fileId_.params.mediaId == undefined || fileId_.params.accessHash == undefined || fileId_.params.fileReference == undefined || fileId_.params.thumbnailSize == undefined) {
|
|
1289
1321
|
UNREACHABLE();
|
|
1290
1322
|
}
|
|
1291
1323
|
const location = new types.InputPhotoFileLocation({
|
|
1292
|
-
id:
|
|
1293
|
-
accessHash:
|
|
1294
|
-
fileReference:
|
|
1295
|
-
thumbSize:
|
|
1324
|
+
id: fileId_.params.mediaId,
|
|
1325
|
+
accessHash: fileId_.params.accessHash,
|
|
1326
|
+
fileReference: fileId_.params.fileReference,
|
|
1327
|
+
thumbSize: fileId_.params.thumbnailSize,
|
|
1296
1328
|
});
|
|
1297
1329
|
return this.downloadInner(location);
|
|
1298
1330
|
}
|
|
@@ -1312,6 +1344,13 @@ export class Client extends ClientAbstract {
|
|
|
1312
1344
|
return name;
|
|
1313
1345
|
}
|
|
1314
1346
|
}
|
|
1347
|
+
/**
|
|
1348
|
+
* Forward multiple messages.
|
|
1349
|
+
*
|
|
1350
|
+
* @param from The identifier of the chat to forward the messages from.
|
|
1351
|
+
* @param to The identifier of the chat to forward the messages to.
|
|
1352
|
+
* @param messageIds The identifiers of the messages to forward.
|
|
1353
|
+
*/
|
|
1315
1354
|
async forwardMessages(from, to, messageIds, params) {
|
|
1316
1355
|
const result = await this.invoke(new functions.MessagesForwardMessages({
|
|
1317
1356
|
fromPeer: await this.getInputPeer(from),
|
|
@@ -1327,9 +1366,19 @@ export class Client extends ClientAbstract {
|
|
|
1327
1366
|
}));
|
|
1328
1367
|
return await this.updatesToMessages(to, result);
|
|
1329
1368
|
}
|
|
1369
|
+
/**
|
|
1370
|
+
* Forward a single message.
|
|
1371
|
+
*
|
|
1372
|
+
* @param from The identifier of the chat to forward the message from.
|
|
1373
|
+
* @param to The identifier of the chat to forward the message to.
|
|
1374
|
+
* @param messageId The identifier of the message to forward.
|
|
1375
|
+
*/
|
|
1330
1376
|
async forwardMessage(from, to, messageId, params) {
|
|
1331
1377
|
return await this.forwardMessages(from, to, [messageId], params).then((v) => v[0]);
|
|
1332
1378
|
}
|
|
1379
|
+
/**
|
|
1380
|
+
* Get information on the currently authorized user.
|
|
1381
|
+
*/
|
|
1333
1382
|
async getMe() {
|
|
1334
1383
|
const users = await this.invoke(new functions.UsersGetUsers({ id: [new types.InputUserSelf()] }));
|
|
1335
1384
|
if (users.length < 1) {
|
package/esm/constants.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export declare const PUBLIC_KEYS: PublicKeys;
|
|
|
5
5
|
export declare const VECTOR_CONSTRUCTOR = 481674261;
|
|
6
6
|
export declare const INITIAL_DC: DC;
|
|
7
7
|
export declare const LAYER = 160;
|
|
8
|
-
export declare const APP_VERSION = "MTKruto 0.0.
|
|
8
|
+
export declare const APP_VERSION = "MTKruto 0.0.980";
|
|
9
9
|
export declare const DEVICE_MODEL: string;
|
|
10
10
|
export declare const LANG_CODE: string;
|
|
11
11
|
export declare const LANG_PACK = "";
|
package/esm/constants.js
CHANGED
|
@@ -54,7 +54,7 @@ export const PUBLIC_KEYS = Object.freeze([
|
|
|
54
54
|
export const VECTOR_CONSTRUCTOR = 0x1CB5C415;
|
|
55
55
|
export const INITIAL_DC = "2-test";
|
|
56
56
|
export const LAYER = 160;
|
|
57
|
-
export const APP_VERSION = "MTKruto 0.0.
|
|
57
|
+
export const APP_VERSION = "MTKruto 0.0.980";
|
|
58
58
|
// @ts-ignore: lib
|
|
59
59
|
export const DEVICE_MODEL = typeof dntShim.Deno === "undefined" ? typeof navigator === "undefined" ? typeof process === "undefined" ? "Unknown" : process.platform + "-" + process.arch : navigator.userAgent.split(" ")[0] : dntShim.Deno.build.os + "-" + dntShim.Deno.build.arch;
|
|
60
60
|
export const LANG_CODE = typeof navigator === "undefined" ? "en" : navigator.language.split("-")[0];
|
package/package.json
CHANGED
|
@@ -68,12 +68,69 @@ export interface ClientParams {
|
|
|
68
68
|
*/
|
|
69
69
|
autoStart?: boolean;
|
|
70
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* A chat identifier as provided by MTKruto or a string starting with a @ that is followed by a username.
|
|
73
|
+
*/
|
|
74
|
+
export type ChatID = number | string;
|
|
75
|
+
export interface SendMessagesParams {
|
|
76
|
+
/**
|
|
77
|
+
* The parse mode to use. If not provided, the default parse mode will be used.
|
|
78
|
+
*/
|
|
79
|
+
parseMode?: ParseMode;
|
|
80
|
+
/**
|
|
81
|
+
* The message's entities.
|
|
82
|
+
*/
|
|
83
|
+
entities?: MessageEntity[];
|
|
84
|
+
/**
|
|
85
|
+
* Whether to disable web page previews in the message that is to be sent.
|
|
86
|
+
*/
|
|
87
|
+
disableWebPagePreview?: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Whether to send the message in a silent way without making a sound on the recipients' clients.
|
|
90
|
+
*/
|
|
91
|
+
disableNotification?: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Whether to protect the contents of the message from copying and forwarding.
|
|
94
|
+
*/
|
|
95
|
+
protectContent?: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* The identifier of a message to reply to.
|
|
98
|
+
*/
|
|
99
|
+
replyToMessageId?: number;
|
|
100
|
+
/**
|
|
101
|
+
* The identifier of a thread to send the message to.
|
|
102
|
+
*/
|
|
103
|
+
messageThreadId?: number;
|
|
104
|
+
/**
|
|
105
|
+
* The identifier of the chat to send the message on behalf of.
|
|
106
|
+
*/
|
|
107
|
+
sendAs?: ChatID;
|
|
108
|
+
/**
|
|
109
|
+
* The reply markup of the message.
|
|
110
|
+
*/
|
|
111
|
+
replyMarkup?: InlineKeyboardMarkup | ReplyKeyboardMarkup | ReplyKeyboardRemove | ForceReply;
|
|
112
|
+
}
|
|
71
113
|
export interface ForwardMessagesParams {
|
|
72
114
|
messageThreadId?: number;
|
|
115
|
+
/**
|
|
116
|
+
* Whether to forward the message in a silent way without making a sound on the recipients' clients.
|
|
117
|
+
*/
|
|
73
118
|
disableNotification?: boolean;
|
|
119
|
+
/**
|
|
120
|
+
* Whether to protect the contents of the forwarded message from copying and forwarding.
|
|
121
|
+
*/
|
|
74
122
|
protectContent?: boolean;
|
|
75
|
-
|
|
123
|
+
/**
|
|
124
|
+
* The identifier of the chat to forward the message on behalf of.
|
|
125
|
+
*/
|
|
126
|
+
sendAs?: ChatID;
|
|
127
|
+
/**
|
|
128
|
+
* Whether to not include the original sender of the message that is going to be forwarded.
|
|
129
|
+
*/
|
|
76
130
|
dropSenderName?: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Whether to not include the original caption of the message that is going to be forwarded.
|
|
133
|
+
*/
|
|
77
134
|
dropCaption?: boolean;
|
|
78
135
|
}
|
|
79
136
|
export declare class Client extends ClientAbstract {
|
|
@@ -178,23 +235,53 @@ export declare class Client extends ClientAbstract {
|
|
|
178
235
|
[getEntity](peer: types.PeerChannel): Promise<types.Channel | null>;
|
|
179
236
|
processResult(result: ReadObject): Promise<void>;
|
|
180
237
|
private updatesToMessages;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
238
|
+
/**
|
|
239
|
+
* Send a text message.
|
|
240
|
+
*
|
|
241
|
+
* @param chatId The chat to send the message to.
|
|
242
|
+
* @param text The message's text.
|
|
243
|
+
*/
|
|
244
|
+
sendMessage(chatId: ChatID, text: string, params?: SendMessagesParams): Promise<Message>;
|
|
245
|
+
/**
|
|
246
|
+
* Retrieve multiple messages.
|
|
247
|
+
*
|
|
248
|
+
* @param chatId The identifier of the chat to retrieve the messages from.
|
|
249
|
+
* @param messageIds The identifiers of the messages to retrieve.
|
|
250
|
+
*/
|
|
251
|
+
getMessages(chatId_: ChatID, messageIds: number[]): Promise<Omit<Message, "replyToMessage">[]>;
|
|
252
|
+
/**
|
|
253
|
+
* Retrieve a single message.
|
|
254
|
+
*
|
|
255
|
+
* @param chatId The identifier of the chat to retrieve the message from.
|
|
256
|
+
* @param messageId The identifier of the message to retrieve.
|
|
257
|
+
*/
|
|
258
|
+
getMessage(chatId: ChatID, messageId: number): Promise<Omit<Message, "replyToMessage"> | null>;
|
|
194
259
|
private downloadInner;
|
|
195
|
-
|
|
260
|
+
/**
|
|
261
|
+
* Download a file.
|
|
262
|
+
*
|
|
263
|
+
* @param fileId The identifier of the file to download.
|
|
264
|
+
*/
|
|
265
|
+
download(fileId: string): Promise<AsyncGenerator<Uint8Array, void, unknown>>;
|
|
196
266
|
[getStickerSetName](inputStickerSet: types.InputStickerSetID, hash?: number): Promise<string>;
|
|
197
|
-
|
|
198
|
-
|
|
267
|
+
/**
|
|
268
|
+
* Forward multiple messages.
|
|
269
|
+
*
|
|
270
|
+
* @param from The identifier of the chat to forward the messages from.
|
|
271
|
+
* @param to The identifier of the chat to forward the messages to.
|
|
272
|
+
* @param messageIds The identifiers of the messages to forward.
|
|
273
|
+
*/
|
|
274
|
+
forwardMessages(from: ChatID, to: ChatID, messageIds: number[], params?: ForwardMessagesParams): Promise<Message[]>;
|
|
275
|
+
/**
|
|
276
|
+
* Forward a single message.
|
|
277
|
+
*
|
|
278
|
+
* @param from The identifier of the chat to forward the message from.
|
|
279
|
+
* @param to The identifier of the chat to forward the message to.
|
|
280
|
+
* @param messageId The identifier of the message to forward.
|
|
281
|
+
*/
|
|
282
|
+
forwardMessage(from: ChatID, to: ChatID, messageId: number, params?: ForwardMessagesParams): Promise<Message>;
|
|
283
|
+
/**
|
|
284
|
+
* Get information on the currently authorized user.
|
|
285
|
+
*/
|
|
199
286
|
getMe(): Promise<import("../types/1_user.js").User>;
|
|
200
287
|
}
|
|
@@ -353,52 +353,23 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
|
|
|
353
353
|
}
|
|
354
354
|
}
|
|
355
355
|
dAuth("authorizing with %s", typeof params === "string" ? "bot token" : params instanceof types.AuthExportedAuthorization ? "exported authorization" : "AuthorizeUserParams");
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
params = params;
|
|
372
|
-
if (err instanceof types.RPCError && err.errorMessage == "SESSION_PASSWORD_NEEDED") {
|
|
373
|
-
while (true) {
|
|
374
|
-
const ap = await this.invoke(new functions.AccountGetPassword());
|
|
375
|
-
if (ap.currentAlgo instanceof types.PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow) {
|
|
376
|
-
try {
|
|
377
|
-
const password = typeof params.password === "string" ? params.password : await params.password(ap.hint ?? null);
|
|
378
|
-
const input = await (0, _0_password_js_1.checkPassword)(password, ap);
|
|
379
|
-
await this.invoke(new functions.AuthCheckPassword({ password: input }));
|
|
380
|
-
await this.storage.setAccountType("user");
|
|
381
|
-
dAuth("authorized as user");
|
|
382
|
-
break;
|
|
383
|
-
}
|
|
384
|
-
catch (err) {
|
|
385
|
-
if (err instanceof types.RPCError && err.errorMessage == "PASSWORD_HASH_INVALID") {
|
|
386
|
-
continue;
|
|
387
|
-
}
|
|
388
|
-
else {
|
|
389
|
-
throw err;
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
else {
|
|
394
|
-
throw new Error(`Handling ${ap.currentAlgo?.constructor.name} not implemented`);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
else {
|
|
399
|
-
throw err;
|
|
400
|
-
}
|
|
356
|
+
const initConnection = async () => {
|
|
357
|
+
await this.invoke(new functions.InitConnection({
|
|
358
|
+
apiId: this.apiId,
|
|
359
|
+
appVersion: this.appVersion,
|
|
360
|
+
deviceModel: this.deviceModel,
|
|
361
|
+
langCode: this.langCode,
|
|
362
|
+
langPack: this.langPack,
|
|
363
|
+
query: new functions.InvokeWithLayer({
|
|
364
|
+
layer: constants_js_1.LAYER,
|
|
365
|
+
query: new functions.HelpGetConfig(),
|
|
366
|
+
}),
|
|
367
|
+
systemLangCode: this.systemLangCode,
|
|
368
|
+
systemVersion: this.systemVersion,
|
|
369
|
+
}));
|
|
370
|
+
d("connection inited");
|
|
401
371
|
};
|
|
372
|
+
await initConnection();
|
|
402
373
|
try {
|
|
403
374
|
await this.fetchState("authorize");
|
|
404
375
|
d("already authorized");
|
|
@@ -409,102 +380,129 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
|
|
|
409
380
|
throw err;
|
|
410
381
|
}
|
|
411
382
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
phoneNumber = typeof params.phone === "string" ? params.phone : await params.phone();
|
|
427
|
-
const sentCode = await this.invoke(new functions.AuthSendCode({
|
|
428
|
-
apiId: this.apiId,
|
|
429
|
-
apiHash: this.apiHash,
|
|
430
|
-
phoneNumber,
|
|
431
|
-
settings: new types.CodeSettings(),
|
|
432
|
-
}));
|
|
433
|
-
dAuth("verification code sent");
|
|
434
|
-
if (sentCode instanceof types.AuthSentCode) {
|
|
435
|
-
while (true) {
|
|
436
|
-
const phoneCode = typeof params.code === "string" ? params.code : await params.code();
|
|
437
|
-
try {
|
|
438
|
-
const auth = await this.invoke(new functions.AuthSignIn({ phoneNumber, phoneCode, phoneCodeHash: sentCode.phoneCodeHash }));
|
|
439
|
-
if (auth instanceof types.AuthAuthorizationSignUpRequired) {
|
|
440
|
-
throw new Error("Sign up not supported");
|
|
441
|
-
}
|
|
442
|
-
else {
|
|
443
|
-
signedIn = true;
|
|
444
|
-
await this.storage.setAccountType("user");
|
|
445
|
-
dAuth("authorized as user");
|
|
446
|
-
break;
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
catch (err) {
|
|
450
|
-
if (err instanceof types.RPCError && err.errorMessage == "PHONE_CODE_INVALID") {
|
|
451
|
-
continue;
|
|
452
|
-
}
|
|
453
|
-
else {
|
|
454
|
-
throw err;
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
else {
|
|
460
|
-
throw new Error(`Handling ${sentCode.constructor.name} not implemented`);
|
|
461
|
-
}
|
|
383
|
+
if (typeof params === "string") {
|
|
384
|
+
while (true) {
|
|
385
|
+
try {
|
|
386
|
+
await this.invoke(new functions.AuthImportBotAuthorization({ apiId: this.apiId, apiHash: this.apiHash, botAuthToken: params, flags: 0 }));
|
|
387
|
+
await this.storage.setAccountType("bot");
|
|
388
|
+
break;
|
|
389
|
+
}
|
|
390
|
+
catch (err) {
|
|
391
|
+
if (err instanceof types.RPCError) {
|
|
392
|
+
const match = err.errorMessage.match(/MIGRATE_(\d)$/);
|
|
393
|
+
if (match) {
|
|
394
|
+
await this[exports.handleMigrationError](err);
|
|
395
|
+
await initConnection();
|
|
396
|
+
continue;
|
|
462
397
|
}
|
|
463
|
-
|
|
464
|
-
|
|
398
|
+
else {
|
|
399
|
+
throw err;
|
|
465
400
|
}
|
|
466
401
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
402
|
+
else {
|
|
403
|
+
throw err;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
dAuth("authorized as bot");
|
|
408
|
+
await this.fetchState("authorize");
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
if (params instanceof types.AuthExportedAuthorization) {
|
|
412
|
+
await this.invoke(new functions.AuthImportAuthorization({ id: params.id, bytes: params.bytes }));
|
|
413
|
+
dAuth("authorization imported");
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
let phone;
|
|
417
|
+
let sentCode;
|
|
418
|
+
while (true) {
|
|
419
|
+
try {
|
|
420
|
+
phone = typeof params.phone === "string" ? params.phone : await params.phone();
|
|
421
|
+
const sendCode = () => this.invoke(new functions.AuthSendCode({
|
|
422
|
+
phoneNumber: phone,
|
|
423
|
+
apiId: this.apiId,
|
|
424
|
+
apiHash: this.apiHash,
|
|
425
|
+
settings: new types.CodeSettings(),
|
|
426
|
+
})).then((v) => v[_1_tl_object_js_1.as](types.AuthSentCode));
|
|
427
|
+
try {
|
|
428
|
+
sentCode = await sendCode();
|
|
429
|
+
}
|
|
430
|
+
catch (err) {
|
|
431
|
+
if (err instanceof types.RPCError) {
|
|
432
|
+
const match = err.errorMessage.match(/MIGRATE_(\d)$/);
|
|
433
|
+
if (match) {
|
|
434
|
+
await this[exports.handleMigrationError](err);
|
|
435
|
+
await initConnection();
|
|
436
|
+
sentCode = await sendCode();
|
|
470
437
|
}
|
|
471
438
|
else {
|
|
472
439
|
throw err;
|
|
473
440
|
}
|
|
474
441
|
}
|
|
442
|
+
else {
|
|
443
|
+
throw err;
|
|
444
|
+
}
|
|
475
445
|
}
|
|
446
|
+
break;
|
|
476
447
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
448
|
+
catch (err) {
|
|
449
|
+
if (err instanceof types.RPCError && err.errorMessage == "PHONE_NUMBER_INVALID") {
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
throw err;
|
|
454
|
+
}
|
|
481
455
|
}
|
|
482
456
|
}
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
457
|
+
dAuth("verification code sent");
|
|
458
|
+
let err;
|
|
459
|
+
while (true) {
|
|
460
|
+
const code = typeof params.code === "string" ? params.code : await params.code();
|
|
461
|
+
try {
|
|
462
|
+
await this.invoke(new functions.AuthSignIn({
|
|
463
|
+
phoneNumber: phone,
|
|
464
|
+
phoneCode: code,
|
|
465
|
+
phoneCodeHash: sentCode.phoneCodeHash,
|
|
466
|
+
}));
|
|
467
|
+
await this.storage.setAccountType("user");
|
|
468
|
+
dAuth("authorized as user");
|
|
469
|
+
await this.fetchState("authorize");
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
catch (err_) {
|
|
473
|
+
if (err_ instanceof types.RPCError && err_.errorMessage == "PHONE_CODE_INVALID") {
|
|
474
|
+
continue;
|
|
493
475
|
}
|
|
494
476
|
else {
|
|
495
|
-
|
|
477
|
+
err = err_;
|
|
478
|
+
break;
|
|
496
479
|
}
|
|
497
480
|
}
|
|
498
|
-
else {
|
|
499
|
-
throw err;
|
|
500
|
-
}
|
|
501
481
|
}
|
|
502
|
-
|
|
482
|
+
if (!(err instanceof types.RPCError && err.errorMessage == "SESSION_PASSWORD_NEEDED")) {
|
|
483
|
+
throw err;
|
|
484
|
+
}
|
|
485
|
+
while (true) {
|
|
486
|
+
const ap = await this.invoke(new functions.AccountGetPassword());
|
|
487
|
+
if (!(ap.currentAlgo instanceof types.PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow)) {
|
|
488
|
+
throw new Error(`Handling ${ap.currentAlgo?.constructor.name} not implemented`);
|
|
489
|
+
}
|
|
503
490
|
try {
|
|
491
|
+
const password = typeof params.password === "string" ? params.password : await params.password(ap.hint ?? null);
|
|
492
|
+
const input = await (0, _0_password_js_1.checkPassword)(password, ap);
|
|
493
|
+
await this.invoke(new functions.AuthCheckPassword({ password: input }));
|
|
494
|
+
await this.storage.setAccountType("user");
|
|
495
|
+
dAuth("authorized as user");
|
|
504
496
|
await this.fetchState("authorize");
|
|
497
|
+
break;
|
|
505
498
|
}
|
|
506
|
-
catch (
|
|
507
|
-
|
|
499
|
+
catch (err) {
|
|
500
|
+
if (err instanceof types.RPCError && err.errorMessage == "PASSWORD_HASH_INVALID") {
|
|
501
|
+
continue;
|
|
502
|
+
}
|
|
503
|
+
else {
|
|
504
|
+
throw err;
|
|
505
|
+
}
|
|
508
506
|
}
|
|
509
507
|
}
|
|
510
508
|
}
|
|
@@ -513,6 +511,16 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
|
|
|
513
511
|
*/
|
|
514
512
|
async start(params) {
|
|
515
513
|
await this.connect();
|
|
514
|
+
try {
|
|
515
|
+
await this.fetchState("authorize");
|
|
516
|
+
d("already authorized");
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
catch (err) {
|
|
520
|
+
if (!(err instanceof types.RPCError) || err.errorMessage != "AUTH_KEY_UNREGISTERED") {
|
|
521
|
+
throw err;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
516
524
|
await this.authorize(params);
|
|
517
525
|
}
|
|
518
526
|
async receiveLoop() {
|
|
@@ -584,15 +592,16 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
|
|
|
584
592
|
this.promises.delete(message.body.msgId);
|
|
585
593
|
}
|
|
586
594
|
}
|
|
587
|
-
else if (message.body instanceof types.
|
|
595
|
+
else if (message.body instanceof types.TypeBadMsgNotification || message.body instanceof types.BadServerSalt) {
|
|
588
596
|
if (message.body instanceof types.BadServerSalt) {
|
|
597
|
+
d("server salt reassigned");
|
|
589
598
|
this.state.salt = message.body.newServerSalt;
|
|
590
599
|
}
|
|
591
|
-
const promise = this.promises.get(message.body.badMsgId);
|
|
592
|
-
if (promise) {
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
}
|
|
600
|
+
// const promise = this.promises.get(message.body.badMsgId);
|
|
601
|
+
// if (promise) {
|
|
602
|
+
// promise.resolve(message.body);
|
|
603
|
+
// this.promises.delete(message.body.badMsgId);
|
|
604
|
+
// }
|
|
596
605
|
}
|
|
597
606
|
this.toAcknowledge.add(message.id);
|
|
598
607
|
}
|
|
@@ -1164,6 +1173,12 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
|
|
|
1164
1173
|
}
|
|
1165
1174
|
return messages;
|
|
1166
1175
|
}
|
|
1176
|
+
/**
|
|
1177
|
+
* Send a text message.
|
|
1178
|
+
*
|
|
1179
|
+
* @param chatId The chat to send the message to.
|
|
1180
|
+
* @param text The message's text.
|
|
1181
|
+
*/
|
|
1167
1182
|
async sendMessage(chatId, text, params) {
|
|
1168
1183
|
const entities_ = params?.entities ?? [];
|
|
1169
1184
|
const parseMode = params?.parseMode ?? this.parseMode;
|
|
@@ -1223,6 +1238,12 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
|
|
|
1223
1238
|
}));
|
|
1224
1239
|
return await this.updatesToMessages(chatId, result).then((v) => v[0]);
|
|
1225
1240
|
}
|
|
1241
|
+
/**
|
|
1242
|
+
* Retrieve multiple messages.
|
|
1243
|
+
*
|
|
1244
|
+
* @param chatId The identifier of the chat to retrieve the messages from.
|
|
1245
|
+
* @param messageIds The identifiers of the messages to retrieve.
|
|
1246
|
+
*/
|
|
1226
1247
|
async getMessages(chatId_, messageIds) {
|
|
1227
1248
|
const peer = await this.getInputPeer(chatId_);
|
|
1228
1249
|
let messages_ = new Array();
|
|
@@ -1258,6 +1279,12 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
|
|
|
1258
1279
|
}
|
|
1259
1280
|
return messages;
|
|
1260
1281
|
}
|
|
1282
|
+
/**
|
|
1283
|
+
* Retrieve a single message.
|
|
1284
|
+
*
|
|
1285
|
+
* @param chatId The identifier of the chat to retrieve the message from.
|
|
1286
|
+
* @param messageId The identifier of the message to retrieve.
|
|
1287
|
+
*/
|
|
1261
1288
|
async getMessage(chatId, messageId) {
|
|
1262
1289
|
const messages = await this.getMessages(chatId, [messageId]);
|
|
1263
1290
|
return messages[0] ?? null;
|
|
@@ -1301,24 +1328,29 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
|
|
|
1301
1328
|
}
|
|
1302
1329
|
}
|
|
1303
1330
|
}
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1331
|
+
/**
|
|
1332
|
+
* Download a file.
|
|
1333
|
+
*
|
|
1334
|
+
* @param fileId The identifier of the file to download.
|
|
1335
|
+
*/
|
|
1336
|
+
async download(fileId) {
|
|
1337
|
+
const fileId_ = _0_file_id_js_1.FileID.decode(fileId);
|
|
1338
|
+
switch (fileId_.fileType) {
|
|
1307
1339
|
case _0_file_id_js_1.FileType.ChatPhoto: {
|
|
1308
|
-
const big =
|
|
1309
|
-
const peer = await this.getInputPeer(
|
|
1310
|
-
const location = new types.InputPeerPhotoFileLocation({ big: big ? true : undefined, peer, photoId:
|
|
1340
|
+
const big = fileId_.params.thumbnailSource == _0_file_id_js_1.ThumbnailSource.ChatPhotoBig;
|
|
1341
|
+
const peer = await this.getInputPeer(fileId_.params.chatId);
|
|
1342
|
+
const location = new types.InputPeerPhotoFileLocation({ big: big ? true : undefined, peer, photoId: fileId_.params.mediaId });
|
|
1311
1343
|
return this.downloadInner(location);
|
|
1312
1344
|
}
|
|
1313
1345
|
case _0_file_id_js_1.FileType.Photo: {
|
|
1314
|
-
if (
|
|
1346
|
+
if (fileId_.params.mediaId == undefined || fileId_.params.accessHash == undefined || fileId_.params.fileReference == undefined || fileId_.params.thumbnailSize == undefined) {
|
|
1315
1347
|
(0, _0_control_js_1.UNREACHABLE)();
|
|
1316
1348
|
}
|
|
1317
1349
|
const location = new types.InputPhotoFileLocation({
|
|
1318
|
-
id:
|
|
1319
|
-
accessHash:
|
|
1320
|
-
fileReference:
|
|
1321
|
-
thumbSize:
|
|
1350
|
+
id: fileId_.params.mediaId,
|
|
1351
|
+
accessHash: fileId_.params.accessHash,
|
|
1352
|
+
fileReference: fileId_.params.fileReference,
|
|
1353
|
+
thumbSize: fileId_.params.thumbnailSize,
|
|
1322
1354
|
});
|
|
1323
1355
|
return this.downloadInner(location);
|
|
1324
1356
|
}
|
|
@@ -1338,6 +1370,13 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
|
|
|
1338
1370
|
return name;
|
|
1339
1371
|
}
|
|
1340
1372
|
}
|
|
1373
|
+
/**
|
|
1374
|
+
* Forward multiple messages.
|
|
1375
|
+
*
|
|
1376
|
+
* @param from The identifier of the chat to forward the messages from.
|
|
1377
|
+
* @param to The identifier of the chat to forward the messages to.
|
|
1378
|
+
* @param messageIds The identifiers of the messages to forward.
|
|
1379
|
+
*/
|
|
1341
1380
|
async forwardMessages(from, to, messageIds, params) {
|
|
1342
1381
|
const result = await this.invoke(new functions.MessagesForwardMessages({
|
|
1343
1382
|
fromPeer: await this.getInputPeer(from),
|
|
@@ -1353,9 +1392,19 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
|
|
|
1353
1392
|
}));
|
|
1354
1393
|
return await this.updatesToMessages(to, result);
|
|
1355
1394
|
}
|
|
1395
|
+
/**
|
|
1396
|
+
* Forward a single message.
|
|
1397
|
+
*
|
|
1398
|
+
* @param from The identifier of the chat to forward the message from.
|
|
1399
|
+
* @param to The identifier of the chat to forward the message to.
|
|
1400
|
+
* @param messageId The identifier of the message to forward.
|
|
1401
|
+
*/
|
|
1356
1402
|
async forwardMessage(from, to, messageId, params) {
|
|
1357
1403
|
return await this.forwardMessages(from, to, [messageId], params).then((v) => v[0]);
|
|
1358
1404
|
}
|
|
1405
|
+
/**
|
|
1406
|
+
* Get information on the currently authorized user.
|
|
1407
|
+
*/
|
|
1359
1408
|
async getMe() {
|
|
1360
1409
|
const users = await this.invoke(new functions.UsersGetUsers({ id: [new types.InputUserSelf()] }));
|
|
1361
1410
|
if (users.length < 1) {
|
package/script/constants.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export declare const PUBLIC_KEYS: PublicKeys;
|
|
|
5
5
|
export declare const VECTOR_CONSTRUCTOR = 481674261;
|
|
6
6
|
export declare const INITIAL_DC: DC;
|
|
7
7
|
export declare const LAYER = 160;
|
|
8
|
-
export declare const APP_VERSION = "MTKruto 0.0.
|
|
8
|
+
export declare const APP_VERSION = "MTKruto 0.0.980";
|
|
9
9
|
export declare const DEVICE_MODEL: string;
|
|
10
10
|
export declare const LANG_CODE: string;
|
|
11
11
|
export declare const LANG_PACK = "";
|
package/script/constants.js
CHANGED
|
@@ -80,7 +80,7 @@ exports.PUBLIC_KEYS = Object.freeze([
|
|
|
80
80
|
exports.VECTOR_CONSTRUCTOR = 0x1CB5C415;
|
|
81
81
|
exports.INITIAL_DC = "2-test";
|
|
82
82
|
exports.LAYER = 160;
|
|
83
|
-
exports.APP_VERSION = "MTKruto 0.0.
|
|
83
|
+
exports.APP_VERSION = "MTKruto 0.0.980";
|
|
84
84
|
// @ts-ignore: lib
|
|
85
85
|
exports.DEVICE_MODEL = typeof dntShim.Deno === "undefined" ? typeof navigator === "undefined" ? typeof process === "undefined" ? "Unknown" : process.platform + "-" + process.arch : navigator.userAgent.split(" ")[0] : dntShim.Deno.build.os + "-" + dntShim.Deno.build.arch;
|
|
86
86
|
exports.LANG_CODE = typeof navigator === "undefined" ? "en" : navigator.language.split("-")[0];
|