Skip to content

Plugin Development

MarkChai edited this page Jul 16, 2026 · 1 revision

业务插件开发

本章展示一个完整的业务插件示例,包含指令匹配、消息提取、复杂消息发送、群管操作和定时任务。

package my_plugin

import (
	"fmt"
	"strings"
	"time"

	adapter_manager "github.com/yeswearebot/adapter-manager"
	adapter_onebot "github.com/yeswearebot/adapter-onebot"
	"github.com/yeswearebot/yes-core/core"
)

type MyPlugin struct {
	stopChan chan struct{} // 用于通知定时任务停止的通道
}

func init() {
	core.Register(func() core.Plugin { return &MyPlugin{} })
}

func (p *MyPlugin) Name() string        { return "my-plugin" }
func (p *MyPlugin) DependsOn() []string { return []string{"adapter-manager", "adapter-onebot"} } // 依赖管理器和底层适配器

func (p *MyPlugin) Init(ctx *core.SystemContext) error {
	// 初始化停止通道
	p.stopChan = make(chan struct{})

	// 1. 监听标准化消息事件
	ctx.Events.Subscribe("adapter.message", func(payload any) {
		event, ok := payload.(*adapter_manager.MessageEvent)
		if !ok {
			return
		}

		// 🌟 1. 简单指令匹配
		if event.PlainText == "天王盖地虎" {
			event.ReplyText("宝塔镇河妖")
			return
		}

		// 🌟 2. 提取消息中的图片
		if strings.HasPrefix(event.PlainText, "/取图") {
			for _, seg := range event.Segments {
				if seg.Type == adapter_manager.SegImage {
					url := seg.GetString("url")
					event.ReplyText("抓到图了,链接是: " + url)
					return
				}
			}
			event.ReplyText("你没发图我可抓不到哦")
			return
		}

		// 🌟 3. 发送复杂的混合消息
		if event.PlainText == "/菜单" {
			msg := []adapter_manager.MessageSegment{
				adapter_manager.At(event.UserID),                              // @发送者
				adapter_manager.Text(" 这是菜单:\n"),                              // 文本
				adapter_manager.Image("https://api.mtyqx.cn/tapi/random.php"), // 随机图片
			}
			event.Reply(msg)
			return
		}

		// 🌟 4. 群管操作:禁言发送者
		if event.PlainText == "禁言我" {
			err := event.BanSender(60) // 禁言60秒
			if err != nil {
				event.ReplyText("禁言失败: " + err.Error())
			} else {
				event.ReplyText("已禁言你60秒")
			}
			return
		}

		// 🌟 5. 消息撤回
		if event.PlainText == "撤回我" {
			err := event.Delete()
			if err != nil {
				event.ReplyText("撤回失败: " + err.Error())
			}
			return
		}

		// 🌟 6. 获取群信息
		if event.PlainText == "/群信息" {
			manager := adapter_manager.GetManager(ctx)
			if manager != nil {
				info, err := manager.GetGroupInfo(event.Platform, event.SceneID, false)
				if err != nil {
					event.ReplyText("获取群信息失败: " + err.Error())
				} else {
					msg := fmt.Sprintf("群名: %s成员数: %d/%d",
						info.GroupName, info.MemberCount, info.MaxMemberCount)
					event.ReplyText(msg)
				}
			}
			return
		}

		// 🌟 7. 喂给 LLM 的文本示例
		if strings.HasPrefix(event.PlainText, "/ai") {
			// LLMText 会将非文本元素占位符化
			fmt.Printf("准备发给大模型的内容: %s\n", event.LLMText)
			event.ReplyText("已收到你的AI请求,正在思考...")
			return
		}
	})

	// 🌟 8. 监听其他事件(如群成员变动)
	ctx.Events.Subscribe("adapter.event", func(payload any) {
		data, ok := payload.(map[string]any)
		if !ok {
			return
		}

		eventType, _ := data["event_type"].(string)
		switch eventType {
		case "group_increase":
			// 群成员增加事件
			groupID, _ := data["group_id"].(int64)
			userID, _ := data["user_id"].(int64)

			manager := adapter_manager.GetManager(ctx)
			if manager != nil {
				welcomeMsg := []adapter_manager.MessageSegment{
					adapter_manager.At(userID),
					adapter_manager.Text(" 欢迎加入群聊!"),
				}
				manager.SendGroupMessage("adapter-onebot", groupID, welcomeMsg)
			}

		case "group_decrease":
			// 群成员减少事件
			groupID, _ := data["group_id"].(int64)
			userID, _ := data["user_id"].(int64)
			fmt.Printf("[事件] 用户 %d 退出了群 %d\n", userID, groupID)
		}
	})

	return nil
}

func (p *MyPlugin) Start(ctx *core.SystemContext) error {
	// 启动定时任务:每5分钟发送一次提醒
	go func() {
		ticker := time.NewTicker(5 * time.Minute)
		defer ticker.Stop()

		for {
			select {
			case <-ticker.C:
				// 获取AdapterManager实例
				manager := adapter_manager.GetManager(ctx)
				if manager != nil {
					// 向指定群发送定时消息(请将 123456789 替换为实际的群号)
					msg := []adapter_manager.MessageSegment{
						adapter_manager.Text("⏰ 定时提醒:当前时间 " + time.Now().Format("15:04:05")),
					}
					manager.SendGroupMessage("adapter-onebot", 717532590, msg)
				}
			case <-p.stopChan:
				// 收到停止信号,退出 goroutine
				fmt.Println("[MyPlugin] 定时任务已停止")
				return
			}
		}
	}()

	return nil
}

func (p *MyPlugin) Stop(ctx *core.SystemContext) error {
	// 发送停止信号,清理资源
	close(p.stopChan)
	return nil
}

Clone this wiki locally