npm package: @iassasin/wschatapi
Description: SinAir chat api
Author: iassasin
Latest version: 2.1.0

# wschatapi
API для написания своих клиентов к чату https://chat.sinair.ru/
## Установка
Для использования в nodejs:
```
npm install @iassasin/wschatapi ws
```
Для использования в браузере:
```
npm install @iassasin/wschatapi
```
## Быстрый старт
```javascript
const {WsChat, WsChatEvents} = require('@iassasin/wschatapi');

// в async функции:
let chat = new WsChat('wss://sinair.ru/ws/chat');
await chat.open();

chat.on(WsChatEvents.message, async (room, message) => {
	if (message.message === 'Пока') {
		room.sendMessage('Пока!');
		await chat.close();
	}
});

let room = await chat.joinRoom('#test');
room.sendMessage('/nick testbot');
room.sendMessage('Привет, я бот!');
```
## Методы API
В API используются два класса, доступные пользователю:
* `WsChat` - основной класс подключения и обработки событий;
* `Room` - класс подключения к конкретной комнате, его нельзя инстанцировать вручную, но к нему появляется доступ после подключения к комнате.

Также доступны несколько перечислений, которые удобно применять при использовании API:
* `WsChatEvents` - доступные для подписки события клиента чата;
* `MessageStyle` - стиль сообщения в чате;
* `ErrorCode` - код ошибки, которую можно получить в результате некоторых операций;
* `UserStatus` - возможные статусы пользователя.

### WsChat
Представляет собой набор управляющих методов и событий.

Большая часть методов возвращает `Promise`, который разрешается в момент успешного завершения операции, либо отклоняется с объектом ошибки.
Если ошибка возникла не в результате вызова подобного метода, то она уходит обработчику события `error`.

Доступные методы:
* `new WsChat(address: string)` - конструктор класса, `address` - адрес websocket-сервера чата, например `wss://sinair.ru/ws/chat`;
* `open(): Promise<void>` - установить соединение с сервером;
* `close(): Promise<void>` - закрыть соединение с сервером;
* `authByApiKey(key: string): Promise<PacketAuth>` - выполнить авторизацию на сервере с помощью постоянного API-ключа (получается в профиле на сайте, рекомендуется для ботов);
* ~~`authByLoginAndPassword(login: string, password: string): Promise<PacketAuth>`~~ - (**более не поддерживается**) выполнить авторизацию на сервере с помощью логина и пароля;
* `restoreConnection(token: string): Promise<PacketAuth>` - восстанавливает соединение по токену, полученному ранее через другие методы аутентификации. При этом происходит автоматическое подключение ко всем комнатам прошлого соединения (придут события `joinRoom` как при подключении к комнате);
* `changeStatus(status: UserStatus): void` - изменить свой статус. Допустимы только значения `UserStatus.away` и `UserStatus.back`;
* `joinRoom(target: string, options?: JoinOptions): Promise<Room>` - присоединиться к комнате `target`. Также можно передать объект опций. Опции по-умолчанию следующие:
```
{
	autoLogin: false, //автоматически войти в комнату с ником, который использовался в ней ранее (для авторизованных пользователей)
	loadHistory: false, //загрузить последние 50+ сообщений в комнате
}
```
* `leaveRoom(target: string): Promise<string>` - покинуть комнату `target`;
* `createRoom(target: string): Promise<string>` - создать комнату с именем `target`;
* `removeRoom(target: string): Promise<string>` - удалить свою комнату с именем `target`;
* `getRoomByTarget(target: string): Room` - найти комнату с именем `target` в списке подключенных.

Доступные свойства:
* `rooms: Room[]` - список комнат, к которым подключен клиент;
* `connected: boolean` - возвращает `true`, если подключение к серверу установлено, иначе `false`.

События (WsChatEvents):
* `open` - вызывается после подключения к серверу;
* `close` - вызывается после отключения от сервера;
* `connectionError(error)` - вызывается при возникновении ошибки подключения;
* `error(error)` - вызывается для необработанных ошибок при работе с API чата;
* `message(room, msgobj)` - вызывается, когда кто-то написал сообщение в комнату. `msgobj` - объект сообщения (будет описан ниже);
* `sysMessage(room, text)` - вызывается при получении системного сообщения. Когда сообщение не относится ни к одной комнате, `room` принимает значение `null`;
* `userStatusChanged(room, userobj)` - вызывается при изменении статуса пользователя в комнате; `userobj` - объект информации о пользователе (будет описан ниже);
* `joinRoom(room)` - вызывается после подключения к комнате, если подключение было вызвано не методом `chat.joinRoom()`. Например, после восстановления соединения методом `restoreConnection`;
* `leaveRoom(target)` - вызывается после исключения из комнаты; `target` - имя комнаты.

### Room
Класс, предоставляющий набор методов для конкретной комнаты.

Методы:
* `sendMessage(text: string)` - отправить сообщение в комнату;
* `changeStatus(status: UserStatus)` - изменить свой статус. Допустимы только следующие значения `UserStatus`: `away`, `back`, `typing`, `stop_typing`;
* `getMemberById(memberId: number)` - получить инфо пользователя по его id.

Свойства:
* `target: string` - кодовое имя комнаты, например `#chat`;
* `members: UserObject[]` - список подключенных к комнате пользователей;
* `memberId: number` - собственный комнатный id в рамках текущего подключения к комнате;
* `memberNick: string` - собственный ник в комнате.

### UserStatus
Перечисление всех возможных статусов пользователей:
* `bad` - если вы получили такой статус, что-то точно пошло не так;
* `offline` - пользователь отключился;
* `online` - пользователь онлайн;
* `away` - пользователь отошел;
* `nick_change` - пользователь изменил ник;
* `gender_change` - пользователь сменил пол;
* `color_change` - пользователь перекрасил ник;
* `back` - пользователь вернулся (после статуса `away`);
* `typing` - пользователь начал набирать сообщение;
* `stop_typing` - пользователь перестал набирать сообщение;
* `orphan` - пользователь потерял соединение с чатом, но еще может восстановить его.

### MessageStyle
Перечисления для определения типа присланного сообщения:
* `message` - обычное сообщение;
* `me` - сообщение о себе в третьем лице;
* `event` - сообщение от третьего лица;
* `offtop` - оффтоп (в чате выделяются серым).

### ErrorCode
Перечисление типа возникшей ошибки.
* `unknown` - незивестная ошибка;
* `database_error` - ошибка соединения с базой данных;
* `already_connected` - вы уже подключены (например, к комнате);
* `not_found` - при запросе что-то было не найдено (например, комната с таким именем);
* `access_denied` - доступ запрещен;
* `invalid_target` - неверно задано имя комнаты;
* `already_exists` - что-то уже существует (например, комната с таким именем);
* `incorrect_loginpass` - неверный логин/пароль (при авторизации);
* `user_banned` - ваш пользователь или все анонимные пользователи заблокированы в комнате.

### PackType
Перечисления типа пакета. Может использоваться при обработке ошибок.
* `error` - сообщение об ошибке;
* `system` - системное сообщение;
* `message` - сообщение;
* `online_list` - запрос список онлайна;
* `auth` - запрос авторизации;
* `status` - информация о пользователе;
* `join` - запрос на подключение к комнате;
* `leave` - запрос на отключение от комнаты;
* `create_room` - запрос на создание комнаты;
* `remove_room` - запрос на удаление комнаты;
* `ping` - служебный пакет для проверки связи.

### Объект сообщения (MessageObject)
* `id` (string?) - необязательное поле. id сообщения, присутствует только у публичных сообщений (в лс отсутствует).
* `color` (string) - цвет никнейма отправителя сообщения;
* `from` (int) - внутрикомнатный ID отправителя сообщения;
* `from_login` (string) - никнейм отправителя сообщения;
* `message` (string) - текст сообщения;
* `style` (MessageStyle) - тип сообщения;
* `target` (string) - название комнаты, в которую было отправлено сообщение;
* `time` (long) - время отправки сообщения в формате unixtime;
* `to` (int) - внутрикомнатный ID получателя сообщения (0, если сообщение публичное).

### Объект информации о пользователе (UserObject)
* `color` (string) - цвет никнейма пользователя;
* `data` (string) - данные события (например, при смене никнейма содержит старый никнейм пользователя);
* `girl` (bool) - имеет ли пользователь имеет женский пол;
* `is_moder` (bool) - является ли пользователь модератором комнаты;
* `is_owner` (bool) - является ли пользователь создателем комнаты;
* `member_id` (int) - внутрикомнатный ID пользователя;
* `name` (string) - никнейм пользователя;
* `status` (UserStatus) - статус пользователя (UserStatus);
* `user_id` (int) - ID аккаунта пользователя (0, если пользователь не авторизирован);
* `last_seen_time` (long) - время последнего присутствия пользователя (время перехода в статус away) в формате unixtime.