class TriggerEngine {
constructor () {
this._triggers = new Map()
this._timers = new Map()
}
register (id, trigger) {
this._triggers.set(id, {
id,
type: trigger.type,
filter: trigger.filter || {},
action: trigger.action,
enabled: trigger.enabled ?? true
})
}
unregister (id) {
this._triggers.delete(id)
if (this._timers.has(id)) {
clearInterval(this._timers.get(id))
this._timers.delete(id)
}
}
enable (id) {
const t = this._triggers.get(id)
if (t) t.enabled = true
}
disable (id) {
const t = this._triggers.get(id)
if (t) t.enabled = false
}
// Fire event and run matching trigger actions
async fire (eventType, data) {
const results = []
for (const [id, trigger] of this._triggers) {
if (!trigger.enabled) continue
if (trigger.type !== eventType) continue
if (this._matchesFilter(trigger.filter, data)) {
try {
const result = await trigger.action(data)
results.push({ id, ok: true, result })
} catch (err) {
results.push({ id, ok: false, error: err.message })
}
}
}
return results
}
_matchesFilter (filter, data) {
if (!filter || Object.keys(filter).length === 0) return true
// Channel filter
if (filter.channel && data.channel !== filter.channel) return false
// Author filter
if (filter.author && data.author !== filter.author) return false
// Content contains filter
if (filter.contains && !data.text?.includes(filter.contains)) return false
// Regex pattern filter
if (filter.pattern) {
const regex = new RegExp(filter.pattern)
if (!regex.test(data.text || '')) return false
}
// Tag filter
if (filter.tags) {
const tags = filter.tags
const text = (data.text || '').toLowerCase()
if (!tags.some(tag => text.includes(tag.toLowerCase()))) return false
}
return true
}
// Start a scheduled trigger (cron-like)
startSchedule (id, intervalMs, action) {
this.register(id, {
type: 'schedule',
action
})
const timer = setInterval(async () => {
const trigger = this._triggers.get(id)
if (!trigger || !trigger.enabled) return
try {
await trigger.action({ timestamp: Date.now(), triggerId: id })
} catch {}
}, intervalMs)
this._timers.set(id, timer)
}
list () {
const result = []
for (const [id, t] of this._triggers) {
result.push({
id,
type: t.type,
enabled: t.enabled,
hasFilter: Object.keys(t.filter).length > 0
})
}
return result
}
get count () {
return this._triggers.size
}
destroy () {
for (const timer of this._timers.values()) {
clearInterval(timer)
}
this._timers.clear()
this._triggers.clear()
}
}
export { TriggerEngine }