export const TriggerState = { untriggered: 0, replied: 1, canReply: 2, cannotReply: 3, }; export function createTriggersChecklist() { return { 'quoi': TriggerState.untriggered, 'feur': TriggerState.untriggered, 'mention': TriggerState.untriggered, 'quoicoubeh': TriggerState.untriggered, }; } // Base class for all detectors, using a Chain of Responsibility pattern export default class detector { nextDetector = null; triggerName = 'quoi'; // default value /** * @param nextDetector The detector that will be checked if this one doesn't detect anything * @returns The next detector */ setNextDetector(nextDetector) { this.nextDetector = nextDetector; return nextDetector; } createSpecificReply(message) { return Promise.resolve(null); } getChanceToReply(message) { if (message.guildId == null) { return 0; } return getSetting(message.guildId, `${this.triggerName}AnswerPercentage`); } async createReply(message, triggersChecklist) { if (message.guildId == null) { return Promise.reject(new Error('No guild ID')); } const ignoredRoleId = getSetting(message.guildId, 'ignoredRoleId'); if (ignoredRoleId !== null && message.member?.roles.cache.has(ignoredRoleId)) { return Promise.resolve(''); } const forcedRoleId = getSetting(message.guildId, 'forcedAnswerRoleId'); // if user has a forced role, skip the percentage (100%) const threshold = (forcedRoleId != null && message.member?.roles.cache.has(forcedRoleId)) ? 100 : this.getChanceToReply(message); triggersChecklist = triggersChecklist ?? createTriggersChecklist(); switch (triggersChecklist[this.triggerName]) { case TriggerState.replied: return Promise.resolve(''); case TriggerState.untriggered: if (Math.floor(Math.random() * 100) < threshold) { triggersChecklist[this.triggerName] = TriggerState.canReply; } else { triggersChecklist[this.triggerName] = TriggerState.cannotReply; } break; } if (triggersChecklist[this.triggerName] === TriggerState.canReply) { const detected = await this.createSpecificReply(message); if (detected !== null) { triggersChecklist[this.triggerName] = TriggerState.replied; return detected; } } if (this.nextDetector) { return this.nextDetector.createReply(message, triggersChecklist); } return Promise.resolve(''); } }