| 1 | import { warn } from '../index.js'; |
| 2 | import { QuickReply } from './QuickReply.js'; |
| 3 | import { QuickReplySettings } from './QuickReplySettings.js'; |
| 4 | |
| 5 | export class AutoExecuteHandler { |
| 6 | /** @type {QuickReplySettings} */ settings; |
| 7 | |
| 8 | /** @type {Boolean[]}*/ preventAutoExecuteStack = []; |
| 9 | |
| 10 | |
| 11 | constructor(/** @type {QuickReplySettings} */settings) { |
| 12 | this.settings = settings; |
| 13 | } |
| 14 | |
| 15 | |
| 16 | checkExecute() { |
| 17 | return this.settings.isEnabled && !this.preventAutoExecuteStack.slice(-1)[0]; |
| 18 | } |
| 19 | |
| 20 | |
| 21 | async performAutoExecute(/** @type {QuickReply[]} */qrList) { |
| 22 | for (const qr of qrList) { |
| 23 | this.preventAutoExecuteStack.push(qr.preventAutoExecute); |
| 24 | try { |
| 25 | await qr.execute({ isAutoExecute: true }); |
| 26 | } catch (ex) { |
| 27 | warn(ex); |
| 28 | } finally { |
| 29 | this.preventAutoExecuteStack.pop(); |
| 30 | } |
| 31 | } |
| 32 | } |
| 33 | |
| 34 | |
| 35 | getCommands(eventName) { |
| 36 | const getFromConfig = (config) => { |
| 37 | // This safely handles cases where a link exists but the set hasn't been loaded (link.set is null) |
| 38 | return config?.setList?.map(link => link.set ? link.set.qrList.filter(qr => qr[eventName]) : [])?.flat() ?? []; |
| 39 | }; |
| 40 | return [ |
| 41 | ...getFromConfig(this.settings.config), |
| 42 | ...getFromConfig(this.settings.chatConfig), |
| 43 | ...getFromConfig(this.settings.charConfig), |
| 44 | ]; |
| 45 | } |
| 46 | |
| 47 | async handleStartup() { |
| 48 | if (!this.checkExecute()) return; |
| 49 | await this.performAutoExecute(this.getCommands('executeOnStartup')); |
| 50 | } |
| 51 | |
| 52 | async handleUser() { |
| 53 | if (!this.checkExecute()) return; |
| 54 | await this.performAutoExecute(this.getCommands('executeOnUser')); |
| 55 | } |
| 56 | |
| 57 | async handleAi() { |
| 58 | if (!this.checkExecute()) return; |
| 59 | await this.performAutoExecute(this.getCommands('executeOnAi')); |
| 60 | } |
| 61 | |
| 62 | async handleChatChanged() { |
| 63 | if (!this.checkExecute()) return; |
| 64 | await this.performAutoExecute(this.getCommands('executeOnChatChange')); |
| 65 | } |
| 66 | |
| 67 | async handleGroupMemberDraft() { |
| 68 | if (!this.checkExecute()) return; |
| 69 | await this.performAutoExecute(this.getCommands('executeOnGroupMemberDraft')); |
| 70 | } |
| 71 | |
| 72 | async handleNewChat() { |
| 73 | if (!this.checkExecute()) return; |
| 74 | await this.performAutoExecute(this.getCommands('executeOnNewChat')); |
| 75 | } |
| 76 | |
| 77 | async handleBeforeGeneration() { |
| 78 | if (!this.checkExecute()) return; |
| 79 | await this.performAutoExecute(this.getCommands('executeBeforeGeneration')); |
| 80 | } |
| 81 | |
| 82 | /** |
| 83 | * @param {any[]} entries Set of activated entries |
| 84 | */ |
| 85 | async handleWIActivation(entries) { |
| 86 | if (!this.checkExecute() || !Array.isArray(entries) || entries.length === 0) return; |
| 87 | const automationIds = entries.map(entry => entry.automationId).filter(Boolean); |
| 88 | if (automationIds.length === 0) return; |
| 89 | |
| 90 | const getFromConfig = (config) => { |
| 91 | return config?.setList |
| 92 | ?.map(link => link.set ? link.set.qrList.filter(qr => qr.automationId && automationIds.includes(qr.automationId)) : []) |
| 93 | ?.flat() ?? []; |
| 94 | }; |
| 95 | |
| 96 | const qrList = [ |
| 97 | ...getFromConfig(this.settings.config), |
| 98 | ...getFromConfig(this.settings.chatConfig), |
| 99 | ...getFromConfig(this.settings.charConfig), |
| 100 | ]; |
| 101 | |
| 102 | await this.performAutoExecute(qrList); |
| 103 | } |
| 104 | } |