diff --git a/package.json b/package.json index cc2a90d1..ac071ea9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "revolt.js", - "version": "4.0.0-alpha.10", + "version": "4.0.0-alpha.11", "main": "dist/index.js", "repository": "https://gitlab.insrt.uk/revolt/revolt.js", "author": "Paul Makles ", diff --git a/src/Client.ts b/src/Client.ts index 8a4e4b29..662af708 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -34,6 +34,8 @@ export declare interface Client { on(event: 'message/delete', listener: (id: string) => void): this; } +export const SYSTEM_USER_ID = '00000000000000000000000000'; + export class Client extends EventEmitter { private db?: Db; heartbeat: number; @@ -98,7 +100,7 @@ export class Client extends EventEmitter { await this.users.restore(user => { return { ...user, online: false } }); await this.channels.restore(); this.users.set({ - _id: '00000000000000000000000000', + _id: SYSTEM_USER_ID, username: 'revolt' }); if (user_id) this.user = this.users.get(user_id); diff --git a/src/api/objects.ts b/src/api/objects.ts index d1963ef0..ab070d66 100644 --- a/src/api/objects.ts +++ b/src/api/objects.ts @@ -101,6 +101,12 @@ export namespace Channels { attachment?: Attachment, edited?: { $date: string } } + + export type SystemMessage = + | { type: "text"; content: string } + | { type: "user_added"; id: string; by: string } + | { type: "user_remove"; id: string; by: string } + | { type: "user_left"; id: string }; } export type User = Users.User; diff --git a/src/index.ts b/src/index.ts index c3c80123..22bafce5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ export * from './Client'; export { Channel, User, Message } from './api/objects'; -export const LIBRARY_VERSION = '4.0.0-alpha.10'; +export const LIBRARY_VERSION = '4.0.0-alpha.11'; export const defaultConfig = { apiURL: 'https://api.revolt.chat', diff --git a/src/maps/Channels.ts b/src/maps/Channels.ts index 3da68d5e..e7a3233a 100644 --- a/src/maps/Channels.ts +++ b/src/maps/Channels.ts @@ -14,6 +14,14 @@ export default class Channels extends Collection { return channel.recipients.find(user => user !== this.client.user?._id) as string; } + tryParseSystemMessage(content: string): ChannelsNS.SystemMessage { + try { + return JSON.parse(content); + } catch (e) { + return { type: 'text', content } + } + } + async fetchMutable(id: string) { if (this.map[id]) return this.get(id) as Channel; let res = await this.client.req<'GET', '/channels/:id'>('GET', `/channels/${id}` as any); diff --git a/src/websocket/client.ts b/src/websocket/client.ts index ff82d9b7..45c5c393 100644 --- a/src/websocket/client.ts +++ b/src/websocket/client.ts @@ -1,8 +1,8 @@ import WebSocket from 'isomorphic-ws'; import { backOff } from 'exponential-backoff'; -import { Client } from '..'; -import { Auth, User } from '../api/objects'; +import { Client, SYSTEM_USER_ID } from '..'; +import { Auth, Channels, User } from '../api/objects'; import { ServerboundNotification, ClientboundNotification } from './notifications'; export class WebSocketClient { @@ -117,6 +117,20 @@ export class WebSocketClient { case 'Message': { if (!this.client.messages.includes(packet._id)) { this.client.messages.push(packet._id); + + if (packet.author === SYSTEM_USER_ID) { + let system = this.client.channels.tryParseSystemMessage(packet.content); + switch (system.type) { + case 'user_added': + case 'user_remove': + await this.client.users.fetch(system.by); + case 'user_left': + await this.client.users.fetch(system.id); + } + } else { + await this.client.users.fetch(packet.author); + } + this.client.emit('message', packet); } break; @@ -130,6 +144,8 @@ export class WebSocketClient { let channel = await this.client.channels.fetchMutable(packet.id); if (channel.channel_type !== 'Group') throw "Not a group channel."; let user_id = packet.user; + await this.client.users.fetch(user_id); + channel.recipients = [ ...channel.recipients.filter(user => user !== user_id), user_id