Skip to content

触发器

触发器提供自定义的LLM触发时机,除了群聊中通过at或前缀、伪人机制等方式主动触发外,也可以自定义触发时机和处理逻辑。触发器可以在特定时间或事件发生时自动执行,并通过LLM生成相应内容发送给指定目标。

Chaite提供了以下几种基本触发器类型:

  • BaseTrigger:所有触发器的基类,提供基本功能
  • CronTrigger:基于定时表达式的触发器,可在特定时间点触发
  • EventTrigger:基于事件的触发器,响应特定事件发生

定时触发器可以按照设定的时间规则自动执行,例如每天、每小时或特定时间点:

import { Chaite, CronTrigger } from 'chaite'
class HourlyReminderTrigger extends CronTrigger {
constructor () {
super({
name: '整点报时',
description: '每小时整点时在指定群组发送报时消息',
cronExpression: '0 * * * *' // 每小时的0分触发
})
}
async execute (context) {
try {
// 获取当前时间
const currentTime = new Date()
const hour = currentTime.getHours()
const formattedTime = currentTime.toLocaleTimeString('zh-CN', {
hour12: false,
timeZone: 'Asia/Shanghai' // 假设使用中国标准时间,可以根据需要调整
})
// 构建要发送给 LLM 的消息,请求生成报时内容
const message = {
role: 'user',
content: [{
type: 'text',
text: `现在是 ${formattedTime},请生成一句简短的整点报时消息,语气友好且自然。`
}]
}
// 查询 LLM 生成报时消息
const preset = await Chaite.getInstance().getChatPresetManager()?.getInstance('m8fpmwy2xabuxhkmbyr')
const response = await this.queryLLM(message, { chatPreset: preset })
const reminderText = response.contents[0].text
// 发送报时消息到指定群组
const GROUP_ID = '1040690625'
Bot.pickGroup(GROUP_ID).sendMsg(reminderText)
logger.info(`已发送整点报时消息到群组 ${GROUP_ID},时间: ${formattedTime}`)
} catch (error) {
logger.error('发送整点报时消息时出错:', error)
}
}
}
export default new HourlyReminderTrigger()

事件触发器会在特定事件发生时执行,例如群组消息、好友请求或其他系统事件。注意在Miao-Yunzai、TRSS-Yunzai以及Karin中关于Bot的定义各不相同,需要用户根据使用的框架自行编写对应逻辑代码。

import { BaseTrigger } from 'chaite'
class GroupRequestTrigger extends BaseTrigger {
constructor (params = {}) {
super({
name: '群组申请通知',
isOneTime: params.isOneTime || false // 是否为一次性触发器,默认 false
})
this.bot = null
this.isRegistered = false
this.eventHandler = this.handleGroupRequestEvent.bind(this)
}
/**
* 实现注册方法
*/
async registerImpl (context) {
if (this.isRegistered) return
this.bot = Bot // 假设 Bot 实例全局可用
if (!this.bot) {
logger.error(`触发器 ${this.name} 注册失败:找不到 Bot 实例`)
return
}
// 注册群组申请事件监听
this.bot.on('request.group', this.eventHandler)
this.isRegistered = true
logger.info(`触发器 ${this.name} 已注册,监听群组申请事件`)
}
/**
* 实现注销方法
*/
async unregisterImpl () {
if (!this.isRegistered || !this.bot) return
this.bot.off('request.group', this.eventHandler)
this.isRegistered = false
logger.info(`触发器 ${this.name} 已注销`)
}
/**
* 处理群组申请事件
*/
async handleGroupRequestEvent (event) {
// 使用 triggerAction 确保一次性触发器的自动清理
await this.triggerAction(async () => {
try {
logger.info('收到群组申请事件:', JSON.stringify(event, null, 2))
// 获取群组实例
const groupId = event.group_id // 假设事件中包含 group_id 字段
const group = this.bot.pickGroup(groupId)
if (!group) {
logger.error(`无法找到群组 ${groupId}`)
return
}
// 获取申请者详细信息(如果事件中包含 user_id)
let userInfo = null
if (event.user_id) {
try {
userInfo = Bot.gml.get(groupId).get(event.user_id, false)
logger.info(`获取申请者信息 (ID: ${event.user_id}):`, userInfo)
} catch (error) {
logger.error(`获取申请者信息 (ID: ${event.user_id}) 失败: ${error.message}`)
}
}
// 构建补充信息对象
const enrichedEvent = {
...event,
user_details: userInfo || { error: '无法获取申请者信息' }
}
// 将事件及补充信息转换为字符串,发送给 LLM
const eventJson = JSON.stringify(enrichedEvent, null, 2)
const userMessage = {
role: 'user',
content: [{
type: 'text',
text: `收到一个群组申请事件,请根据以下事件内容生成一段简短的提醒消息,提醒管理员尽快处理,语气自然且友好:\n\n${eventJson}`
}]
}
// 调用 LLM 获取提醒内容
const response = await this.queryLLM(userMessage, { model: 'gpt-4.1' })
if (response.contents && response.contents.length > 0) {
const reminderText = response.contents[0].text
if (groupId) {
await group.sendMsg(reminderText)
logger.info(`已向群组 ${groupId} 发送申请处理提醒消息`)
} else {
logger.error('事件中未找到 group_id,无法发送提醒消息')
}
} else {
logger.error('生成提醒内容失败:LLM 返回内容为空')
if (groupId) {
await group.sendMsg('处理群组申请事件时发生错误,无法提醒。')
}
}
} catch (error) {
logger.error(`处理群组申请事件失败: ${error.message}`)
const groupId = event.group_id
if (groupId) {
const group = this.bot.pickGroup(groupId)
if (group) {
await group.sendMsg('处理群组申请事件时发生错误,无法提醒。')
}
}
}
})
}
}
export default new GroupRequestTrigger()

触发器可以设置为一次性,触发后会自动销毁:

import { CronTrigger } from 'chaite'
class OneTimeTrigger extends CronTrigger {
constructor () {
super({
name: '一次性提醒',
description: '在特定时间点执行一次后自动销毁',
cronExpression: '30 12 * * *', // 每天12:30触发
isOneTime: true // 设置为一次性触发器
})
}
async execute (context) {
try {
// 执行一次性任务
const message = {
role: 'user',
content: [{
type: 'text',
text: '请生成一条特别的通知消息,提醒用户这是一条一次性通知,不会再次发送。'
}]
}
const response = await this.queryLLM(message, { model: 'gpt-3.5-turbo' })
const notificationText = response.contents[0].text
// 发送到指定目标
const TARGET_ID = '123456789'
await Bot.pickFriend(TARGET_ID).sendMsg(notificationText)
logger.info(`已发送一次性通知到 ${TARGET_ID}`)
// 注意:不需要手动处理注销,BaseTrigger.triggerAction 会自动处理
} catch (error) {
logger.error('执行一次性触发器时出错:', error)
}
}
}
export default new OneTimeTrigger()
  1. 明确触发条件:定义清晰的触发条件,避免过于频繁的触发
  2. 错误处理:在触发器执行逻辑中添加完善的错误处理
  3. 资源管理:确保触发器在不需要时被正确注销,避免资源泄漏
  4. 合理使用一次性触发器:针对临时任务使用一次性触发器
  5. 避免重复触发:设计触发器时注意避免重复触发同一事件