102 lines
2.7 KiB
TypeScript
102 lines
2.7 KiB
TypeScript
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);
|
|
}
|