Files
NTSH-Control/src/Twilio.ts

112 lines
2.8 KiB
TypeScript

import { join } from 'path';
import { Main } from './Main';
import { pathExists, readJSON, writeJSON } from 'fs-extra';
const PREFIX = '[Twilio]';
export class TwilioHandler {
private _Main: Main;
counter: {
date: string;
count: number;
} = {
date: new Date().toLocaleDateString('nl-NL'),
count: 0,
};
client;
constructor(Main: Main) {
this._Main = Main;
}
canSendMessage() {
const maxMessages = this._Main.Config.twilio.maxMessagesPerDay;
return this.counter.count < maxMessages;
}
async incrementCounter() {
const today = new Date().toLocaleDateString('nl-NL');
if (this.counter.date !== today) {
this.counter.date = today;
this.counter.count = 0;
}
this.counter.count++;
await writeJSON(join(this._Main.dataPath, 'twilio.json'), this.counter);
}
async load() {
const twilioConfigPath = join(this._Main.dataPath, 'twilio.json');
const twilioConfigExists = await pathExists(twilioConfigPath);
if (twilioConfigExists) {
this.counter = await readJSON(twilioConfigPath);
}
this.client = require('twilio')(
this._Main.Config.twilio.accountSid,
this._Main.Config.twilio.authToken,
);
}
async resetError(category: TwilioCategories) {
if (!this.lastErrors.has(category)) return;
this.lastErrors.delete(category);
}
private lastErrors: Map<TwilioCategories, string> = new Map();
private errorLog: string[] = [];
private errorTimeout: NodeJS.Timeout;
async sendError(category: TwilioCategories, error: string) {
if (this.lastErrors.get(category) === error) return;
this.lastErrors.set(category, error);
if (error == null) return;
this.errorLog.push(`${category}: ${error}`);
clearTimeout(this.errorTimeout);
this.errorTimeout = setTimeout(async () => {
const errorMessage = this.errorLog
.map((error) => `- ${error}`)
.join('\n');
this.errorLog = [];
if (!this.canSendMessage())
return console.log(PREFIX, 'Max messages per day reached');
await this.incrementCounter();
console.log(PREFIX, `Sending to Twilio:\n`, errorMessage);
const promises = this._Main.Config.twilio.toNumbers.map(
(toNumber) => this.sendMessage(toNumber, errorMessage),
);
await Promise.all(promises);
}, this._Main.Config.twilio.aggregateTimeout);
}
sendMessage(to: string, message: string) {
return new Promise<boolean>((resolve) => {
this.client.messages
.create({
body: message,
from: `${this._Main.Config.twilio.fromNumber}`,
to: to,
})
.then((message: any) => {
console.log(`Twilio message sent with SID: ${message.sid}`);
resolve(true);
})
.catch((error: any) => {
console.error('Error sending Twilio message:', error);
resolve(false);
});
});
}
}
type TwilioCategories =
| 'CameraRunner'
| 'UnityRunner'
| 'UnityWebSocket'
| 'Status'
| 'Audio';