refactor: enhance event handling in IRC, Slack, and Telegram clients

This commit is contained in:
Flummi 2025-03-18 10:47:58 +01:00
parent 3e1cfe18f9
commit ca114f677e
4 changed files with 70 additions and 36 deletions

View File

@ -29,6 +29,11 @@ interface ParsedCommand {
params: string[];
}
interface IRCEvents {
data: [string | [string, any]];
error: [string];
}
const colors = {
white: "00", black: "01", navy: "02", green: "03", red: "04",
brown: "05", purple: "06", orange: "07", yellow: "08",
@ -59,6 +64,14 @@ export default class irc extends EventEmitter {
user: Map<string, { account?: string; cached: number }>;
};
emit<K extends keyof IRCEvents>(event: K, ...args: IRCEvents[K]): boolean {
return super.emit(event, ...args);
}
on<K extends keyof IRCEvents>(event: K, listener: (...args: IRCEvents[K]) => void): this {
return super.on(event, listener);
}
constructor(options: IRCOptions) {
super();
this.options = {
@ -102,38 +115,29 @@ export default class irc extends EventEmitter {
this.connect();
}
connect(reconnect: boolean = false): void {
if(reconnect)
this.socket = undefined;
if(this.options.ssl) {
this.socket = tls.connect({
private createSocket(): net.Socket | tls.TLSSocket {
return this.options.ssl
? tls.connect({
host: this.options.host,
port: this.options.port,
rejectUnauthorized: !this.options.selfSigned,
}, () => this.handleConnection());
}
else {
this.socket = net.connect({
})
: net.connect({
host: this.options.host,
port: this.options.port,
}, () => this.handleConnection());
}
if(!this.socket)
throw new Error("Socket konnte nicht initialisiert werden.");
});
}
connect(reconnect: boolean = false): void {
if(reconnect)
this.socket = undefined;
this.socket = this.createSocket();
this.socket.on("data", (msg: string) => this.handleData(msg));
this.socket.on("end", () => this.handleDisconnect());
this.socket.on("error", (err: Error) => this.handleError(err));
this.socket.setEncoding("utf-8");
this.socket.on("data", (msg: string) => {
console.log("Received data:", msg);
this.handleData(msg);
});
this.socket.on("end", () => {
this.handleDisconnect();
});
this.socket.on("error", (err: Error) => {
this.handleError(err);
});
this.handleConnection();
}
private handleConnection(): void {

View File

@ -40,12 +40,27 @@ interface SlackRTMStartResponse {
description?: string;
}
interface SlackEvents {
data: [string | [string, any]];
error: [string];
message: [SlackMessage];
}
export default class slack extends EventEmitter {
private options: Required<SlackOptions>;
private token: string;
private api: string = "https://slack.com/api";
private interval: NodeJS.Timeout | null = null;
private server: ServerInfo;
private reconnectAttempts = 0;
emit<K extends keyof SlackEvents>(event: K, ...args: SlackEvents[K]): boolean {
return super.emit(event, ...args);
}
on<K extends keyof SlackEvents>(event: K, listener: (...args: SlackEvents[K]) => void): this {
return super.on(event, listener);
}
constructor(options: SlackOptions) {
super();
@ -92,6 +107,7 @@ export default class slack extends EventEmitter {
if(res.url) {
this.server.wss.url = url.parse(res.url);
this.reconnectAttempts = 0;
this.initializeWebSocket();
}
else
@ -128,7 +144,7 @@ export default class slack extends EventEmitter {
if(!this.server.wss.socket)
return;
this.interval = setInterval(async () => await this.ping(), 30000);
this.interval = setInterval(async () => await this.ping(), 3e4);
this.server.wss.socket.on("data", async (data: Buffer) => {
try {
@ -158,12 +174,15 @@ export default class slack extends EventEmitter {
}
async reconnect(): Promise<void> {
this.server.wss.url = null;
this.server.wss.socket = null;
if(this.interval)
clearInterval(this.interval);
this.emit("data", ["info", "reconnecting slack"]);
await this.connect();
if(this.reconnectAttempts >= 5) {
this.emit("data", ["error", "Too many reconnect attempts"]);
return;
}
this.reconnectAttempts++;
setTimeout(async () => {
this.emit("data", ["info", "Reconnecting to Slack"]);
await this.connect();
}, this.reconnectAttempts * 1e3);
}
async getChannel(channelId: string): Promise<string | undefined> {
@ -247,8 +266,7 @@ export default class slack extends EventEmitter {
private parseData(data: Buffer): SlackMessage | undefined {
try {
const json = JSON.parse(data.toString());
return json;
return JSON.parse(data.toString()) as SlackMessage;
}
catch(err: any) {
this.emit("data", ["error", "failed to parse data"]);

View File

@ -50,6 +50,11 @@ interface TelegramUpdate {
inline_query?: any;
}
interface TelegramEvents {
data: [string | [string, any]];
error: [string];
}
export default class tg extends EventEmitter {
private options: Required<TelegramOptions>;
private token: string;
@ -64,6 +69,14 @@ export default class tg extends EventEmitter {
me: {},
};
emit<K extends keyof TelegramEvents>(event: K, ...args: TelegramEvents[K]): boolean {
return super.emit(event, ...args);
}
on<K extends keyof TelegramEvents>(event: K, listener: (...args: TelegramEvents[K]) => void): this {
return super.on(event, listener);
}
constructor(options: TelegramOptions) {
super();
this.options = {

1
src/types.d.ts vendored
View File

@ -11,7 +11,6 @@ export interface Bot {
server: {
channel: Map<string, string[]>;
motd: string;
//user: Map<string, any>;
user: {
[channel: string]: any
};