diff --git a/handler/handler.go b/handler/handler.go index 3f94022..65c48fd 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -10,6 +10,7 @@ import ( type Handler func(msg model.Message) (reply model.Reply) var handlers = make(map[string]Handler) +var frontMatchHandlers = make(map[string]Handler) var liveHandlers = make(map[int64]map[int64]Handler) var privateAllHandler Handler @@ -21,6 +22,10 @@ func RegisterHandler(trigger string, handler Handler) { handlers[trigger] = handler } +func RegisterFrontMatchHandler(trigger string, handler Handler) { + frontMatchHandlers[trigger] = handler +} + func RegisterLiveHandler(groupID int64, userID int64, handler Handler) { //userID=-1 means for all users in groupID if _, ok := liveHandlers[groupID]; !ok { liveHandlers[groupID] = make(map[int64]Handler) @@ -50,6 +55,11 @@ func MsgInHandler(msg model.Message) (reply model.Reply) { return handler(msg) } } + for trigger, handler := range frontMatchHandlers { + if strings.HasPrefix(msg.RawMsg, trigger) { + return handler(msg) + } + } msgArray := strings.Split(msg.RawMsg, " ") if handler, ok := handlers[msgArray[0]]; ok { return handler(msg) diff --git a/handler/urlparser/url.go b/handler/urlparser/url.go index 7464931..a0b8d4f 100644 --- a/handler/urlparser/url.go +++ b/handler/urlparser/url.go @@ -10,17 +10,43 @@ import ( "git.lxtend.com/qqbot/handler" "git.lxtend.com/qqbot/model" + "git.lxtend.com/qqbot/util" ) func init() { - handler.RegisterFrontMatchHandler("[CQ:json,data=", urlParser) + handler.RegisterFrontMatchHandler("[CQ:json,data=", cqJsonUrlParser) + handler.RegisterFrontMatchHandler("http://", plainTextUrlParser) + handler.RegisterFrontMatchHandler("https://", plainTextUrlParser) } -func urlParser(msg model.Message) (reply model.Reply) { +func plainTextUrlParser(msg model.Message) (reply model.Reply) { + url := msg.RawMsg + url = strings.Split(url, " ")[0] + url = strings.Split(url, "\n")[0] + url = strings.Split(url, "\r")[0] + url = strings.Split(url, "\t")[0] + url, _ = removeTrackingParams(url) + newUrl, _ := resolveFinalURL(url) + newUrl, _ = removeTrackingParams(newUrl) + if util.IsEquivalentURL(url, newUrl) { + return model.Reply{ + ReplyMsg: "", + ReferOriginMsg: false, + FromMsg: msg, + } + } + return model.Reply{ + ReplyMsg: newUrl, + ReferOriginMsg: true, + FromMsg: msg, + } +} + +func cqJsonUrlParser(msg model.Message) (reply model.Reply) { qqdocurl, err := extractQQDocURL(msg.RawMsg) if err != nil { return model.Reply{ - ReplyMsg: fmt.Sprintf("解析失败: %v", err), + ReplyMsg: "", ReferOriginMsg: true, FromMsg: msg, } diff --git a/util/url.go b/util/url.go new file mode 100644 index 0000000..6dbb0b6 --- /dev/null +++ b/util/url.go @@ -0,0 +1,33 @@ +package util + +import ( + "net/url" + "strings" +) + +// isEquivalentURL 判断两个 URL 是否在规范化后相同 +func IsEquivalentURL(url1, url2 string) bool { + norm1 := normalizeURL(url1) + norm2 := normalizeURL(url2) + return norm1 == norm2 +} + +// normalizeURL 规范化 URL:移除末尾斜杠、协议标准化、移除 index.html +func normalizeURL(rawURL string) string { + u, err := url.Parse(rawURL) + if err != nil { + return rawURL + } + + // 将 http 和 https 视为同一种协议 + u.Scheme = "https" + + // 移除尾部的 /index.html 或 .html + u.Path = strings.TrimSuffix(u.Path, "/index.html") + u.Path = strings.TrimSuffix(u.Path, ".html") + + // 移除末尾的 / + u.Path = strings.TrimRight(u.Path, "/") + + return u.String() +}