webmaxsocket 1.1.3 → 1.1.5
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 +87 -4
- package/api.package.md +193 -0
- package/index.js +3 -1
- package/lib/client.js +1128 -27
- package/lib/opcodes.js +3 -8
- package/lib/qrWebLogin.js +59 -0
- package/lib/socketTransport.js +3 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
**WebMaxSocket** — async Node.js библиотека для работы с внутренним API мессенджера Max. Поддерживает **QR-код авторизацию**, **Token авторизацию**, и работу через **WebSocket** (WEB) или **TCP Socket** (IOS/ANDROID).
|
|
6
6
|
|
|
7
|
+
Сводка всех методов: **[api.package.md](./api.package.md)**.
|
|
8
|
+
|
|
7
9
|
## ✨ Особенности / Features
|
|
8
10
|
|
|
9
11
|
- ✅ **QR-код авторизация** / QR code authentication
|
|
@@ -13,7 +15,10 @@
|
|
|
13
15
|
- ✅ **Автоматическое сохранение сессий** / Automatic session storage
|
|
14
16
|
- ✅ **Автовыбор транспорта** после QR-авторизации (переход на TCP)
|
|
15
17
|
- ✅ **Отправка и получение сообщений** / Send and receive messages
|
|
18
|
+
- ✅ **Загрузка медиа с диска:** `uploadPhoto`, `uploadVideo`, `uploadFile`, `uploadAudio` → `attachments` в `sendMessage` / `sendMessageChannel` / `reply`
|
|
16
19
|
- ✅ **Скачивание вложений по URL** (`baseUrl` из `attaches`) во временный файл — `downloadUrlToTempFile`, `message.downloadAttachment()`
|
|
20
|
+
- ✅ **Группы и каналы:** создание, инвайты, админы, участники, ссылки, mute, подписка — см. раздел API
|
|
21
|
+
- ✅ **Реакции, пины, настройки профиля и приватности, контакты / блокировка**
|
|
17
22
|
- ✅ **Редактирование и удаление сообщений** / Edit and delete messages
|
|
18
23
|
- ✅ **Event-driven архитектура** / Event-driven architecture
|
|
19
24
|
- ✅ **Обработка входящих уведомлений** / Handle incoming notifications
|
|
@@ -288,14 +293,14 @@ const message = await client.sendMessage({
|
|
|
288
293
|
|
|
289
294
|
##### `sendMessageChannel(options)`
|
|
290
295
|
|
|
291
|
-
Отправляет сообщение в канал без уведомления (notify: false).
|
|
296
|
+
Отправляет сообщение в канал без уведомления (notify: false). Поля **`text`**, **`replyTo`**, **`attachments`** — те же, что у `sendMessage` (вложения из `uploadPhoto` / `uploadVideo` / `uploadFile` / `uploadAudio`).
|
|
292
297
|
|
|
293
298
|
```javascript
|
|
294
299
|
const message = await client.sendMessageChannel({
|
|
295
300
|
chatId: 123,
|
|
296
301
|
text: 'Сообщение в канал',
|
|
297
|
-
replyTo: null,
|
|
298
|
-
attachments: []
|
|
302
|
+
replyTo: null,
|
|
303
|
+
attachments: [] // опционально: [attach] после upload*
|
|
299
304
|
});
|
|
300
305
|
```
|
|
301
306
|
|
|
@@ -307,10 +312,57 @@ const message = await client.sendMessageChannel({
|
|
|
307
312
|
await client.editMessage({
|
|
308
313
|
messageId: 456,
|
|
309
314
|
chatId: 123,
|
|
310
|
-
text: 'Исправленный текст'
|
|
315
|
+
text: 'Исправленный текст',
|
|
316
|
+
attachments: [] // опционально, после upload*
|
|
311
317
|
});
|
|
312
318
|
```
|
|
313
319
|
|
|
320
|
+
##### Пины, реакции
|
|
321
|
+
|
|
322
|
+
| Метод | Назначение |
|
|
323
|
+
|--------|------------|
|
|
324
|
+
| `pinMessage({ chatId, messageId, notifyPin })` | Закрепить сообщение |
|
|
325
|
+
| `setMessageReaction({ chatId, messageId, emoji })` | Эмодзи-реакция |
|
|
326
|
+
| `cancelMessageReaction({ chatId, messageId })` | Снять реакцию |
|
|
327
|
+
| `getMessageReactions({ chatId, messageId, count })` | Список реакций |
|
|
328
|
+
|
|
329
|
+
##### Чаты, каналы, группы
|
|
330
|
+
|
|
331
|
+
| Метод | Назначение |
|
|
332
|
+
|--------|------------|
|
|
333
|
+
| `getChatInfo(chatIds)` | Информация по id (массив или одно число) |
|
|
334
|
+
| `resolveLink(link)` | Разрешить URL / `join/…` (LINK_INFO) |
|
|
335
|
+
| `joinChatByLink(link)` | Вступить по ссылке |
|
|
336
|
+
| `setChatSubscription(chatId, subscribe)` | Подписка на канал |
|
|
337
|
+
| `createGroup({ title, userIds })` | Новая группа |
|
|
338
|
+
| `createChannel({ title })` | Новый канал |
|
|
339
|
+
| `muteChat(chatId, mute)` | Уведомления чата (не беспокоить) |
|
|
340
|
+
| `getChatMembers({ chatId, marker, count, type })` | Участники (count ≤ 500) |
|
|
341
|
+
| `inviteToChat({ chatId, userIds, showHistory })` | Пригласить |
|
|
342
|
+
| `removeFromChat({ chatId, userIds, cleanMsgPeriod })` | Исключить |
|
|
343
|
+
| `addChatAdmins({ chatId, userIds, permissions })` | Выдать админку (по умолчанию `permissions: 120`) |
|
|
344
|
+
| `removeChatAdmins({ chatId, userIds })` | Снять админку |
|
|
345
|
+
| `transferChatOwnership({ chatId, newOwnerId })` | Передать владение |
|
|
346
|
+
| `setGroupOptions({ chatId, options })` | Настройки группы (`ALL_CAN_PIN_MESSAGE`, …) |
|
|
347
|
+
| `resolveChannelByUsername(username)` | Канал по @username |
|
|
348
|
+
| `joinChannelByUsername(username)` | Вступить по @username |
|
|
349
|
+
| `resolveInviteHash(hash)` | Инвайт по хэшу без префикса `join/` |
|
|
350
|
+
|
|
351
|
+
##### Контакты и профиль
|
|
352
|
+
|
|
353
|
+
| Метод | Назначение |
|
|
354
|
+
|--------|------------|
|
|
355
|
+
| `getContacts(contactIds)` | Несколько контактов (массив id) |
|
|
356
|
+
| `addContact(userId)` | В контакты |
|
|
357
|
+
| `blockUser(userId)` | Заблокировать |
|
|
358
|
+
| `updateProfile({ firstName, lastName, description })` | Своё имя / описание |
|
|
359
|
+
| `setHiddenOnline(hidden)` | Скрыть «в сети» |
|
|
360
|
+
| `setFindableByPhone(mode)` | `'ALL'` \| `'CONTACTS'` или boolean |
|
|
361
|
+
| `setCallsPrivacyMode(mode)` | Кто может звонить |
|
|
362
|
+
| `setChatsInvitePrivacy(mode)` | Кто может приглашать в чаты |
|
|
363
|
+
|
|
364
|
+
Часть методов требует прав в чате; ответы сервера зависят от роли и типа чата.
|
|
365
|
+
|
|
314
366
|
##### `deleteMessage(options)`
|
|
315
367
|
|
|
316
368
|
Удаляет сообщение.
|
|
@@ -334,6 +386,36 @@ await client.forwardMessage({
|
|
|
334
386
|
});
|
|
335
387
|
```
|
|
336
388
|
|
|
389
|
+
##### Загрузка медиа для `attachments`
|
|
390
|
+
|
|
391
|
+
Все методы ниже возвращают объект(ы), которые передаются в **`attachments`** у `sendMessage`, **`sendMessageChannel`** и **`message.reply`**. Нужен **Node.js 18+** (`fetch`, `FormData`). Схема: опкод загрузки → `UPLOAD_ATTACH_PREP` (65) → HTTP POST на выданный URL. Для **видео** и **файлов** после POST клиент ждёт **`NOTIF_ATTACH` (opcode 136)**.
|
|
392
|
+
|
|
393
|
+
| Метод | Результат для `attachments` |
|
|
394
|
+
|--------|-----------------------------|
|
|
395
|
+
| `uploadPhoto(chatId, filePath)` | `{ _type: 'PHOTO', photoToken }` |
|
|
396
|
+
| `uploadVideo(chatId, filePath)` | `{ _type: 'VIDEO', videoId, token }` |
|
|
397
|
+
| `uploadFile(chatId, filePath, options?)` | `{ _type: 'FILE', fileId }` — документы, архивы; `options`: `{ filename, mimeType }` |
|
|
398
|
+
| `uploadAudio(chatId, filePath)` | то же, что `uploadFile` с MIME для `.mp3`, `.ogg`, `.m4a`, `.wav`, … |
|
|
399
|
+
|
|
400
|
+
```javascript
|
|
401
|
+
const photo = await client.uploadPhoto(chatId, './a.png');
|
|
402
|
+
const video = await client.uploadVideo(chatId, './b.mp4');
|
|
403
|
+
const file = await client.uploadFile(chatId, './doc.pdf');
|
|
404
|
+
const audio = await client.uploadAudio(chatId, './track.mp3');
|
|
405
|
+
|
|
406
|
+
await client.sendMessage({
|
|
407
|
+
chatId,
|
|
408
|
+
text: 'Набор вложений',
|
|
409
|
+
attachments: [photo, video]
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
await client.sendMessageChannel({
|
|
413
|
+
chatId,
|
|
414
|
+
text: 'В канал с файлом',
|
|
415
|
+
attachments: [file]
|
|
416
|
+
});
|
|
417
|
+
```
|
|
418
|
+
|
|
337
419
|
##### `sendChatAction(chatId, action)`
|
|
338
420
|
|
|
339
421
|
Отправляет действие в чате (печатает, выбирает стикер и т.д.).
|
|
@@ -679,6 +761,7 @@ webmaxsocket/
|
|
|
679
761
|
├── example-sms.js # SMS авторизация
|
|
680
762
|
├── example-ios.js # IOS/ANDROID Socket
|
|
681
763
|
├── package.json
|
|
764
|
+
├── api.package.md # Справочник API (все методы)
|
|
682
765
|
└── README.md
|
|
683
766
|
```
|
|
684
767
|
|
package/api.package.md
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# WebMaxSocket — справочник API
|
|
2
|
+
|
|
3
|
+
Краткий перечень возможностей для работы с библиотекой. Подробности и примеры — в `README.md`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Экспорт пакета (`require('webmaxsocket')`)
|
|
8
|
+
|
|
9
|
+
| Символ | Описание |
|
|
10
|
+
|--------|----------|
|
|
11
|
+
| `WebMaxClient` | Основной клиент |
|
|
12
|
+
| `MaxSocketTransport` | Низкоуровневый TCP-транспорт |
|
|
13
|
+
| `User`, `Message`, `ChatAction` | Сущности |
|
|
14
|
+
| `ChatActions`, `EventTypes`, `MessageTypes` | Константы |
|
|
15
|
+
| `Opcode`, `getOpcodeName` | Опкоды протокола |
|
|
16
|
+
| `UserAgentPayload` | User-Agent для handshake |
|
|
17
|
+
| `downloadUrlToTempFile`, `extFromContentType`, `extFromAttachType` | Скачивание медиа по URL |
|
|
18
|
+
| `resolveIncomingLogMode`, `printIncomingLog` | Режим лога входящих |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## `WebMaxClient`
|
|
23
|
+
|
|
24
|
+
Клиент наследует `EventEmitter`: `on`, `once`, `emit`, `off` (в т.ч. событие `connected`, `raw_message`).
|
|
25
|
+
|
|
26
|
+
### Свойства (полезные)
|
|
27
|
+
|
|
28
|
+
| Свойство | Описание |
|
|
29
|
+
|----------|----------|
|
|
30
|
+
| `me` | Профиль после авторизации |
|
|
31
|
+
| `session` | Менеджер сессий |
|
|
32
|
+
| `isConnected`, `isAuthorized` | Состояние |
|
|
33
|
+
| `userAgent` | Текущий User-Agent |
|
|
34
|
+
| `deviceId` | ID устройства |
|
|
35
|
+
| `incomingLogMode` | `'off'` \| `'messages'` \| `'verbose'` |
|
|
36
|
+
|
|
37
|
+
### Запуск и соединение
|
|
38
|
+
|
|
39
|
+
| Метод | Описание |
|
|
40
|
+
|-------|----------|
|
|
41
|
+
| `start()` | Подключение, авторизация, обработчики `onStart` |
|
|
42
|
+
| `connect()` | Только соединение (низкоуровнево) |
|
|
43
|
+
| `connectWithSession()` | Сессия + синхронизация |
|
|
44
|
+
| `handshake()` | Handshake (WebSocket-путь) |
|
|
45
|
+
| `sync()` | LOGIN по токену |
|
|
46
|
+
| `fetchMyProfile()` | Загрузка `me` |
|
|
47
|
+
| `stop()` | Закрыть транспорт |
|
|
48
|
+
| `logout()` | Остановка + удаление сессии |
|
|
49
|
+
|
|
50
|
+
### Авторизация
|
|
51
|
+
|
|
52
|
+
| Метод | Описание |
|
|
53
|
+
|-------|----------|
|
|
54
|
+
| `authorize(phone?)` | Сценарий авторизации по умолчанию |
|
|
55
|
+
| `authorizeByQR()` | QR (WEB) |
|
|
56
|
+
| `authorizeBySMS(phone)` | SMS; возвращает `{ sendCode }` |
|
|
57
|
+
| `requestQR()` | Запрос QR |
|
|
58
|
+
| `checkQRStatus(trackId)` | Статус QR |
|
|
59
|
+
| `loginByQR(trackId)` | Завершение по QR |
|
|
60
|
+
| `pollQRStatus(...)` | Ожидание сканирования QR |
|
|
61
|
+
| `showLinkDeviceQR(options?)` | QR «подключить устройство» после входа |
|
|
62
|
+
|
|
63
|
+
### Сообщения
|
|
64
|
+
|
|
65
|
+
| Метод | Описание |
|
|
66
|
+
|-------|----------|
|
|
67
|
+
| `sendMessage({ chatId, text, cid?, replyTo?, attachments? })` | С уведомлением |
|
|
68
|
+
| `sendMessageChannel({ ... })` | Канал, `notify: false` |
|
|
69
|
+
| `editMessage({ chatId, messageId, text, attachments? })` | Редактирование |
|
|
70
|
+
| `deleteMessage({ chatId, messageId, forMe? })` | Удаление |
|
|
71
|
+
| `uploadPhoto(chatId, filePath)` | Вложение фото → `attachments` |
|
|
72
|
+
| `uploadVideo(chatId, filePath)` | Видео |
|
|
73
|
+
| `uploadFile(chatId, filePath, options?)` | Файл |
|
|
74
|
+
| `uploadAudio(chatId, filePath)` | Аудио как файл |
|
|
75
|
+
|
|
76
|
+
### Пины и реакции
|
|
77
|
+
|
|
78
|
+
| Метод | Описание |
|
|
79
|
+
|-------|----------|
|
|
80
|
+
| `pinMessage({ chatId, messageId, notifyPin? })` | Закрепить |
|
|
81
|
+
| `setMessageReaction({ chatId, messageId, emoji })` | Реакция |
|
|
82
|
+
| `cancelMessageReaction({ chatId, messageId })` | Снять реакцию |
|
|
83
|
+
| `getMessageReactions({ chatId, messageId, count? })` | Список реакций |
|
|
84
|
+
|
|
85
|
+
### Чаты, каналы, группы
|
|
86
|
+
|
|
87
|
+
| Метод | Описание |
|
|
88
|
+
|-------|----------|
|
|
89
|
+
| `getChats(marker?)` | Список чатов |
|
|
90
|
+
| `getHistory(chatId, from?, backward?, forward?)` | История |
|
|
91
|
+
| `getChatInfo(chatIds)` | Инфо по id |
|
|
92
|
+
| `resolveLink(link)` | LINK_INFO |
|
|
93
|
+
| `joinChatByLink(link)` | Вступить по ссылке |
|
|
94
|
+
| `setChatSubscription(chatId, subscribe)` | Подписка на канал |
|
|
95
|
+
| `createGroup({ title, userIds })` | Новая группа |
|
|
96
|
+
| `createChannel({ title })` | Новый канал |
|
|
97
|
+
| `muteChat(chatId, mute?)` | Не беспокоить для чата |
|
|
98
|
+
| `getChatMembers({ chatId, marker?, count?, type? })` | Участники |
|
|
99
|
+
| `inviteToChat({ chatId, userIds, showHistory? })` | Пригласить |
|
|
100
|
+
| `removeFromChat({ chatId, userIds, cleanMsgPeriod? })` | Исключить |
|
|
101
|
+
| `addChatAdmins({ chatId, userIds, permissions? })` | Админы |
|
|
102
|
+
| `removeChatAdmins({ chatId, userIds })` | Снять админов |
|
|
103
|
+
| `transferChatOwnership({ chatId, newOwnerId })` | Смена владельца |
|
|
104
|
+
| `setGroupOptions({ chatId, options })` | Настройки группы |
|
|
105
|
+
| `resolveChannelByUsername(username)` | Канал по @ |
|
|
106
|
+
| `joinChannelByUsername(username)` | Вступить по @ |
|
|
107
|
+
| `resolveInviteHash(hash)` | Инвайт `join/...` |
|
|
108
|
+
|
|
109
|
+
### Контакты и профиль
|
|
110
|
+
|
|
111
|
+
| Метод | Описание |
|
|
112
|
+
|-------|----------|
|
|
113
|
+
| `getUser(userId)` | Один контакт → `User` |
|
|
114
|
+
| `getContacts(contactIds)` | Несколько контактов (сырой ответ) |
|
|
115
|
+
| `addContact(userId)` | В контакты |
|
|
116
|
+
| `blockUser(userId)` | Блокировка |
|
|
117
|
+
| `updateProfile({ firstName?, lastName?, description? })` | Профиль |
|
|
118
|
+
| `setHiddenOnline(hidden)` | Скрыть онлайн |
|
|
119
|
+
| `setFindableByPhone(mode)` | Поиск по телефону |
|
|
120
|
+
| `setCallsPrivacyMode(mode)` | Звонки |
|
|
121
|
+
| `setChatsInvitePrivacy(mode)` | Приглашения в чаты |
|
|
122
|
+
|
|
123
|
+
### Обработчики событий
|
|
124
|
+
|
|
125
|
+
| Метод | Событие |
|
|
126
|
+
|-------|---------|
|
|
127
|
+
| `onStart(handler)` | Успешный старт |
|
|
128
|
+
| `onMessage(handler)` | Новое сообщение |
|
|
129
|
+
| `onMessageRemoved(handler)` | Удалено сообщение |
|
|
130
|
+
| `onChatAction(handler)` | Действие в чате |
|
|
131
|
+
| `onError(handler)` | Ошибки |
|
|
132
|
+
|
|
133
|
+
### Прочее
|
|
134
|
+
|
|
135
|
+
| Метод | Описание |
|
|
136
|
+
|-------|----------|
|
|
137
|
+
| `logIncoming(label, payload)` | Ручной лог `[incoming:…]` |
|
|
138
|
+
| `sendAndWait(opcode, payload, cmd?, timeout?)` | Низкоуровневый RPC |
|
|
139
|
+
| `triggerHandlers(eventType, data?)` | Внутренний вызов обработчиков (редко нужен снаружи) |
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## `Message`
|
|
144
|
+
|
|
145
|
+
| Метод / свойство | Описание |
|
|
146
|
+
|------------------|----------|
|
|
147
|
+
| `id`, `cid`, `chatId`, `text`, `senderId`, `sender`, `attachments`, `rawData`, … | Поля |
|
|
148
|
+
| `fetchSender()` | Подгрузить отправителя |
|
|
149
|
+
| `getSenderName()` | Имя для лога |
|
|
150
|
+
| `reply({ text, cid?, attachments?, quote? })` | Ответ в чат |
|
|
151
|
+
| `edit({ text, … })` | Редактировать |
|
|
152
|
+
| `delete()` | Удалить |
|
|
153
|
+
| `forward(chatId)` | В `Message` вызывает `client.forwardMessage` — метод на клиенте может отсутствовать, проверьте версию |
|
|
154
|
+
| `downloadAttachment(index?, options?)` | Скачать вложение по `baseUrl` во временный файл |
|
|
155
|
+
| `toJSON()`, `toString()` | Сериализация |
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## `ChatAction`
|
|
160
|
+
|
|
161
|
+
| Свойство | Описание |
|
|
162
|
+
|----------|----------|
|
|
163
|
+
| `type`, `chatId`, `userId`, `user`, `timestamp`, `rawData` | Данные действия |
|
|
164
|
+
| `toString()`, `toJSON()` | Представление |
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## `User`
|
|
169
|
+
|
|
170
|
+
Основные поля: `id`, `firstname`, `lastname`, `phone`, `avatar`, `fullname` (getter) и др. — см. `lib/entities/User.js`.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Константы
|
|
175
|
+
|
|
176
|
+
- **`EventTypes`**: `START`, `MESSAGE`, `MESSAGE_REMOVED`, `CHAT_ACTION`, `ERROR`, `DISCONNECT`
|
|
177
|
+
- **`ChatActions`**: `TYPING`, `STICKER`, `FILE`, `RECORDING_VOICE`, `RECORDING_VIDEO`
|
|
178
|
+
- **`MessageTypes`**: `TEXT`, `IMAGE`, `VIDEO`, `AUDIO`, `DOCUMENT`, `STICKER`
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Утилиты (не методы клиента)
|
|
183
|
+
|
|
184
|
+
| Функция | Описание |
|
|
185
|
+
|---------|----------|
|
|
186
|
+
| `downloadUrlToTempFile(url, { dir?, filename?, extFallback? })` | HTTP → временный файл |
|
|
187
|
+
| `extFromContentType`, `extFromAttachType` | Подбор расширения |
|
|
188
|
+
| `resolveIncomingLogMode(options)` | Режим `logIncoming` из опций конструктора |
|
|
189
|
+
| `printIncomingLog(label, payload)` | Печать JSON в консоль |
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
*Файл для быстрой навигации; при расхождении с кодом приоритет у реализации в `lib/`.*
|
package/index.js
CHANGED
|
@@ -13,6 +13,7 @@ const { Opcode, getOpcodeName } = require('./lib/opcodes');
|
|
|
13
13
|
const { UserAgentPayload } = require('./lib/userAgent');
|
|
14
14
|
const { downloadUrlToTempFile, extFromContentType, extFromAttachType } = require('./lib/downloadMedia');
|
|
15
15
|
const { resolveIncomingLogMode, printIncomingLog } = require('./lib/incomingLog');
|
|
16
|
+
const { parseQrTrackId } = require('./lib/qrWebLogin');
|
|
16
17
|
|
|
17
18
|
module.exports = {
|
|
18
19
|
WebMaxClient,
|
|
@@ -30,6 +31,7 @@ module.exports = {
|
|
|
30
31
|
extFromContentType,
|
|
31
32
|
extFromAttachType,
|
|
32
33
|
resolveIncomingLogMode,
|
|
33
|
-
printIncomingLog
|
|
34
|
+
printIncomingLog,
|
|
35
|
+
parseQrTrackId
|
|
34
36
|
};
|
|
35
37
|
|