webmaxsocket 1.0.0 → 1.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.
package/README.md CHANGED
@@ -2,13 +2,15 @@
2
2
 
3
3
  ## 📖 Описание / Description
4
4
 
5
- **WebMaxSocket** — async Node.js библиотека для работы с внутренним API мессенджера Max. Позволяет создавать WebSocket соединение с **QR-кодом авторизацией**.
5
+ **WebMaxSocket** — async Node.js библиотека для работы с внутренним API мессенджера Max. Поддерживает **QR-код авторизацию**, **Token авторизацию**, и работу через **WebSocket** (WEB) или **TCP Socket** (IOS/ANDROID).
6
6
 
7
7
  ## ✨ Особенности / Features
8
8
 
9
9
  - ✅ **QR-код авторизация** / QR code authentication
10
- - ✅ **WebSocket соединение** / WebSocket connection
10
+ - ✅ **Token авторизация** / Token authentication
11
+ - ✅ **Два транспорта:** WebSocket (WEB) и TCP Socket (IOS/ANDROID)
11
12
  - ✅ **Автоматическое сохранение сессий** / Automatic session storage
13
+ - ✅ **Автовыбор транспорта** после QR-авторизации (переход на TCP)
12
14
  - ✅ **Отправка и получение сообщений** / Send and receive messages
13
15
  - ✅ **Редактирование и удаление сообщений** / Edit and delete messages
14
16
  - ✅ **Event-driven архитектура** / Event-driven architecture
@@ -21,6 +23,16 @@
21
23
  npm install webmaxsocket
22
24
  ```
23
25
 
26
+ ### Зависимости для Socket транспорта (IOS/ANDROID)
27
+
28
+ Для работы с TCP Socket транспортом требуется библиотека `lz4`. Если при установке возникают проблемы с `node-gyp`:
29
+
30
+ ```bash
31
+ npm install lz4 --ignore-scripts
32
+ ```
33
+
34
+ **Примечание:** Для обычной QR-авторизации (WEB) дополнительные зависимости не нужны. Socket транспорт используется только после сохранения сессии или при явном указании `deviceType: 'IOS'`/`'ANDROID'`.
35
+
24
36
  ## 🚀 Быстрый старт / Quick Start
25
37
 
26
38
  ### Базовый пример / Basic Example
@@ -63,9 +75,9 @@ main().catch(console.error);
63
75
 
64
76
  ### Авторизация / Authentication
65
77
 
66
- При первом запуске вы увидите QR-код в консоли:
78
+ #### Способ 1: QR-код (рекомендуется для первого запуска)
67
79
 
68
- On first run, you'll see a QR code in the console:
80
+ При первом запуске вы увидите QR-код в консоли:
69
81
 
70
82
  ```
71
83
  🔐 АВТОРИЗАЦИЯ ЧЕРЕЗ QR-КОД
@@ -76,15 +88,76 @@ On first run, you'll see a QR code in the console:
76
88
  📸 Отсканируйте QR-код
77
89
 
78
90
  █████████████████████████████
79
- █████████████████████████████
80
- ████ ▄▄▄▄▄ █▀█ █▄▄█ ▄▄▄▄▄ ████
81
- ████ █ █ █▀▀▀█ ▄█ █ █ ████
82
91
  ...
83
92
  ```
84
93
 
85
- После сканирования токен сохраняется автоматически.
94
+ После сканирования:
95
+ - Токен и clientSessionId сохраняются автоматически
96
+ - При следующем запуске клиент **автоматически переключится на TCP Socket** для стабильности
97
+ - Повторная авторизация не требуется
98
+
99
+ #### Способ 2: SMS авторизация (IOS/ANDROID)
100
+
101
+ Авторизация по номеру телефона с кодом из SMS:
102
+
103
+ ```javascript
104
+ const client = new WebMaxClient({
105
+ name: 'my_session',
106
+ deviceType: 'IOS' // Обязательно для SMS авторизации
107
+ });
108
+
109
+ await client.connect();
110
+
111
+ // Запрос кода
112
+ const authSession = await client.authorizeBySMS('+79001234567');
113
+
114
+ // Получаем код из SMS и отправляем
115
+ const code = '123456'; // Код из SMS
116
+ await authSession.sendCode(code);
117
+
118
+ // Завершаем запуск
119
+ await client.triggerHandlers(client.handlers.START);
120
+ ```
121
+
122
+ Или запустите готовый пример:
123
+
124
+ ```bash
125
+ node example-sms.js
126
+ node example-sms.js +79001234567 # с номером в аргументе
127
+ ```
128
+
129
+ #### Способ 3: Token авторизация
130
+
131
+ Если у вас уже есть токен (от другого сервиса/приложения):
132
+
133
+ ```javascript
134
+ const client = new WebMaxClient({
135
+ name: 'my_session',
136
+ token: 'An_Sx6HQ9HDiftNkVBNf6Q5PG5D8Oyj...', // Ваш токен
137
+ configPath: 'config/myconfig.json', // Или из файла
138
+ saveToken: true
139
+ });
140
+
141
+ await client.start();
142
+ ```
143
+
144
+ Формат конфига (`config/default.json`):
145
+ ```json
146
+ {
147
+ "token": "An_Sx6HQ9HDiftNk...",
148
+ "ua": "Mozilla/5.0 (iPhone...)",
149
+ "device_type": 2,
150
+ "deviceType": "IOS"
151
+ }
152
+ ```
153
+
154
+ #### Транспорты
86
155
 
87
- After scanning, the token is saved automatically.
156
+ - **WEB** (`deviceType: 'WEB'` или `device_type: 1`) → WebSocket (ws-api.oneme.ru)
157
+ - **IOS** (`deviceType: 'IOS'` или `device_type: 2`) → TCP Socket (api.oneme.ru)
158
+ - **ANDROID** (`deviceType: 'ANDROID'` или `device_type: 3`) → TCP Socket (api.oneme.ru)
159
+
160
+ Клиент **автоматически выбирает** правильный транспорт на основе сохраненного deviceType.
88
161
 
89
162
  ## API
90
163
 
@@ -97,7 +170,11 @@ After scanning, the token is saved automatically.
97
170
  ```javascript
98
171
  const client = new WebMaxClient({
99
172
  name: 'session', // Имя сессии (для сохранения авторизации)
100
- phone: '+1234567890', // Номер телефона
173
+ token: 'An_Sx6H...', // Токен авторизации (опционально)
174
+ configPath: 'myconfig', // Путь к config файлу (опционально)
175
+ deviceType: 'WEB', // Тип устройства: 'WEB', 'IOS', 'ANDROID' (опционально)
176
+ saveToken: true, // Сохранять токен в сессию (по умолчанию true)
177
+ debug: false, // Отладочный режим (опционально)
101
178
  apiUrl: 'wss://...', // URL WebSocket API (опционально)
102
179
  maxReconnectAttempts: 5,// Максимальное количество попыток переподключения
103
180
  reconnectDelay: 3000 // Задержка между попытками переподключения (мс)
@@ -114,9 +191,24 @@ const client = new WebMaxClient({
114
191
  await client.start();
115
192
  ```
116
193
 
194
+ ##### `authorizeBySMS(phone)`
195
+
196
+ Авторизация по номеру телефона через SMS (только для IOS/ANDROID).
197
+
198
+ ```javascript
199
+ // Подключаемся
200
+ await client.connect();
201
+
202
+ // Запрашиваем код
203
+ const authSession = await client.authorizeBySMS('+79001234567');
204
+
205
+ // Вводим код из SMS
206
+ await authSession.sendCode('123456');
207
+ ```
208
+
117
209
  ##### `sendMessage(options)`
118
210
 
119
- Отправляет сообщение в чат.
211
+ Отправляет сообщение в чат с уведомлением (notify: true).
120
212
 
121
213
  ```javascript
122
214
  const message = await client.sendMessage({
@@ -128,6 +220,20 @@ const message = await client.sendMessage({
128
220
  });
129
221
  ```
130
222
 
223
+ ##### `sendMessageChannel(options)`
224
+
225
+ Отправляет сообщение в канал без уведомления (notify: false).
226
+
227
+ ```javascript
228
+ const message = await client.sendMessageChannel({
229
+ chatId: 123,
230
+ text: 'Сообщение в канал',
231
+ cid: Date.now(),
232
+ replyTo: null, // ID сообщения для ответа (опционально)
233
+ attachments: [] // Вложения (опционально)
234
+ });
235
+ ```
236
+
131
237
  ##### `editMessage(options)`
132
238
 
133
239
  Редактирует сообщение.
@@ -362,22 +468,94 @@ ChatActions.RECORDING_VOICE // Записывает голосовое
362
468
  ChatActions.RECORDING_VIDEO // Записывает видео
363
469
  ```
364
470
 
471
+ ### MaxSocketTransport
472
+
473
+ Низкоуровневый TCP Socket транспорт для IOS/ANDROID (api.oneme.ru).
474
+
475
+ #### Прямое использование (advanced)
476
+
477
+ ```javascript
478
+ const { MaxSocketTransport } = require('webmaxsocket');
479
+
480
+ const transport = new MaxSocketTransport({
481
+ deviceType: 'IOS',
482
+ ua: 'Mozilla/5.0 (iPhone...)',
483
+ deviceId: 'your-device-id',
484
+ debug: true
485
+ });
486
+
487
+ await transport.connect();
488
+ await transport.handshake(userAgentPayload);
489
+ const syncData = await transport.sync(token, userAgent);
490
+ ```
491
+
492
+ **Примечание:** В большинстве случаев используйте `WebMaxClient`, который автоматически выбирает нужный транспорт.
493
+
494
+ ## 📚 Примеры
495
+
496
+ ### Пример 1: QR-авторизация (example.js)
497
+
498
+ ```bash
499
+ node example.js
500
+ ```
501
+
502
+ Первый запуск - QR-авторизация, повторные запуски - автоматический вход через TCP Socket.
503
+
504
+ ### Пример 2: Token авторизация (example-token.js)
505
+
506
+ ```bash
507
+ # Через config файл
508
+ node example-token.js
509
+ node example-token.js myconfig # config/myconfig.json
510
+
511
+ # Через переменную окружения
512
+ TOKEN="ваш_токен" node example-token.js
513
+ ```
514
+
515
+ ### Пример 3: SMS авторизация (example-sms.js)
516
+
517
+ ```bash
518
+ # Интерактивный ввод номера
519
+ node example-sms.js
520
+
521
+ # С номером в аргументе
522
+ node example-sms.js +79001234567
523
+ ```
524
+
525
+ ### Пример 4: IOS/ANDROID Socket (example-ios.js)
526
+
527
+ ```bash
528
+ # С готовым конфигом
529
+ node example-ios.js
530
+
531
+ # С отладкой
532
+ node example-ios.js --debug
533
+ ```
534
+
365
535
  ## Структура проекта
366
536
 
367
537
  ```
368
538
  webmaxsocket/
369
539
  ├── lib/
370
540
  │ ├── client.js # Основной клиент
541
+ │ ├── socketTransport.js # TCP Socket транспорт
371
542
  │ ├── session.js # Управление сессиями
543
+ │ ├── userAgent.js # UserAgent генератор
544
+ │ ├── opcodes.js # Протокол опкоды
372
545
  │ ├── constants.js # Константы
373
546
  │ └── entities/
374
547
  │ ├── User.js # Класс пользователя
375
548
  │ ├── Message.js # Класс сообщения
376
549
  │ ├── ChatAction.js # Класс действия в чате
377
550
  │ └── index.js # Экспорт сущностей
551
+ ├── config/ # Конфигурационные файлы
552
+ │ └── example.json # Пример конфига
378
553
  ├── sessions/ # Директория с сохраненными сессиями
379
554
  ├── index.js # Точка входа
380
- ├── example.js # Пример использования
555
+ ├── example.js # QR-авторизация
556
+ ├── example-token.js # Token авторизация
557
+ ├── example-sms.js # SMS авторизация
558
+ ├── example-ios.js # IOS/ANDROID Socket
381
559
  ├── package.json
382
560
  └── README.md
383
561
  ```
@@ -408,4 +586,52 @@ try {
408
586
  } catch (error) {
409
587
  console.error('Ошибка:', error.message);
410
588
  }
411
- ```
589
+ ```
590
+
591
+ ## 🔧 Отладка / Debug
592
+
593
+ Для включения отладочного вывода:
594
+
595
+ ```javascript
596
+ const client = new WebMaxClient({
597
+ name: 'my_session',
598
+ debug: true // или process.env.DEBUG = '1'
599
+ });
600
+ ```
601
+
602
+ Или через переменную окружения:
603
+
604
+ ```bash
605
+ DEBUG=1 node example.js
606
+ ```
607
+
608
+ ## 💡 Важные замечания
609
+
610
+ 1. **TCP Socket после QR-авторизации:** После первой успешной QR-авторизации клиент автоматически сохраняет `clientSessionId` и переключается на TCP Socket транспорт при следующем запуске для повышения стабильности.
611
+
612
+ 2. **Разница между sendMessage и sendMessageChannel:**
613
+ - `sendMessage()` - отправка с уведомлением (notify: true) для обычных чатов
614
+ - `sendMessageChannel()` - отправка без уведомления (notify: false) для каналов
615
+
616
+ 3. **Автоматический выбор транспорта:** Клиент автоматически определяет какой транспорт использовать на основе `deviceType` в сессии или config файле.
617
+
618
+ ## 🔗 Ссылки / Links
619
+
620
+ - [GitHub Repository](https://github.com/Tellarion/webmaxsocket)
621
+ - [NPM Package](https://www.npmjs.com/package/webmaxsocket)
622
+
623
+ ## 📄 Лицензия / License
624
+
625
+ MIT License - see LICENSE file for details
626
+
627
+ ## 👤 Автор / Author
628
+
629
+ Tellarion - [tellarion.dev](https://tellarion.dev)
630
+
631
+ ## 💝 Поддержка / Support
632
+
633
+ Если вам нравится эта библиотека и вы хотите поддержать разработку:
634
+
635
+ **USDT (TRC20):** `TXfs1iVbp2aLd3rbc4cenVzMoTevP5RbBE`
636
+
637
+ Спасибо за вашу поддержку!
@@ -0,0 +1,6 @@
1
+ {
2
+ "token": "YOUR_TOKEN_HERE",
3
+ "ua": "Mozilla/5.0 (iPhone15,2; CPU iPhone OS 18_6_2 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/602.1.50",
4
+ "device_type": 2,
5
+ "deviceType": "IOS"
6
+ }
package/example-ios.js ADDED
@@ -0,0 +1,186 @@
1
+ /**
2
+ * IOS/ANDROID: вход через Socket (api.oneme.ru), не WebSocket
3
+ * WEB: через WebSocket (ws-api.oneme.ru)
4
+ *
5
+ * С готовым конфигом: node example-ios.js
6
+ * Без токена — запрос телефона и SMS
7
+ */
8
+
9
+ const path = require('path');
10
+ const fs = require('fs');
11
+ const { WebMaxClient, MaxSocketTransport } = require('./index');
12
+ const { UserAgentPayload } = require('./lib/userAgent');
13
+ const { Opcode } = require('./lib/opcodes');
14
+
15
+ const argv = process.argv.slice(2).filter((a) => a !== '--debug' && a !== '-d');
16
+ if (process.argv.includes('--debug') || process.argv.includes('-d')) process.env.DEBUG = '1';
17
+ const CONFIG_NAME = argv[0] || process.env.CONFIG || 'default';
18
+
19
+ function loadConfig() {
20
+ const base = path.join(process.cwd(), 'config');
21
+ const p = path.join(base, CONFIG_NAME + (CONFIG_NAME.endsWith('.json') ? '' : '.json'));
22
+ if (!fs.existsSync(p)) return null;
23
+ return JSON.parse(fs.readFileSync(p, 'utf8'));
24
+ }
25
+
26
+ function configToUserAgent(config) {
27
+ const dt = config.deviceType || (config.device_type === 2 ? 'IOS' : config.device_type === 3 ? 'ANDROID' : 'WEB');
28
+ return new UserAgentPayload({
29
+ deviceType: dt,
30
+ locale: config.locale || 'ru',
31
+ deviceLocale: config.deviceLocale || config.locale || 'ru',
32
+ osVersion: config.osVersion || '18.6.2',
33
+ deviceName: config.deviceName || 'Safari',
34
+ headerUserAgent: config.headerUserAgent || config.ua || '',
35
+ appVersion: config.appVersion || '25.12.14',
36
+ screen: config.screen || '390x844 3.0x',
37
+ timezone: config.timezone || 'Europe/Moscow',
38
+ buildNumber: config.buildNumber,
39
+ clientSessionId: config.clientSessionId,
40
+ release: config.release
41
+ });
42
+ }
43
+
44
+ function useSocket(config) {
45
+ const dt = config.deviceType || config.device_type;
46
+ return dt === 'IOS' || dt === 'ANDROID' || dt === 2 || dt === 3;
47
+ }
48
+
49
+ async function main() {
50
+ const config = loadConfig();
51
+ const hasToken = config && config.token && config.token.length >= 50;
52
+
53
+ if (hasToken && useSocket(config)) {
54
+ console.log('🚀 Socket (api.oneme.ru) — IOS/ANDROID\n');
55
+ const ua = configToUserAgent(config);
56
+ const transport = new MaxSocketTransport({
57
+ deviceType: config.deviceType || (config.device_type === 2 ? 'IOS' : 'ANDROID'),
58
+ ua: config.headerUserAgent || config.ua,
59
+ deviceId: config.deviceId || require('uuid').v4(),
60
+ debug: process.env.DEBUG === '1'
61
+ });
62
+
63
+ transport.onNotification = (data) => {
64
+ if (data.opcode === Opcode.NOTIF_MESSAGE && data.payload) {
65
+ const m = data.payload;
66
+ if (m.senderId !== transport.me?.id) {
67
+ console.log('💬', (m.sender?.firstName || 'User') + ':', m.text || '[вложение]');
68
+ }
69
+ }
70
+ };
71
+
72
+ await transport.connect();
73
+ await transport.handshake(ua);
74
+
75
+ const syncResp = await transport.sync(config.token, ua.toJSON());
76
+
77
+ if (process.env.DEBUG === '1') {
78
+ const s = JSON.stringify(syncResp, null, 2);
79
+ console.log('\n📋 Sync (сырой):', s.slice(0, 3000) + (s.length > 3000 ? '\n...' : ''));
80
+ }
81
+ console.log('\n📋 Ключи sync:', Object.keys(syncResp || {}).join(', '));
82
+
83
+ const contact = syncResp?.profile?.contact ?? syncResp?.profile?.user ?? syncResp?.contact;
84
+ if (contact) {
85
+ const names = contact.names || [];
86
+ const name = Array.isArray(names) ? names[0] : names;
87
+ const first = name?.firstName ?? name?.name ?? '';
88
+ const last = name?.lastName ?? '';
89
+ transport.me = {
90
+ id: contact.id,
91
+ firstname: first,
92
+ lastname: last,
93
+ fullname: [first, last].filter(Boolean).join(' ') || 'User'
94
+ };
95
+ console.log('\n👤 Профиль:');
96
+ console.log(' ID:', contact.id);
97
+ console.log(' Имя:', transport.me.fullname);
98
+ console.log(' Телефон:', contact.phone ? '+' + contact.phone : '—');
99
+ }
100
+
101
+ const syncChats = syncResp?.chats ?? syncResp?.chatList ?? syncResp?.list ?? [];
102
+ const chats = await transport.getChats();
103
+ const allChats = syncChats.length ? syncChats : chats;
104
+ console.log('\n📂 Диалоги (' + allChats.length + '):');
105
+ allChats.slice(0, 20).forEach((c, i) => {
106
+ const t = c.title ?? c.name ?? c.chat?.title ?? ('Chat ' + (c.id ?? c.chatId ?? i));
107
+ const lastMsg = c.lastMessage?.text ?? c.lastMessage?.message ?? '—';
108
+ console.log(` ${i + 1}. ${t} — ${String(lastMsg).slice(0, 35)}`);
109
+ });
110
+ if (allChats.length > 20) console.log(' ... и ещё', allChats.length - 20);
111
+
112
+ const contacts = syncResp?.contacts || [];
113
+ if (contacts.length) {
114
+ console.log('\n📇 Контакты:', contacts.length);
115
+ }
116
+
117
+ console.log('\n🤖 Socket работает (Ctrl+C — выход)\n');
118
+ process.on('SIGINT', () => { transport.close(); process.exit(0); });
119
+ return;
120
+ }
121
+
122
+ if (hasToken) {
123
+ const client = new WebMaxClient({
124
+ name: 'web_session',
125
+ configPath: CONFIG_NAME,
126
+ saveToken: false,
127
+ debug: process.env.DEBUG === '1'
128
+ });
129
+ client.onStart(async () => {
130
+ if (client.me) console.log('\n✅ Вход:', client.me.fullname || client.me.firstname, '(ID:', client.me.id + ')\n');
131
+ try { console.log('📂 Диалогов:', (await client.getChats()).length); } catch (e) { console.log('⚠️', e.message); }
132
+ });
133
+ client.onMessage((m) => { if (m.senderId !== client.me?.id) console.log('💬', m.getSenderName() + ':', m.text); });
134
+ client.onError((e) => console.error('❌', e.message));
135
+ await client.start();
136
+ console.log('🤖 Бот работает (Ctrl+C — выход)\n');
137
+ return;
138
+ }
139
+
140
+ const readline = require('readline');
141
+ const { v4: uuidv4 } = require('uuid');
142
+ const IOS_UA = 'Mozilla/5.0 (iPhone15,2; CPU iPhone OS 18_6_2 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/602.1.50';
143
+
144
+ function ask(q) {
145
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
146
+ return new Promise((r) => rl.question(q, (a) => { rl.close(); r(a.trim()); }));
147
+ }
148
+
149
+ console.log('📱 Получение токена по телефону (Socket)\n');
150
+ const phone = await ask('Номер (+79xxxxxxxxx): ');
151
+ if (!/^\+?\d{10,15}$/.test(phone.replace(/\s/g, ''))) { console.error('❌ Неверный формат'); process.exit(1); }
152
+ let clean = phone.replace(/\D/g, '');
153
+ if (clean.startsWith('8') && clean.length === 11) clean = '7' + clean.slice(1);
154
+ else if (clean.startsWith('9') && clean.length === 10) clean = '7' + clean;
155
+ const norm = '+' + clean;
156
+
157
+ const transport = new MaxSocketTransport({ deviceType: 'IOS', ua: IOS_UA, deviceId: uuidv4(), debug: process.env.DEBUG === '1' });
158
+ await transport.connect();
159
+ await transport.handshake(new UserAgentPayload({ deviceType: 'IOS', headerUserAgent: IOS_UA, appVersion: '25.12.14', osVersion: '18.6.2', deviceName: 'Safari', screen: '390x844 3.0x', locale: 'ru', deviceLocale: 'ru', timezone: 'Europe/Moscow' }));
160
+
161
+ console.log('📤 Запрос кода...');
162
+ const tempToken = await transport.requestCode(norm);
163
+ if (!tempToken) throw new Error('Не получен временный токен');
164
+ const code = await ask('Код из SMS (6 цифр): ');
165
+ if (!/^\d{6}$/.test(code)) throw new Error('Неверный код');
166
+
167
+ const authResp = await transport.sendCode(tempToken, code);
168
+ const token = authResp?.tokenAttrs?.LOGIN?.token;
169
+ if (!token) throw new Error(authResp?.passwordChallenge ? '2FA не поддерживается' : 'Токен не получен');
170
+ await transport.close();
171
+
172
+ const cfg = { token, ua: IOS_UA, device_type: 2, deviceType: 'IOS' };
173
+ const dir = path.join(process.cwd(), 'config');
174
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
175
+ fs.writeFileSync(path.join(dir, CONFIG_NAME + '.json'), JSON.stringify(cfg, null, 2), 'utf8');
176
+ console.log('\n✅ Конфиг сохранён:', path.join(dir, CONFIG_NAME + '.json'));
177
+ console.log(' Запуск: node example-ios.js', CONFIG_NAME);
178
+ }
179
+
180
+ main().catch((e) => { console.error('❌', e.message); process.exit(1); });
181
+ process.on('SIGINT', () => {
182
+ console.log('\n\n👋 Завершение работы...');
183
+ console.log('\n💝 Нравится библиотека? Поддержите разработку:');
184
+ console.log(' USDT (TRC20): TXfs1iVbp2aLd3rbc4cenVzMoTevP5RbBE');
185
+ process.exit(0);
186
+ });
package/example-sms.js ADDED
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Пример авторизации по SMS (IOS/ANDROID)
3
+ *
4
+ * Использование:
5
+ * node example-sms.js
6
+ * node example-sms.js +79001234567 # с номером в аргументе
7
+ */
8
+
9
+ const readline = require('readline');
10
+ const { WebMaxClient } = require('./index');
11
+
12
+ function ask(question) {
13
+ const rl = readline.createInterface({
14
+ input: process.stdin,
15
+ output: process.stdout
16
+ });
17
+ return new Promise((resolve) => {
18
+ rl.question(question, (answer) => {
19
+ rl.close();
20
+ resolve(answer.trim());
21
+ });
22
+ });
23
+ }
24
+
25
+ async function main() {
26
+ // Получаем номер телефона из аргумента или запрашиваем
27
+ let phone = process.argv[2];
28
+
29
+ if (!phone) {
30
+ phone = await ask('📱 Введите номер телефона (+79001234567): ');
31
+ }
32
+
33
+ // Валидация номера
34
+ if (!/^\+?\d{10,15}$/.test(phone.replace(/\s/g, ''))) {
35
+ console.error('❌ Неверный формат номера телефона');
36
+ process.exit(1);
37
+ }
38
+
39
+ console.log('\n🚀 Запуск клиента с SMS авторизацией...\n');
40
+
41
+ // Создаем клиент с IOS deviceType для SMS авторизации
42
+ const client = new WebMaxClient({
43
+ name: 'sms_session',
44
+ deviceType: 'IOS', // Обязательно для SMS авторизации
45
+ debug: process.env.DEBUG === '1'
46
+ });
47
+
48
+ // Обработчик запуска
49
+ client.onStart(async () => {
50
+ if (client.me) {
51
+ console.log('\n📋 ДАННЫЕ ПОЛЬЗОВАТЕЛЯ:');
52
+ console.log('─'.repeat(40));
53
+ console.log(`👤 Имя: ${client.me.fullname || client.me.firstname}`);
54
+ console.log(`🆔 ID: ${client.me.id}`);
55
+ console.log(`📱 Телефон: +${client.me.phone || '—'}`);
56
+ }
57
+
58
+ try {
59
+ const chats = await client.getChats();
60
+ console.log(`\n📂 Диалогов: ${chats.length}`);
61
+ } catch (e) {
62
+ console.log('⚠️ Не удалось загрузить диалоги:', e.message);
63
+ }
64
+ });
65
+
66
+ // Обработчик сообщений
67
+ client.onMessage(async (message) => {
68
+ if (message.senderId === client.me?.id) return;
69
+ console.log(`\n💬 ${message.getSenderName()}: ${message.text}`);
70
+
71
+ await message.reply({
72
+ text: 'Автоответ: сообщение получено!',
73
+ cid: Date.now()
74
+ });
75
+ console.log('✅ Отправлен автоответ');
76
+ });
77
+
78
+ client.onError((err) => console.error('❌', err.message));
79
+
80
+ try {
81
+ // Подключаемся
82
+ await client.connect();
83
+
84
+ // Проверяем есть ли сохраненный токен
85
+ const savedToken = client.session.get('token');
86
+
87
+ if (savedToken) {
88
+ console.log('✅ Найдена сохраненная сессия, вход по токену...\n');
89
+ client._token = savedToken;
90
+ await client.sync();
91
+ client.isAuthorized = true;
92
+ } else {
93
+ // SMS авторизация
94
+ console.log('📱 Требуется SMS авторизация\n');
95
+ const authSession = await client.authorizeBySMS(phone);
96
+
97
+ // Запрашиваем код
98
+ const code = await ask('\n📲 Введите код из SMS (6 цифр): ');
99
+
100
+ if (!/^\d{6}$/.test(code)) {
101
+ console.error('❌ Неверный формат кода');
102
+ process.exit(1);
103
+ }
104
+
105
+ // Отправляем код и завершаем авторизацию
106
+ await authSession.sendCode(code);
107
+ }
108
+
109
+ // Запускаем обработчики start
110
+ await client.triggerHandlers(client.handlers.START);
111
+
112
+ console.log('\n✅ Клиент запущен успешно!');
113
+ console.log('🤖 Бот работает (Ctrl+C — выход)\n');
114
+
115
+ } catch (error) {
116
+ console.error('❌ Ошибка:', error.message);
117
+ process.exit(1);
118
+ }
119
+ }
120
+
121
+ process.on('SIGINT', () => {
122
+ console.log('\n\n👋 Завершение работы...');
123
+ console.log('\n💝 Нравится библиотека? Поддержите разработку:');
124
+ console.log(' USDT (TRC20): TXfs1iVbp2aLd3rbc4cenVzMoTevP5RbBE');
125
+ process.exit(0);
126
+ });
127
+
128
+ main().catch((error) => {
129
+ console.error('❌ Критическая ошибка:', error);
130
+ process.exit(1);
131
+ });