UNPKG

@tsuk1ko/cq-websocket

Version:

A Node SDK for developing QQ chatbots based on WebSocket, which is depending on CoolQ and CQHTTP API plugin.

329 lines (286 loc) 9.84 kB
export enum WebSocketType { API = '/api', EVENT = '/event', } export enum WebSocketState { DISABLED = -1, INIT = 0, CONNECTING = 1, CONNECTED = 2, CLOSING = 3, CLOSED = 4, } export interface CQRequestOptions { timeout: number; } export type WebSocketProtocol = 'http:' | 'https:' | 'ws:' | 'wss:'; export interface CQWebSocketOption { accessToken: string; enableAPI: boolean; enableEvent: boolean; protocol: WebSocketProtocol; host: string; port: number; baseUrl: string; /** @deprecated */ qq: number | string; reconnection: boolean; reconnectionAttempts: number; reconnectionDelay: number; // fragmentOutgoingMessages: boolean; // fragmentationThreshold: number; // tlsOptions: any; requestOptions: CQRequestOptions; forcePostFormat: 'string'; } export type BaseEvents = 'message' | 'notice' | 'request' | 'error' | 'ready'; export type MessageEvents = | 'message.private' | 'message.discuss' | 'message.discuss.@' | 'message.discuss.@.me' | 'message.group' | 'message.group.@' | 'message.group.@.me' | 'message.guild' | 'message.guild.@' | 'message.guild.@.me'; export type NoticeEvents = | 'notice.group_upload' | 'notice.group_admin' | 'notice.group_admin.set' | 'notice.group_admin.unset' | 'notice.group_decrease' | 'notice.group_decrease.leave' | 'notice.group_decrease.kick' | 'notice.group_decrease.kick_me' | 'notice.group_increase' | 'notice.group_increase.approve' | 'notice.group_increase.invite' | 'notice.group_ban' | 'notice.group_ban.ban' | 'notice.group_ban.lift_ban' | 'notice.friend_add' | 'notice.group_recall' | 'notice.friend_recall' | 'notice.notify' | 'notice.notify.poke' | 'notice.notify.lucky_king' | 'notice.notify.honor' | 'notice.group_card' | 'notice.offline_file' | 'notice.client_status' | 'notice.essence' | 'notice.essence.add' | 'notice.essence.delete'; export type RequestEvents = | 'request.friend' | 'request.group.add' | 'request.group.invite' // node | 'request.group'; export type MetaEvents = 'meta_event.lifecycle' | 'meta_event.heartbeat'; export type SocketEvents = | 'socket.connecting' | 'socket.connect' | 'socket.failed' | 'socket.reconnecting' | 'socket.reconnect' | 'socket.reconnect_failed' | 'socket.max_reconnect' | 'socket.closing' | 'socket.close' | 'socket.error'; export type APIEvents = 'api.send.pre' | 'api.send.post' | 'api.response'; export type Events = BaseEvents | MessageEvents | NoticeEvents | RequestEvents | SocketEvents | APIEvents; export type ListenerReturn = void | Promise<void>; export type ArrayMessage = (CQTag | CQHTTPMessage | string)[]; export type MessageListenerReturn = | ListenerReturn | string | Promise<string> | ArrayMessage | Promise<ArrayMessage> | Promise<void | string | ArrayMessage>; export type MessageEventListener = ( event: CQEvent, context: Record<string, any>, tags: CQTag[], ) => MessageListenerReturn; export type ContextEventListener = (context: Record<string, any>) => ListenerReturn; export type SocketEventListener = (type: WebSocketType, attempts: number) => ListenerReturn; export type SocketExcludeType = 'socket.connect' | 'socket.closing' | 'socket.close' | 'socket.error'; export interface APITimeoutError extends Error { readonly req: APIRequest; } export interface SocketError extends Error {} export interface InvalidWsTypeError extends Error { readonly which: WebSocketType; } export interface InvalidContextError extends SyntaxError { readonly which: WebSocketType; readonly data: string; } export interface UnexpectedContextError extends Error { readonly context: Record<string, any>; readonly reason: string; } export declare class CQEvent { readonly messageFormat: 'string' | 'array'; stopPropagation(): void; getMessage(): string | ArrayMessage; setMessage(msg: string | ArrayMessage): void; appendMessage(msg: string | CQTag | CQHTTPMessage): void; hasMessage(): boolean; onResponse(handler: (res: object) => void, options: number | CQRequestOptions): void; onError(handler: (err: APITimeoutError) => void): void; } export interface APIRequest { action: string; params?: any; } export interface APIResponse<T> { status: string; retcode: number; data: T; } export class CQWebSocket { constructor(opt?: Partial<CQWebSocketOption>); connect(wsType?: WebSocketType): CQWebSocket; disconnect(wsType?: WebSocketType): CQWebSocket; reconnect(delay?: number, wsType?: WebSocketType): CQWebSocket; isSockConnected(wsType: WebSocketType): CQWebSocket; isReady(): boolean; on(event_type: MessageEvents | 'message', listener: MessageEventListener): CQWebSocket; on( event_type: NoticeEvents | RequestEvents | MetaEvents | 'notice' | 'request' | 'meta_event', listener: ContextEventListener, ): CQWebSocket; on(event_type: Exclude<SocketEvents, SocketExcludeType>, listener: SocketEventListener): CQWebSocket; on(event_type: 'socket.connect', listener: (type: WebSocketType, socket: any, attempts: number) => void): CQWebSocket; on(event_type: 'socket.closing', listener: (type: WebSocketType) => void): CQWebSocket; on(event_type: 'socket.close', listener: (type: WebSocketType, code: number, desc: string) => void): CQWebSocket; on(event_type: 'socket.error', listener: (type: WebSocketType, err: SocketError) => void): CQWebSocket; on(event_type: 'api.send.pre', listener: (apiRequest: APIRequest) => void): CQWebSocket; on(event_type: 'api.send.post', listener: () => void): CQWebSocket; on(event_type: 'api.response', listener: (result: APIResponse<any>) => void): CQWebSocket; on(event_type: 'error', listener: (err: InvalidContextError | UnexpectedContextError) => void): CQWebSocket; on(event_type: 'ready', listener: () => void): CQWebSocket; once(event_type: MessageEvents | 'message', listener: MessageEventListener): CQWebSocket; once( event_type: NoticeEvents | RequestEvents | MetaEvents | 'notice' | 'request' | 'meta_event', listener: ContextEventListener, ): CQWebSocket; once(event_type: Exclude<SocketEvents, SocketExcludeType>, listener: SocketEventListener): CQWebSocket; once( event_type: 'socket.connect', listener: (type: WebSocketType, socket: any, attempts: number) => void, ): CQWebSocket; once(event_type: 'socket.closing', listener: (type: WebSocketType) => void): CQWebSocket; once(event_type: 'socket.close', listener: (type: WebSocketType, code: number, desc: string) => void): CQWebSocket; once(event_type: 'socket.error', listener: (type: WebSocketType, err: Error) => void): CQWebSocket; once(event_type: 'api.send.pre', listener: (apiRequest: APIRequest) => void): CQWebSocket; once(event_type: 'api.send.post', listener: () => void): CQWebSocket; once(event_type: 'api.response', listener: (result: APIResponse<any>) => void): CQWebSocket; once(event_type: 'error', listener: (err: Error) => void): CQWebSocket; once(event_type: 'ready', listener: () => void): CQWebSocket; off(event_type?: Events, listener?: Function): CQWebSocket; } export interface CQWebSocket { <T>(method: string, params?: Record<string, any>, options?: number | CQRequestOptions): Promise<APIResponse<T>>; } export default CQWebSocket; /******************************************/ export type Serializable = string | number | boolean; export interface CQHTTPMessage { type: string; data: Record<string, string> | null; } export declare class CQTag { readonly tagName: string; readonly data: Readonly<Record<string, Serializable>>; modifier: Record<string, Serializable>; equals(another: CQTag): boolean; coerce(): this; toJSON(): CQHTTPMessage; valueOf(): string; toString(): string; } export class CQAt extends CQTag { readonly qq: string; constructor(qq: number | string); } export class CQAnonymous extends CQTag { ignore: boolean; constructor(shouldIgnoreIfFailed?: boolean); } export class CQBFace extends CQTag { readonly id: number; /** * To send a bface, not only `id` but also `p`, * which is the name of child directory of `data/bface`, * is required. * @see https://github.com/richardchien/coolq-http-api/wiki/CQ-%E7%A0%81%E7%9A%84%E5%9D%91 */ constructor(id: number, p: string); } export class CQCustomMusic extends CQTag { readonly url: string; readonly audio: string; readonly title: string; readonly content?: string; readonly image?: string; readonly type: 'custom'; constructor(url: string, audio: string, title: string, content?: string, image?: string); } export class CQDice extends CQTag { readonly type: number; constructor(); } export class CQEmoji extends CQTag { readonly id: number; constructor(id: number); } export class CQFace extends CQTag { readonly id: number; constructor(id: number); } export class CQImage extends CQTag { readonly file: string; readonly url?: string; cache?: boolean; constructor(file: string, cache?: boolean); } export class CQMusic extends CQTag { readonly type: string; readonly id: number; constructor(type: string, id: number); } export class CQRecord extends CQTag { readonly file: string; magic?: true; constructor(file: string, magic?: boolean); hasMagic(): boolean; } export class CQRPS extends CQTag { readonly type: number; constructor(); } export class CQSFace extends CQTag { readonly id: number; constructor(id: number); } export class CQShake extends CQTag { constructor(); } export class CQShare extends CQTag { readonly url: string; readonly title: string; readonly content?: string; readonly image?: string; constructor(url: string, title: string, content?: string, image?: string); } export class CQText extends CQTag { readonly text: string; constructor(text: string); }