max-account-api 0.1.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.
@@ -0,0 +1,1141 @@
1
+ /**
2
+ * Wire-level types — direct mirrors of MAX WebSocket payloads.
3
+ * Version 11 of protocol observed at wss://ws-api.oneme.ru/websocket.
4
+ */
5
+ export interface WireFrame<P = unknown> {
6
+ ver: number;
7
+ cmd: 0 | 1 | 3;
8
+ seq: number;
9
+ opcode: number;
10
+ payload?: P;
11
+ }
12
+ export interface UserAgent {
13
+ deviceType: 'WEB' | 'ANDROID' | 'IOS' | 'DESKTOP';
14
+ locale: string;
15
+ deviceLocale: string;
16
+ osVersion: string;
17
+ deviceName: string;
18
+ headerUserAgent: string;
19
+ appVersion: string;
20
+ screen: string;
21
+ timezone: string;
22
+ /** Mobile-only. CPU arch — observed `x86_64` / `arm64-v8a`. */
23
+ arch?: string;
24
+ /** Mobile-only. Numeric build of the native app (e.g. 6690 for v26.15.1). */
25
+ buildNumber?: number;
26
+ /** Mobile-only. Set when FCM push channel is provisioned (e.g. `GCM`). */
27
+ pushDeviceType?: string;
28
+ }
29
+ export interface HelloRequest {
30
+ userAgent: UserAgent;
31
+ deviceId: string;
32
+ }
33
+ export type PhoneAuthStartType = 'START_AUTH' | 'RESEND';
34
+ export interface PhoneAuthStartRequest {
35
+ type: PhoneAuthStartType;
36
+ phone: string;
37
+ }
38
+ /** Server returns a short-lived token used in PhoneAuthVerifyRequest. */
39
+ export interface PhoneAuthStartResponse {
40
+ token: string;
41
+ /** Seconds until the SMS code expires. */
42
+ ttl?: number;
43
+ /** Length of the expected SMS code (usually 5). */
44
+ codeLength?: number;
45
+ }
46
+ export interface PhoneAuthVerifyRequest {
47
+ verifyCode: string;
48
+ token: string;
49
+ /** Observed constant `'CHECK_CODE'` on mobile op 18. */
50
+ authTokenType?: 'CHECK_CODE';
51
+ }
52
+ /** Success: LOGIN token; failure: server throws `{error:'verify.code.wrong'}`. */
53
+ export interface PhoneAuthVerifyResponse {
54
+ tokenAttrs: {
55
+ LOGIN?: {
56
+ token: string;
57
+ };
58
+ };
59
+ profile?: {
60
+ profileOptions: unknown[];
61
+ contact: ContactInfo;
62
+ };
63
+ passwordChallenge?: PasswordChallenge;
64
+ }
65
+ export interface HelloResponse {
66
+ 'phone-auth-enabled': boolean;
67
+ location: string;
68
+ lang: boolean;
69
+ 'reg-country-code': string[];
70
+ }
71
+ export interface QrStartResponse {
72
+ pollingInterval: number;
73
+ qrLink: string;
74
+ ttl: number;
75
+ trackId: string;
76
+ expiresAt: number;
77
+ }
78
+ export interface QrPollResponse {
79
+ /** Server omits `loginAvailable` until the QR is confirmed; it then becomes `true`. */
80
+ status: {
81
+ loginAvailable?: boolean;
82
+ expiresAt: number;
83
+ };
84
+ }
85
+ /**
86
+ * Op 290 — sent by the **mobile** binary transport to confirm a web-side QR
87
+ * login. The `qrLink` is the value from the web-side {@link QrStartResponse}.
88
+ *
89
+ * MAX's camera-scan path eventually calls into the same op with the decoded
90
+ * URL. Doing it programmatically (no camera) is the basis of
91
+ * {@link import('./qr-bind.js').qrBindWebSession}.
92
+ *
93
+ * Wire prefix: `f0 34` (op-hint), `flags=1`. Response is an empty ACK.
94
+ */
95
+ export interface QrConfirmRequest {
96
+ qrLink: string;
97
+ }
98
+ export interface QrLoginResponse {
99
+ /** Empty `{}` when 2FA cloud password is enabled and `passwordChallenge` is set instead. */
100
+ tokenAttrs: {
101
+ LOGIN?: {
102
+ token: string;
103
+ };
104
+ };
105
+ profile?: {
106
+ profileOptions: unknown[];
107
+ contact: ContactInfo;
108
+ };
109
+ /** Present when account has 2FA cloud password — caller must finish via op 115. */
110
+ passwordChallenge?: PasswordChallenge;
111
+ }
112
+ export interface PasswordChallenge {
113
+ config: {
114
+ passMaxLen: number;
115
+ passMinLen: number;
116
+ hintMaxLen: number;
117
+ };
118
+ trackId: string;
119
+ /** Masked email (e.g. `m****@g****.com`). */
120
+ email: string;
121
+ /** User-set hint string (shown to the user as a reminder for their password). */
122
+ hint?: string;
123
+ }
124
+ export interface AuthTrackStartRequest {
125
+ /** Observed value: 0 (start cloud-password track). */
126
+ type: number;
127
+ }
128
+ export interface AuthTrackStartResponse {
129
+ trackId: string;
130
+ }
131
+ export interface AuthPasswordInfoRequest {
132
+ trackId: string;
133
+ }
134
+ export interface AuthPasswordInfoResponse {
135
+ password: {
136
+ enabled: boolean;
137
+ email?: string;
138
+ };
139
+ }
140
+ export interface AuthPasswordValidateRequest {
141
+ trackId: string;
142
+ password: string;
143
+ }
144
+ export interface AuthPasswordHintRequest {
145
+ trackId: string;
146
+ hint: string;
147
+ }
148
+ export interface AuthEmailSendCodeRequest {
149
+ trackId: string;
150
+ email: string;
151
+ }
152
+ export interface AuthEmailSendCodeResponse {
153
+ trackId: string;
154
+ blockingDuration: number;
155
+ codeLength: number;
156
+ }
157
+ export interface AuthEmailVerifyCodeRequest {
158
+ trackId: string;
159
+ verifyCode: string;
160
+ }
161
+ export interface AuthEmailVerifyCodeResponse {
162
+ trackId: string;
163
+ /** Masked email confirming which account got verified. */
164
+ email: string;
165
+ }
166
+ export interface AuthPasswordCommitRequest {
167
+ trackId: string;
168
+ /** Server-side capability list. Observed `[0,3,4]` for set, `[5]` for remove. */
169
+ expectedCapabilities: number[];
170
+ password?: string;
171
+ hint?: string;
172
+ /** Pass `true` (with `expectedCapabilities:[5]`) to disable 2FA. */
173
+ remove2fa?: boolean;
174
+ }
175
+ export interface AuthPasswordVerifyRequest {
176
+ trackId: string;
177
+ password: string;
178
+ }
179
+ export interface AuthPasswordVerifyResponse {
180
+ trackId: string;
181
+ }
182
+ /** Op 115: complete QR login when account has 2FA cloud password. */
183
+ export interface AuthQrPasswordLoginRequest {
184
+ trackId: string;
185
+ password: string;
186
+ }
187
+ export interface AuthQrPasswordLoginResponse {
188
+ tokenAttrs: {
189
+ LOGIN: {
190
+ token: string;
191
+ };
192
+ };
193
+ profile?: {
194
+ profileOptions: unknown[];
195
+ contact: ContactInfo;
196
+ };
197
+ }
198
+ export interface ChatClearRequest {
199
+ chatId: number;
200
+ /** Wipe everything up to this server-time ms. */
201
+ lastEventTime: number;
202
+ /** `true` clears for all participants (admin only); `false` clears for self. */
203
+ forAll: boolean;
204
+ }
205
+ export interface ChatsSyncRequest {
206
+ /** Last `modified` timestamp seen by the client; server returns chats updated after. */
207
+ marker: number;
208
+ }
209
+ export interface ChatsSyncResponse {
210
+ chats: MaxChat[];
211
+ }
212
+ export interface ChatResolveLinkRequest {
213
+ /** Full max.ru URL (`https://max.ru/<slug>` or `https://max.ru/:invite/<token>`). */
214
+ link: string;
215
+ }
216
+ export interface ChatResolveLinkResponse {
217
+ chat: MaxChat;
218
+ }
219
+ export interface LinkPreviewRequest {
220
+ text: string;
221
+ }
222
+ export interface LinkPreviewResponse {
223
+ attachments: MessageAttach[];
224
+ }
225
+ export interface VideoUploadInfo {
226
+ url: string;
227
+ videoId: number;
228
+ token: string;
229
+ uploaderType?: number;
230
+ }
231
+ /**
232
+ * Op 82 request. The same opcode serves **video** and **audio** uploads —
233
+ * the `(uploaderType, type)` pair selects the back-end CDN:
234
+ * - `uploaderType: 0, type: 1` → regular video (returns OK-CDN URL)
235
+ * - `uploaderType: 1, type: 2` → audio / voice note (returns `au.oneme.ru/uploadAudio` URL)
236
+ *
237
+ * Values from on-the-wire capture of `ru.oneme.app` v26.15.1.
238
+ */
239
+ export interface VideoUploadUrlRequest {
240
+ count: number;
241
+ uploaderType?: number;
242
+ type?: number;
243
+ }
244
+ export interface VideoUploadUrlResponse {
245
+ info: VideoUploadInfo[];
246
+ }
247
+ export interface CallHistoryRequest {
248
+ /** `false` paginates backward through past calls. */
249
+ forward: boolean;
250
+ count: number;
251
+ /** Optional cursor; pass `forwardMarker` from previous response. */
252
+ marker?: number;
253
+ }
254
+ export interface CallHistoryEntry {
255
+ chatId: number;
256
+ chatType: string;
257
+ message: MaxMessage;
258
+ }
259
+ export interface CallHistoryResponse {
260
+ forwardMarker?: number;
261
+ history: CallHistoryEntry[];
262
+ }
263
+ export interface WebTokenResponse {
264
+ token: string;
265
+ /** Absolute ms when the token must be refreshed. */
266
+ token_refresh_ts: number;
267
+ /** Absolute ms when the token finally expires. */
268
+ token_lifetime_ts: number;
269
+ }
270
+ export interface MemberLeavePush {
271
+ chatId: number;
272
+ userId: number;
273
+ }
274
+ export interface PresencePush {
275
+ userId: number;
276
+ presence: {
277
+ seen: number;
278
+ status: number;
279
+ };
280
+ }
281
+ export interface ProfileUpdatePush {
282
+ profile: {
283
+ profileOptions: unknown[];
284
+ contact: ContactInfo;
285
+ };
286
+ }
287
+ export interface ContactName {
288
+ name: string;
289
+ firstName?: string;
290
+ lastName?: string;
291
+ type: 'ONEME' | 'CUSTOM';
292
+ }
293
+ export interface ContactInfo {
294
+ id: number;
295
+ registrationTime: number;
296
+ accountStatus: number;
297
+ country?: string;
298
+ names: ContactName[];
299
+ phone?: number;
300
+ options?: string[];
301
+ photoId?: number;
302
+ description?: string;
303
+ baseUrl?: string;
304
+ baseRawUrl?: string;
305
+ updateTime: number;
306
+ }
307
+ export interface MessageElement {
308
+ type: 'STRONG' | 'EMPHASIZED' | 'UNDERLINE' | 'STRIKETHROUGH' | 'MONOSPACED' | 'LINK' | 'MENTION' | 'HEADING';
309
+ length: number;
310
+ from?: number;
311
+ attributes?: Record<string, unknown>;
312
+ }
313
+ export interface MessageAttach {
314
+ _type: string;
315
+ [key: string]: unknown;
316
+ }
317
+ export interface MessageLink {
318
+ type: 'REPLY' | 'FORWARD';
319
+ messageId?: string;
320
+ chatId?: number;
321
+ message?: MaxMessage;
322
+ }
323
+ export interface ReactionCounter {
324
+ count: number;
325
+ reaction: string;
326
+ }
327
+ export interface ReactionInfo {
328
+ counters?: ReactionCounter[];
329
+ yourReaction?: string;
330
+ totalCount?: number;
331
+ }
332
+ export interface MaxMessage {
333
+ id: string;
334
+ cid?: number;
335
+ sender: number;
336
+ time: number;
337
+ text?: string;
338
+ type: 'USER' | 'SYSTEM' | 'CONTROL';
339
+ elements?: MessageElement[];
340
+ attaches?: MessageAttach[];
341
+ options?: number;
342
+ link?: MessageLink;
343
+ reactionInfo?: ReactionInfo;
344
+ }
345
+ export interface OutgoingMessage {
346
+ text: string;
347
+ cid: number;
348
+ elements?: MessageElement[];
349
+ attaches?: MessageAttach[];
350
+ link?: MessageLink;
351
+ }
352
+ export interface SendMessageRequest {
353
+ chatId: number;
354
+ message: OutgoingMessage;
355
+ notify: boolean;
356
+ }
357
+ export interface SendMessageResponse {
358
+ chatId: number;
359
+ message: MaxMessage;
360
+ unread: number;
361
+ mark: number;
362
+ }
363
+ export interface IncomingMessageNotify {
364
+ chatId: number;
365
+ unread: number;
366
+ message: MaxMessage;
367
+ ttl: boolean;
368
+ mark: number;
369
+ prevMessageId?: string;
370
+ }
371
+ export interface ChatParticipants {
372
+ [userId: string]: number;
373
+ }
374
+ export interface MaxChat {
375
+ id: number;
376
+ cid?: number;
377
+ type: 'DIALOG' | 'CHAT' | 'CHANNEL';
378
+ status?: 'ACTIVE' | 'REMOVED';
379
+ owner?: number;
380
+ joinTime?: number;
381
+ created?: number;
382
+ modified?: number;
383
+ lastEventTime?: number;
384
+ lastMessage?: MaxMessage;
385
+ participants?: ChatParticipants;
386
+ participantsCount?: number;
387
+ newMessages?: number;
388
+ prevMessageId?: string;
389
+ hasBots?: boolean;
390
+ options?: Record<string, boolean>;
391
+ restrictions?: number;
392
+ /** Group-only fields (present on op 55 / 77 responses). */
393
+ title?: string;
394
+ description?: string;
395
+ link?: string;
396
+ access?: 'PRIVATE' | 'PUBLIC';
397
+ pinnedMessage?: MaxMessage;
398
+ adminParticipants?: Record<string, {
399
+ permissions: number;
400
+ inviterId?: number;
401
+ promotedAt?: number;
402
+ }>;
403
+ }
404
+ export interface LoginRequest {
405
+ token: string;
406
+ chatsCount: number;
407
+ interactive: boolean;
408
+ chatsSync: number;
409
+ contactsSync: number;
410
+ presenceSync: number;
411
+ draftsSync: number;
412
+ }
413
+ export interface LoginResponse {
414
+ profile: {
415
+ profileOptions: unknown[];
416
+ contact: ContactInfo;
417
+ };
418
+ chats: MaxChat[];
419
+ contacts: ContactInfo[];
420
+ token: string;
421
+ config: {
422
+ server: Record<string, unknown>;
423
+ user: Record<string, unknown>;
424
+ };
425
+ hash: string;
426
+ experiments: Record<string, string | boolean | number>;
427
+ presence: Record<string, unknown>;
428
+ messages: Record<string, unknown>;
429
+ time: number;
430
+ }
431
+ export interface ReadMessageRequest {
432
+ type: 'READ_MESSAGE';
433
+ chatId: number;
434
+ messageId: string;
435
+ mark: number;
436
+ }
437
+ export interface HistoryRequest {
438
+ chatId: number;
439
+ from: number;
440
+ forward: number;
441
+ backward: number;
442
+ getMessages: boolean;
443
+ }
444
+ export interface HistoryResponse {
445
+ messages: MaxMessage[];
446
+ }
447
+ export interface TypingRequest {
448
+ chatId: number;
449
+ type: 'TEXT' | 'AUDIO' | 'PHOTO' | 'FILE';
450
+ }
451
+ export interface SubscribeRequest {
452
+ chatId: number;
453
+ subscribe: boolean;
454
+ }
455
+ export interface ReactionSetRequest {
456
+ chatId: number;
457
+ messageId: string;
458
+ reaction: {
459
+ reactionType: 'EMOJI';
460
+ id: string;
461
+ };
462
+ }
463
+ export interface ReactionSetResponse {
464
+ reactionInfo: ReactionInfo;
465
+ }
466
+ export interface ReactionsGetRequest {
467
+ chatId: number;
468
+ messageIds: string[];
469
+ }
470
+ export interface ReactionsGetResponse {
471
+ messagesReactions: Record<string, ReactionInfo>;
472
+ }
473
+ export interface GroupParticipantsRequest {
474
+ chatId: number;
475
+ userIds: number[];
476
+ operation: 'add' | 'remove';
477
+ /** Present when adjusting admin role. Omit for plain member ops. */
478
+ type?: 'ADMIN';
479
+ /** Bitmask of admin permissions. 255 = all. Required when operation=add+type=ADMIN. */
480
+ permissions?: number;
481
+ /** Show last messages to newly added member. */
482
+ showHistory?: boolean;
483
+ /** Seconds of recent history to wipe when kicking. 0 = keep. */
484
+ cleanMsgPeriod?: number;
485
+ }
486
+ export interface GroupParticipantsResponse {
487
+ chat: MaxChat;
488
+ }
489
+ export interface CommonChatsRequest {
490
+ userIds: number[];
491
+ }
492
+ export interface CommonChatsResponse {
493
+ hasMore: boolean;
494
+ commonChats: MaxChat[];
495
+ }
496
+ export interface MessageSearchRequest {
497
+ chatId: number;
498
+ query: string;
499
+ count: number;
500
+ }
501
+ export interface MessageSearchHit {
502
+ message: MaxMessage;
503
+ highlights: string[];
504
+ }
505
+ export interface MessageSearchResponse {
506
+ result: MessageSearchHit[];
507
+ ucpQId: string;
508
+ total?: number;
509
+ }
510
+ export interface ChatUpdateNotify {
511
+ chat: MaxChat;
512
+ }
513
+ export interface ReadMarkNotify {
514
+ setAsUnread: boolean;
515
+ chatId: number;
516
+ userId: number;
517
+ mark: number;
518
+ }
519
+ export interface CreateGroupAttach extends MessageAttach {
520
+ _type: 'CONTROL';
521
+ event: 'new';
522
+ chatType: 'CHAT' | 'CHANNEL';
523
+ title: string;
524
+ userIds: number[];
525
+ }
526
+ export interface DeleteMessagesRequest {
527
+ chatId: number;
528
+ messageIds: string[];
529
+ /** true = delete only on this device; false = delete for all participants. */
530
+ forMe: boolean;
531
+ }
532
+ export interface DeleteMessagesResponse {
533
+ chatId: number;
534
+ messageIds: string[];
535
+ }
536
+ export interface EditMessageRequest {
537
+ chatId: number;
538
+ messageId: string;
539
+ text: string;
540
+ elements?: MessageElement[];
541
+ /** Server expects key `attachments`, NOT `attaches`. Keep wire field as-is. */
542
+ attachments?: MessageAttach[];
543
+ }
544
+ export interface EditMessageResponse {
545
+ message: MaxMessage & {
546
+ status?: 'EDITED';
547
+ updateTime?: number;
548
+ };
549
+ }
550
+ export interface ReactionRemoveRequest {
551
+ chatId: number;
552
+ messageId: string;
553
+ }
554
+ export interface ReactionsListRequest {
555
+ chatId: number;
556
+ messageId: string;
557
+ count: number;
558
+ }
559
+ /**
560
+ * Group settings (op 55). One call per "field group". Use shape variants:
561
+ * { options: { ALL_CAN_PIN_MESSAGE: false } }
562
+ * { theme, description } // rename / set bio
563
+ * { pinMessageId, notifyPin } // pin a message
564
+ *
565
+ * `theme` is the displayed group title — server kept the legacy field name.
566
+ */
567
+ export interface ChatSettingsOptions {
568
+ OFFICIAL?: boolean;
569
+ ONLY_OWNER_CAN_CHANGE_ICON_TITLE?: boolean;
570
+ ONLY_ADMIN_CAN_CALL?: boolean;
571
+ COMMENTS?: boolean;
572
+ SENT_BY_PHONE?: boolean;
573
+ CONFIRM_BEFORE_SEND?: boolean;
574
+ A_PLUS_CHANNEL?: boolean;
575
+ ALL_CAN_PIN_MESSAGE?: boolean;
576
+ SIGN_ADMIN?: boolean;
577
+ MESSAGE_COPY_NOT_ALLOWED?: boolean;
578
+ ONLY_ADMIN_CAN_ADD_MEMBER?: boolean;
579
+ MEMBERS_CAN_SEE_PRIVATE_LINK?: boolean;
580
+ /** Channel join requires admin approval. */
581
+ JOIN_REQUEST?: boolean;
582
+ }
583
+ export interface ChatSettingsRequest {
584
+ chatId: number;
585
+ options?: ChatSettingsOptions;
586
+ theme?: string;
587
+ description?: string;
588
+ pinMessageId?: string;
589
+ notifyPin?: boolean;
590
+ /** Avatar token (from PHOTO upload). Setting on group/channel updates icon. */
591
+ photoToken?: string;
592
+ /** Rotate / regenerate the private invite link. */
593
+ revokePrivateLink?: boolean;
594
+ }
595
+ export interface ChatSettingsResponse {
596
+ chat: MaxChat;
597
+ }
598
+ export interface ChatReactionsSettingsRequest {
599
+ chatId: number;
600
+ /** false = reactions disabled in chat; true = enabled. */
601
+ value: boolean;
602
+ /** Reactions per message limit (server default 2). */
603
+ count?: number;
604
+ /** Allowed emojis when `included=true`; ignored when reactions disabled. */
605
+ reactionIds?: string[];
606
+ /** true = only `reactionIds` allowed; false = all reactions allowed. */
607
+ included?: boolean;
608
+ }
609
+ export interface ChatReactionsSettings {
610
+ chatId: number;
611
+ count: number;
612
+ updateTime: number;
613
+ isActive: boolean;
614
+ included: boolean;
615
+ reactionIds: string[];
616
+ }
617
+ export interface ChatReactionsSettingsResponse {
618
+ chatReactionsSettings: ChatReactionsSettings;
619
+ }
620
+ export interface WebTokenResponse {
621
+ token: string;
622
+ token_lifetime_ts: number;
623
+ token_refresh_ts: number;
624
+ }
625
+ /**
626
+ * Public domain types used in events emitted by the high-level Client.
627
+ */
628
+ export interface IncomingMessage {
629
+ chatId: number;
630
+ messageId: string;
631
+ text: string;
632
+ fromId: number;
633
+ time: number;
634
+ raw: MaxMessage;
635
+ }
636
+ export interface ClientEvents {
637
+ ready: () => void;
638
+ message: (msg: IncomingMessage) => void;
639
+ raw: (frame: WireFrame) => void;
640
+ error: (err: Error) => void;
641
+ close: (code: number, reason: string) => void;
642
+ reconnect: (attempt: number) => void;
643
+ qr: (info: {
644
+ link: string;
645
+ expiresAt: number;
646
+ }) => void;
647
+ login: (profile: ContactInfo) => void;
648
+ /** Server pushed an updated chat snapshot (op 135). */
649
+ chatUpdate: (chat: MaxChat) => void;
650
+ /** Other participant read up to a mark in a chat (op 130). */
651
+ readByOther: (info: ReadMarkNotify) => void;
652
+ /** Server bumped the user-config hash (op 134) — re-fetch settings if cared. */
653
+ configChanged: (hash: string) => void;
654
+ /** Background HTTP file upload finished server-side (op 136). */
655
+ fileUploadDone: (info: {
656
+ fileId: number | string;
657
+ }) => void;
658
+ /** Sticker pack / recents updated (op 150). */
659
+ stickerRecentsUpdate: (info: StickerRecentsPush) => void;
660
+ /** A user left a group / left chat (op 129). */
661
+ memberLeave: (info: MemberLeavePush) => void;
662
+ /** Presence (online / last-seen) update for a subscribed contact (op 132). */
663
+ presence: (info: PresencePush) => void;
664
+ /** Profile fields of a known contact changed (op 159). */
665
+ contactUpdate: (contact: ContactInfo) => void;
666
+ }
667
+ export interface ProfileUpdateRequest {
668
+ firstName?: string;
669
+ lastName?: string;
670
+ description?: string;
671
+ /** Token from PHOTO upload (op 80 + HTTP) when setting avatar. */
672
+ photoToken?: string;
673
+ /** Required when sending photoToken. */
674
+ avatarType?: 'USER_AVATAR';
675
+ }
676
+ export interface ProfileUpdateResponse {
677
+ profile: {
678
+ profileOptions: unknown[];
679
+ contact: ContactInfo;
680
+ };
681
+ }
682
+ /** Per-chat settings: mute, sound, etc. */
683
+ export interface ChatNotificationSettings {
684
+ /** -1 = mute forever, 0 = unmuted, future ts = muted until. */
685
+ dontDisturbUntil?: number;
686
+ led?: boolean;
687
+ vibr?: boolean;
688
+ sound?: string;
689
+ favIndex?: number;
690
+ }
691
+ /** Subset of user-level setting keys (server has many more). */
692
+ export interface UserSettings {
693
+ SEARCH_BY_PHONE?: 'ALL' | 'CONTACTS' | 'NOBODY';
694
+ INCOMING_CALL?: 'ALL' | 'CONTACTS' | 'NOBODY';
695
+ CHATS_INVITE?: 'ALL' | 'CONTACTS' | 'NOBODY';
696
+ CONTENT_LEVEL_ACCESS?: boolean;
697
+ HIDDEN?: boolean;
698
+ PHONE_NUMBER_PRIVACY?: 'ALL' | 'CONTACTS' | 'NOBODY';
699
+ PUSH_SOUND?: string;
700
+ INACTIVE_TTL?: number;
701
+ SHOW_READ_MARK?: boolean;
702
+ DOUBLE_TAP_REACTION_DISABLED?: boolean;
703
+ SAFE_MODE_NO_PIN?: boolean;
704
+ FAMILY_PROTECTION?: boolean;
705
+ PUSH_DETAILS?: boolean;
706
+ PUSH_NEW_CONTACTS?: boolean;
707
+ UNSAFE_FILES?: boolean;
708
+ CHATS_PUSH_NOTIFICATION?: boolean;
709
+ CHATS_PUSH_SOUND?: string;
710
+ M_CALL_PUSH_NOTIFICATION?: boolean;
711
+ DONT_DISTURB_UNTIL?: number;
712
+ [key: string]: unknown;
713
+ }
714
+ export interface SettingsRequest {
715
+ settings: {
716
+ chats?: Record<string, ChatNotificationSettings>;
717
+ user?: UserSettings;
718
+ };
719
+ }
720
+ export interface SettingsResponse {
721
+ chats?: Record<string, ChatNotificationSettings>;
722
+ user?: UserSettings;
723
+ hash?: string;
724
+ }
725
+ export interface ActiveSession {
726
+ client: string;
727
+ location?: string;
728
+ current?: boolean;
729
+ time: number;
730
+ info?: string;
731
+ }
732
+ export interface SessionsListResponse {
733
+ sessions: ActiveSession[];
734
+ }
735
+ export type ContactActionType = 'REMOVE' | 'UPDATE' | 'BLOCK' | 'UNBLOCK';
736
+ export interface ContactActionRequest {
737
+ contactId: number;
738
+ action: ContactActionType;
739
+ firstName?: string;
740
+ lastName?: string;
741
+ }
742
+ export interface ContactActionResponse {
743
+ contact?: ContactInfo;
744
+ }
745
+ export interface ContactsListByStatusRequest {
746
+ status: 'BLOCKED' | 'ACTIVE' | string;
747
+ count: number;
748
+ from: number;
749
+ }
750
+ export interface ContactsListByStatusResponse {
751
+ contacts: ContactInfo[];
752
+ }
753
+ export interface ContactAddByPhoneRequest {
754
+ phone: string;
755
+ firstName?: string;
756
+ lastName?: string;
757
+ }
758
+ export interface ContactAddByPhoneResponse {
759
+ new: boolean;
760
+ contact: ContactInfo;
761
+ }
762
+ export interface ContactLookupByPhoneRequest {
763
+ phone: string;
764
+ }
765
+ export interface ContactLookupByPhoneResponse {
766
+ contact: ContactInfo;
767
+ }
768
+ export type AttachFilterType = 'PHOTO' | 'VIDEO' | 'FILE' | 'AUDIO' | 'SHARE';
769
+ export interface HistoryByAttachRequest {
770
+ chatId: number;
771
+ messageId: string;
772
+ attachTypes: AttachFilterType[];
773
+ forward: number;
774
+ backward: number;
775
+ }
776
+ export interface HistoryByAttachResponse {
777
+ messages: MaxMessage[];
778
+ total?: number;
779
+ }
780
+ export interface ChatDeleteRequest {
781
+ chatId: number;
782
+ forAll: boolean;
783
+ lastEventTime: number;
784
+ }
785
+ export interface ChatLeaveRequest {
786
+ chatId: number;
787
+ }
788
+ export interface ChatLeaveResponse {
789
+ message: MaxMessage;
790
+ }
791
+ export interface MembersListRequest {
792
+ chatId: number;
793
+ type: 'MEMBER' | 'ADMIN';
794
+ marker: number;
795
+ count: number;
796
+ }
797
+ export interface MemberEntry {
798
+ presence?: {
799
+ seen?: number;
800
+ status?: string;
801
+ };
802
+ contact: ContactInfo;
803
+ }
804
+ export interface MembersListResponse {
805
+ members: MemberEntry[];
806
+ }
807
+ export type GlobalSearchSection = 'PUBLIC_CHATS' | 'USERS' | 'PRIVATE_CHATS' | 'CHANNELS' | 'GROUPS' | 'BOTS' | 'ALL';
808
+ export interface GlobalSearchRequest {
809
+ query: string;
810
+ count: number;
811
+ marker?: string;
812
+ type?: GlobalSearchSection;
813
+ }
814
+ export interface GlobalSearchHit {
815
+ section?: GlobalSearchSection;
816
+ highlights?: string[];
817
+ chatId?: number;
818
+ chat?: MaxChat;
819
+ contact?: ContactInfo;
820
+ }
821
+ export interface GlobalSearchResponse {
822
+ result: GlobalSearchHit[];
823
+ counters?: Record<string, number>;
824
+ total?: number;
825
+ ucpQId?: string;
826
+ marker?: string;
827
+ }
828
+ export interface MessageStatsRequest {
829
+ chatId: number;
830
+ messageIds: string[];
831
+ }
832
+ export interface MessageStatsResponse {
833
+ stats: Record<string, {
834
+ views: number;
835
+ }>;
836
+ }
837
+ /** Inner JSON serialised into `internalParams` string when starting a call. */
838
+ export interface CallInternalParams {
839
+ deviceId: string;
840
+ sdkVersion: string;
841
+ clientAppKey: string;
842
+ platform: 'WEB' | 'ANDROID' | 'IOS' | 'DESKTOP';
843
+ protocolVersion: number;
844
+ domainId: string;
845
+ capabilities: string;
846
+ }
847
+ export interface CallStartRequest {
848
+ conversationId: string;
849
+ calleeIds: number[];
850
+ /** JSON-stringified `CallInternalParams`. */
851
+ internalParams: string;
852
+ isVideo: boolean;
853
+ }
854
+ export interface CallStartResponse {
855
+ conversationId: string;
856
+ /** JSON-stringified server-side params (WebRTC endpoint, token, TURN). */
857
+ internalCallerParams: string;
858
+ }
859
+ /** Parsed shape of `internalCallerParams`. */
860
+ export interface CallCallerParams {
861
+ id: {
862
+ internal: string | number;
863
+ external: string | number;
864
+ };
865
+ isConcurrent?: boolean;
866
+ endpoint: string;
867
+ wtEndpoint?: string;
868
+ clientType: string;
869
+ turn?: Array<{
870
+ urls: string | string[];
871
+ username?: string;
872
+ credential?: string;
873
+ }>;
874
+ }
875
+ export interface PhotoUploadUrlRequest {
876
+ count: number;
877
+ }
878
+ export interface PhotoUploadUrlResponse {
879
+ url: string;
880
+ }
881
+ /** Server response from HTTP photo upload (POST iu.oneme.ru/uploadImage). */
882
+ export interface PhotoUploadHttpResponse {
883
+ photos: Record<string, {
884
+ token: string;
885
+ }>;
886
+ }
887
+ export interface FileUploadUrlRequest {
888
+ count: number;
889
+ }
890
+ export interface FileUploadInfo {
891
+ url: string;
892
+ fileId: number;
893
+ token: string;
894
+ }
895
+ export interface FileUploadUrlResponse {
896
+ info: FileUploadInfo[];
897
+ }
898
+ export interface FileDownloadUrlRequest {
899
+ fileId: number;
900
+ chatId: number;
901
+ messageId: string;
902
+ }
903
+ export interface FileDownloadUrlResponse {
904
+ unsafe: boolean;
905
+ url: string;
906
+ }
907
+ export interface ExternalVideoResolveRequest {
908
+ videoId: string;
909
+ token: string;
910
+ chatId: number;
911
+ messageId: string;
912
+ }
913
+ export interface ExternalVideoResolveResponse {
914
+ EXTERNAL?: string;
915
+ cache?: boolean;
916
+ MP4_1080?: string;
917
+ MP4_720?: string;
918
+ MP4_480?: string;
919
+ MP4_240?: string;
920
+ [quality: string]: string | boolean | undefined;
921
+ }
922
+ export interface FileUploadDonePush {
923
+ fileId: number | string;
924
+ }
925
+ export type StickerPackActionType = 'FAVORITE_STICKER_SET' | 'UNFAVORITE_STICKER_SET' | string;
926
+ export interface StickerPackActionRequest {
927
+ type: StickerPackActionType;
928
+ id: number | string;
929
+ }
930
+ export interface StickerPackActionResponse {
931
+ success: boolean;
932
+ updateTime: number;
933
+ }
934
+ export interface StickerRecentsPush {
935
+ recentsList?: Array<{
936
+ type: string;
937
+ id?: number | string;
938
+ stickerId?: number | string;
939
+ }>;
940
+ type?: string;
941
+ emojiList?: string[];
942
+ recentEmojiList?: string[];
943
+ updateType?: 'ADDED' | 'REMOVED';
944
+ id?: number | string;
945
+ position?: number;
946
+ sync?: number;
947
+ }
948
+ export interface PhotoAttach extends MessageAttach {
949
+ _type: 'PHOTO';
950
+ photoToken: string;
951
+ }
952
+ export interface FileAttach extends MessageAttach {
953
+ _type: 'FILE';
954
+ fileId: number | string;
955
+ }
956
+ export interface StickerAttach extends MessageAttach {
957
+ _type: 'STICKER';
958
+ stickerId: number | string;
959
+ }
960
+ export interface ContactAttach extends MessageAttach {
961
+ _type: 'CONTACT';
962
+ contactId: number;
963
+ }
964
+ export interface PollAttach extends MessageAttach {
965
+ _type: 'POLL';
966
+ title: string;
967
+ answers: Array<{
968
+ text: string;
969
+ }>;
970
+ /** Bitmask: 4 = anonymous, 12 = anon+publicly visible voters, etc. */
971
+ settings: number;
972
+ }
973
+ /**
974
+ * Voice / audio message attach.
975
+ *
976
+ * Wire format (confirmed by on-the-wire capture of `ru.oneme.app` v26.15.1):
977
+ * - `_type: 'AUDIO'`
978
+ * - `token`: the **only** identifier — returned by the audio upload (op 82
979
+ * with `{uploaderType:1, type:2}` → POST to `au.oneme.ru/uploadAudio`).
980
+ * No `fileId` / `videoId` / `audioId` field is sent on the wire.
981
+ * - `duration`: in **milliseconds** (not seconds)
982
+ * - `wave`: raw 80-byte waveform energy buffer (one byte per slice)
983
+ */
984
+ export interface AudioAttach extends MessageAttach {
985
+ _type: 'AUDIO';
986
+ token: string;
987
+ duration: number;
988
+ wave?: Uint8Array;
989
+ }
990
+ /**
991
+ * Video attach.
992
+ *
993
+ * Wire format (confirmed by on-the-wire capture of `ru.oneme.app` v26.15.1):
994
+ * - `_type: 'VIDEO'`
995
+ * - `token`: returned by the upload (op 82 with `{uploaderType:0, type:1}`
996
+ * → POST to OK CDN). No `videoId` / `fileId` is sent in the attach.
997
+ * - `videoType`: `1` → circular **video note**; absent / `0` → regular clip
998
+ * - `thumbhash`: raw bytes (may be empty `b''`) — preview hash
999
+ *
1000
+ * Use {@link MaxClient.sendVideo} or {@link MaxClient.sendVideoNote}.
1001
+ */
1002
+ export interface VideoAttach extends MessageAttach {
1003
+ _type: 'VIDEO';
1004
+ token: string;
1005
+ videoType?: number;
1006
+ thumbhash?: Uint8Array;
1007
+ duration?: number;
1008
+ width?: number;
1009
+ height?: number;
1010
+ }
1011
+ /**
1012
+ * Geolocation attach (op 64 with `_type:'LOCATION'`). The receiver client
1013
+ * shows a map preview centred at the coords.
1014
+ */
1015
+ export interface LocationAttach extends MessageAttach {
1016
+ _type: 'LOCATION';
1017
+ latitude: number;
1018
+ longitude: number;
1019
+ /** Optional human-readable label (e.g. "Red Square"). */
1020
+ name?: string;
1021
+ /** Optional street address. */
1022
+ address?: string;
1023
+ }
1024
+ export interface PollAnswerInfo {
1025
+ answerId: number;
1026
+ text?: string;
1027
+ options?: number;
1028
+ votes?: Array<{
1029
+ userId: number;
1030
+ timestamp: number;
1031
+ }>;
1032
+ voteCount?: number;
1033
+ rate?: number;
1034
+ }
1035
+ export interface PollState {
1036
+ result: PollAnswerInfo[];
1037
+ voterPreviewIds?: number[];
1038
+ total: number;
1039
+ }
1040
+ export interface PollVoteRequest {
1041
+ chatId: number;
1042
+ messageId: string;
1043
+ pollId: number | string;
1044
+ answersIds: number[];
1045
+ }
1046
+ export interface PollVoteResponse {
1047
+ state: PollState;
1048
+ }
1049
+ export interface PollGetRequest {
1050
+ chatId: number;
1051
+ polls: Array<{
1052
+ messageId: string;
1053
+ pollId: number | string;
1054
+ }>;
1055
+ }
1056
+ export interface PollInfo {
1057
+ pollId: number | string;
1058
+ _type: 'POLL';
1059
+ title: string;
1060
+ settings: number;
1061
+ version: number;
1062
+ answers: PollAnswerInfo[];
1063
+ state: PollState;
1064
+ }
1065
+ export interface PollGetResponse {
1066
+ polls: PollInfo[];
1067
+ }
1068
+ export interface BotMiniAppOpenRequest {
1069
+ botId: number;
1070
+ chatId: number;
1071
+ }
1072
+ export interface BotMiniAppOpenResponse {
1073
+ query_id?: string;
1074
+ url: string;
1075
+ }
1076
+ export interface ComplainReason {
1077
+ reasonTitle: string;
1078
+ reasonId: number | string;
1079
+ }
1080
+ export interface ComplainCategory {
1081
+ typeId: number;
1082
+ reasons: ComplainReason[];
1083
+ }
1084
+ export interface ComplainsSyncResponse {
1085
+ complains: ComplainCategory[];
1086
+ complainSync: number;
1087
+ }
1088
+ export interface ChatFolder {
1089
+ id: string;
1090
+ sourceId?: string;
1091
+ options: number[];
1092
+ filters: number[];
1093
+ updateTime: number;
1094
+ title: string;
1095
+ include?: number[];
1096
+ favorites?: number[];
1097
+ }
1098
+ export interface FoldersGetRequest {
1099
+ folderIds: string[];
1100
+ }
1101
+ export interface FoldersGetResponse {
1102
+ folders: ChatFolder[];
1103
+ }
1104
+ export interface FolderUpsertRequest {
1105
+ id: string;
1106
+ title: string;
1107
+ include: number[];
1108
+ filters: number[];
1109
+ options: number[];
1110
+ favorites: number[];
1111
+ }
1112
+ export interface FolderUpsertResponse {
1113
+ folderSync?: number;
1114
+ folder: ChatFolder;
1115
+ foldersOrder?: string[];
1116
+ }
1117
+ export interface FoldersOrderRequest {
1118
+ folderIds: string[];
1119
+ }
1120
+ export interface FoldersOrderResponse {
1121
+ foldersOrder: string[];
1122
+ folderSync?: number;
1123
+ }
1124
+ export interface ChatReactionsSettingsGetRequest {
1125
+ chatIds: number[];
1126
+ }
1127
+ export interface ChatReactionsSettingsGetResponse {
1128
+ chatReactionsSettings: ChatReactionsSettings[];
1129
+ }
1130
+ export interface EventLogItem {
1131
+ type: string;
1132
+ userId?: number;
1133
+ time?: number;
1134
+ sessionId?: string;
1135
+ event: string;
1136
+ params?: Record<string, unknown>;
1137
+ }
1138
+ export interface EventLogRequest {
1139
+ events: EventLogItem[];
1140
+ }
1141
+ //# sourceMappingURL=types.d.ts.map