import { EMessageType, Formatter, IMessage, Protocol } from '@squeebot/core'; class VirtualChatProtocol extends Protocol { public format = new Formatter(false, false); public type = 'VirtualChatProtocol'; public me = { name: 'Squeebot', id: `socket/${this.serverName}/Squeebot` }; get serverName() { return this.config.name; } get server() { const plugin = this.plugin; return plugin.getServer(this.serverName); } public start(...args: any[]): void { this.server?.addListener('message', this.boundMessageHandler); this.server?.addListener('close', this.stopHandler); } public stop(force?: boolean | undefined): void { this.server?.removeListener('message', this.boundMessageHandler); this.server?.removeListener('close', this.stopHandler); } private messageHandler( message: SocketMessage, sender: { id: string; intent?: string }, reply: replyFn ) { if (message.command !== 'event') return; const [eventName, ...argv] = message.arguments as string[]; const newMessage = { id: message.id || makeID(), type: eventName as EMessageType, data: message, text: argv.join(' '), source: this, time: new Date(), target: { id: sender.id, name: sender.intent || sender.id }, sender: { id: sender.id, name: sender.intent || sender.id }, fullSenderID: `socket/${this.serverName}/${sender.id}`, fullRoomID: `socket/${this.serverName}/${sender.id}`, resolved: false, direct: true, resolve: (...data: any[]) => { newMessage.resolved = true; const response = this.parseMessage(...data); if (!response || !this.server?.alive) return; reply({ id: newMessage.id, command: 'message', arguments: ['message', response], }); }, reject: (error) => reply({ id: newMessage.id, status: 'ERROR', arguments: [error], }), mention: (target) => `${target.name}, `, } as IMessage; this.plugin.stream.emitTo( 'channel', eventName !== 'message' ? 'event' : 'message', newMessage ); } private parseMessage(...data: any[]): string | null { let response = util.format(data[0], ...data.slice(1)); if (!response) { return null; } if (Array.isArray(data[0])) { try { response = this.format.compose(data[0]); } catch (e: any) { logger.error( '[%s] Failed to compose message:', this.fullName, e.message ); return null; } } return response; } private boundMessageHandler = this.messageHandler.bind(this); private stopHandler = this.stop.bind(this, true); }