134 lines
2.6 KiB
TypeScript
134 lines
2.6 KiB
TypeScript
import {
|
|
ChatInputCommandInteraction,
|
|
Client,
|
|
SlashCommandBuilder,
|
|
TextChannel,
|
|
} from 'discord.js';
|
|
import {
|
|
Sequelize,
|
|
Model,
|
|
INTEGER,
|
|
STRING,
|
|
BOOLEAN,
|
|
DATE,
|
|
literal,
|
|
} from 'sequelize';
|
|
|
|
export interface Settings {
|
|
client: Client; // Main Discord client object
|
|
db: Sequelize; // Database access object
|
|
publicChannel?: string; // Channel to use if a reminder is public
|
|
loopIntervalSec?: number; // Loop interval in seconds
|
|
}
|
|
|
|
export class Nag extends Model {
|
|
// Primary key
|
|
declare id: number;
|
|
// User who created this nag
|
|
declare userId: number;
|
|
// Description of what you're supposed to do
|
|
declare text: string;
|
|
// Custom failure text
|
|
declare failText?: string;
|
|
// Should we @here?
|
|
declare mentionHere?: boolean;
|
|
}
|
|
|
|
export class CheckIn extends Model {
|
|
declare nagId: string;
|
|
// Date of the last time user ran /checkin
|
|
declare lastCheckIn: Date;
|
|
}
|
|
|
|
export async function initAndSyncTables(sequelize: Sequelize) {
|
|
Nag.init(
|
|
{
|
|
id: {
|
|
primaryKey: true,
|
|
type: INTEGER,
|
|
autoIncrement: true,
|
|
},
|
|
userId: {
|
|
type: INTEGER,
|
|
allowNull: false,
|
|
},
|
|
text: {
|
|
type: STRING,
|
|
allowNull: false,
|
|
},
|
|
failText: {
|
|
type: STRING,
|
|
},
|
|
mentionHere: {
|
|
type: BOOLEAN,
|
|
},
|
|
},
|
|
{sequelize},
|
|
);
|
|
CheckIn.init(
|
|
{
|
|
nagId: {
|
|
type: INTEGER,
|
|
allowNull: false,
|
|
},
|
|
lastCheckIn: {
|
|
type: DATE,
|
|
allowNull: false,
|
|
},
|
|
},
|
|
{sequelize},
|
|
);
|
|
Nag.hasOne(CheckIn, {foreignKey: 'nagId'});
|
|
await Nag.sync();
|
|
await CheckIn.sync();
|
|
}
|
|
|
|
import {Guild, Channel} from 'discord.js';
|
|
|
|
export class Plugin {
|
|
settings: Settings;
|
|
publicChannel?: Channel;
|
|
interval: NodeJS.Timeout;
|
|
|
|
constructor(settings: Settings) {
|
|
this.settings = settings;
|
|
}
|
|
|
|
start() {
|
|
if (!this.settings.loopIntervalSec) {
|
|
this.settings.loopIntervalSec = 60; // 1 minute
|
|
}
|
|
this.interval = setInterval(
|
|
this.loop,
|
|
this.settings.loopIntervalSec * 1000,
|
|
);
|
|
}
|
|
|
|
async triggerNag(nag: Nag) {
|
|
const client = this.settings.client;
|
|
const chan = client.channels.cache.get('1234'); // TODO
|
|
if (!(chan instanceof TextChannel)) {
|
|
return; // TODO
|
|
}
|
|
try {
|
|
const failText =
|
|
nag.failText ??
|
|
`<@${nag.userId}> didn't complete "${nag.text}". Shame shame!`;
|
|
const mentionHere = nag.mentionHere ? '<@here> ' : '';
|
|
const msg = `${mentionHere}${failText}`;
|
|
await chan.send(msg);
|
|
} catch (error) {
|
|
console.log('Error while creating Nag:', error); // TODO
|
|
}
|
|
}
|
|
|
|
async loop() {
|
|
console.debug('nag.js main loop');
|
|
// Find all nags where the last check-in was before (next check in) - (24 hours)
|
|
}
|
|
|
|
stop() {
|
|
clearInterval(this.interval);
|
|
}
|
|
}
|