diff --git a/config/config.go b/config/config.go index 2a256828..6dd389e7 100644 --- a/config/config.go +++ b/config/config.go @@ -149,6 +149,7 @@ type Settings struct { GlobalInteractionToMessage bool `yaml:"global_interaction_to_message"` AutoPutInteraction bool `yaml:"auto_put_interaction"` PutInteractionDelay int `yaml:"put_interaction_delay"` + ImgUpApiVtv2 bool `yaml:"img_up_api_ntv2"` } // LoadConfig 从文件中加载配置并初始化单例配置 @@ -183,7 +184,7 @@ func LoadConfig(path string) (*Config, error) { } // 确保配置完整性 - if err := ensureConfigComplete(conf, path); err != nil { + if err := ensureConfigComplete(path); err != nil { return nil, err } @@ -193,7 +194,7 @@ func LoadConfig(path string) (*Config, error) { } // 确保配置完整性 -func ensureConfigComplete(conf *Config, path string) error { +func ensureConfigComplete(path string) error { // 读取配置文件到缓冲区 configData, err := os.ReadFile(path) if err != nil { @@ -1844,3 +1845,16 @@ func GetPutInteractionDelay() int { } return instance.Settings.PutInteractionDelay } + +// 获取ntv2转换开关 +func GetImgUpApiVtv2() bool { + mu.Lock() + defer mu.Unlock() + + if instance == nil { + mylog.Println("Warning: instance is nil when trying to ImgUpApiVtv2 value.") + return false + } + return instance.Settings.ImgUpApiVtv2 +} + diff --git a/go.mod b/go.mod index 32dd19e1..ab7d1abe 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,7 @@ require ( require ( github.com/clbanning/mxj v1.8.4 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-querystring v1.0.0 // indirect github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -69,6 +70,6 @@ require ( golang.org/x/net v0.10.0 golang.org/x/sys v0.13.0 golang.org/x/text v0.9.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/protobuf v1.32.0 // indirect mvdan.cc/xurls v1.1.0 ) diff --git a/go.sum b/go.sum index 2d33d267..c368c245 100644 --- a/go.sum +++ b/go.sum @@ -70,6 +70,8 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -276,6 +278,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/handlers/message_parser.go b/handlers/message_parser.go index c6e0991f..7e530e53 100644 --- a/handlers/message_parser.go +++ b/handlers/message_parser.go @@ -1038,7 +1038,7 @@ func parseQQMuiscMDData(musicid string) (*dto.Markdown, *keyboard.MessageKeyboar return nil, nil, errors.New("song not found") } albumMid := info.Get("track_info.album.mid").String() - pinfo, _ := FetchTrackInfo(info.Get("track_info.mid").Str) + //pinfo, _ := FetchTrackInfo(info.Get("track_info.mid").Str) jumpURL := "https://i.y.qq.com/v8/playsong.html?platform=11&appshare=android_qq&appversion=10030010&hosteuin=oKnlNenz7i-s7c**&songmid=" + info.Get("track_info.mid").Str + "&type=0&appsongtype=1&_wv=1&source=qq&ADTAG=qfshare" content := info.Get("track_info.singer.0.name").String() @@ -1077,9 +1077,10 @@ func parseQQMuiscMDData(musicid string) (*dto.Markdown, *keyboard.MessageKeyboar Params: mdParams, } // 使用gjson获取musicUrl - musicUrl := gjson.Get(pinfo, "url_mid.data.midurlinfo.0.purl").String() + //musicUrl := gjson.Get(pinfo, "url_mid.data.midurlinfo.0.purl").String() // 处理 Keyboard - kb := createMusicKeyboard(jumpURL, musicUrl) + //kb := createMusicKeyboard(jumpURL, musicUrl) + kb := createMusicKeyboard(jumpURL) return md, kb, nil } @@ -1093,7 +1094,8 @@ func QQMusicSongInfo(id string) (gjson.Result, error) { return gjson.Get(d, "songinfo.data"), nil } -func createMusicKeyboard(jumpURL string, musicURL string) *keyboard.MessageKeyboard { +// func createMusicKeyboard(jumpURL string, musicURL string) *keyboard.MessageKeyboard { +func createMusicKeyboard(jumpURL string) *keyboard.MessageKeyboard { // 初始化自定义键盘 customKeyboard := &keyboard.CustomKeyboard{} currentRow := &keyboard.Row{} // 创建一个新行 diff --git a/handlers/send_group_msg.go b/handlers/send_group_msg.go index 8465b4fc..9329bcdc 100644 --- a/handlers/send_group_msg.go +++ b/handlers/send_group_msg.go @@ -88,6 +88,10 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap if message.Params.UserID != nil { messageID = echo.GetLazyMessagesIdv2(message.Params.GroupID.(string), message.Params.UserID.(string)) mylog.Printf("GetLazyMessagesIdv2: %v", messageID) + } else { + //如果应用端没有传递userid 那就用群号模式的lazyid 但是不保证顺序是对的 + messageID = echo.GetLazyMessagesId(message.Params.GroupID.(string)) + mylog.Printf("GetLazyMessagesIdv1: %v", messageID) } //2000是群主动 此时不能被动转主动 //仅在开启lazy_message_id时,有信息主动转被动特性,即,SSM @@ -205,7 +209,7 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap singleItem[imageType] = []string{imageUrl} msgseq := echo.GetMappingSeq(messageID) echo.AddMappingSeq(messageID, msgseq+1) - groupReply := generateGroupMessage(messageID, singleItem, "", msgseq+1) + groupReply := generateGroupMessage(messageID, singleItem, "", msgseq+1, apiv2, message.Params.GroupID.(string)) // 进行类型断言 richMediaMessage, ok := groupReply.(*dto.RichMediaMessage) if !ok { @@ -262,7 +266,6 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap _, err = apiv2.PostGroupMessage(context.TODO(), message.Params.GroupID.(string), groupMessage) if err != nil { mylog.Printf("发送组合消息失败: %v", err) - return "", nil // 或其他错误处理 } if err != nil && strings.Contains(err.Error(), `"code":22009`) { mylog.Printf("信息发送失败,加入到队列中,下次被动信息进行发送") @@ -283,7 +286,7 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap if messageText != "" { msgseq := echo.GetMappingSeq(messageID) echo.AddMappingSeq(messageID, msgseq+1) - groupReply := generateGroupMessage(messageID, nil, messageText, msgseq+1) + groupReply := generateGroupMessage(messageID, nil, messageText, msgseq+1, apiv2, message.Params.GroupID.(string)) // 进行类型断言 groupMessage, ok := groupReply.(*dto.MessageToCreate) @@ -317,7 +320,7 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap //mylog.Println("singleItem:", singleItem) msgseq := echo.GetMappingSeq(messageID) echo.AddMappingSeq(messageID, msgseq+1) - groupReply := generateGroupMessage(messageID, singleItem, "", msgseq+1) + groupReply := generateGroupMessage(messageID, singleItem, "", msgseq+1, apiv2, message.Params.GroupID.(string)) // 进行类型断言 richMediaMessage, ok := groupReply.(*dto.RichMediaMessage) if !ok { @@ -352,7 +355,7 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap if config.GetSendError() { //把报错当作文本发出去 msgseq := echo.GetMappingSeq(messageID) echo.AddMappingSeq(messageID, msgseq+1) - groupReply := generateGroupMessage(messageID, nil, err.Error(), msgseq+1) + groupReply := generateGroupMessage(messageID, nil, err.Error(), msgseq+1, apiv2, message.Params.GroupID.(string)) // 进行类型断言 groupMessage, ok := groupReply.(*dto.MessageToCreate) if !ok { @@ -496,7 +499,7 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap } // 上传富媒体信息 -func generateGroupMessage(id string, foundItems map[string][]string, messageText string, msgseq int) interface{} { +func generateGroupMessage(id string, foundItems map[string][]string, messageText string, msgseq int, apiv2 openapi.OpenAPI, groupid string) interface{} { if imageURLs, ok := foundItems["local_image"]; ok && len(imageURLs) > 0 { // 从本地路径读取图片 imageData, err := os.ReadFile(imageURLs[0]) @@ -527,7 +530,7 @@ func generateGroupMessage(id string, foundItems map[string][]string, messageText base64Encoded := base64.StdEncoding.EncodeToString(compressedData) // 上传base64编码的图片并获取其URL - imageURL, err := images.UploadBase64ImageToServer(base64Encoded) + imageURL, _, _, _, err := images.UploadBase64ImageToServer(id, base64Encoded, groupid, apiv2) if err != nil { mylog.Printf("Error uploading base64 encoded image: %v", err) // 如果上传失败,也返回文本信息,提示上传失败 @@ -569,10 +572,7 @@ func generateGroupMessage(id string, foundItems map[string][]string, messageText return nil } RecordData = silk.EncoderSilk(RecordData) - mylog.Errorf("音频转码ing") - if err != nil { - return nil - } + mylog.Printf("音频转码ing") } // 将解码的语音数据转换回base64格式并上传 imageURL, err := images.UploadBase64RecordToServer(base64.StdEncoding.EncodeToString(RecordData)) @@ -620,7 +620,7 @@ func generateGroupMessage(id string, foundItems map[string][]string, messageText base64Encoded := base64.StdEncoding.EncodeToString(imageData) // 上传图片并获取新的URL - newURL, err := images.UploadBase64ImageToServer(base64Encoded) + newURL, _, _, _, err := images.UploadBase64ImageToServer(id, base64Encoded, groupid, apiv2) if err != nil { mylog.Printf("Error uploading base64 encoded image: %v", err) return &dto.MessageToCreate{ @@ -685,7 +685,7 @@ func generateGroupMessage(id string, foundItems map[string][]string, messageText base64Encoded := base64.StdEncoding.EncodeToString(imageData) // 上传图片并获取新的URL - newURL, err := images.UploadBase64ImageToServer(base64Encoded) + newURL, _, _, _, err := images.UploadBase64ImageToServer(id, base64Encoded, groupid, apiv2) if err != nil { mylog.Printf("Error uploading base64 encoded image: %v", err) return &dto.MessageToCreate{ @@ -735,10 +735,7 @@ func generateGroupMessage(id string, foundItems map[string][]string, messageText return nil } fileRecordData = silk.EncoderSilk(fileRecordData) - mylog.Errorf("音频转码ing") - if err != nil { - return nil - } + mylog.Printf("音频转码ing") } // 将解码的语音数据转换回base64格式并上传 imageURL, err := images.UploadBase64RecordToServer(base64.StdEncoding.EncodeToString(fileRecordData)) @@ -788,10 +785,7 @@ func generateGroupMessage(id string, foundItems map[string][]string, messageText return nil } recordData = silk.EncoderSilk(recordData) - mylog.Errorf("音频转码ing") - if err != nil { - return nil - } + mylog.Printf("音频转码ing") } // 转换为base64 base64Encoded := base64.StdEncoding.EncodeToString(recordData) @@ -849,10 +843,7 @@ func generateGroupMessage(id string, foundItems map[string][]string, messageText return nil } recordData = silk.EncoderSilk(recordData) - mylog.Errorf("音频转码ing") - if err != nil { - return nil - } + mylog.Printf("音频转码ing") } // 转换为base64 base64Encoded := base64.StdEncoding.EncodeToString(recordData) @@ -899,7 +890,7 @@ func generateGroupMessage(id string, foundItems map[string][]string, messageText } } // 将解码的图片数据转换回base64格式并上传 - imageURL, err := images.UploadBase64ImageToServer(base64.StdEncoding.EncodeToString(compressedData)) + imageURL, _, _, _, err := images.UploadBase64ImageToServer(id, base64.StdEncoding.EncodeToString(compressedData), groupid, apiv2) if err != nil { mylog.Printf("failed to upload base64 image: %v", err) return nil diff --git a/handlers/send_guild_channel_forum.go b/handlers/send_guild_channel_forum.go index 26326230..a812d869 100644 --- a/handlers/send_guild_channel_forum.go +++ b/handlers/send_guild_channel_forum.go @@ -57,7 +57,7 @@ func HandleSendGuildChannelForum(client callapi.Client, api openapi.OpenAPI, api mylog.Println("频道发帖子messageText:", messageText) - Forum, err := GenerateForumMessage(foundItems, messageText) + Forum, err := GenerateForumMessage(foundItems, messageText, apiv2) if err != nil { mylog.Printf("组合帖子信息失败: %v", err) } @@ -152,7 +152,7 @@ func HandleSendGuildChannelForum(client callapi.Client, api openapi.OpenAPI, api // } // GenerateForumMessage 生成帖子消息 -func GenerateForumMessage(foundItems map[string][]string, messageText string) (*dto.FourmToCreate, error) { +func GenerateForumMessage(foundItems map[string][]string, messageText string, apiv2 openapi.OpenAPI) (*dto.FourmToCreate, error) { var forum dto.FourmToCreate // 设置标题 @@ -231,7 +231,7 @@ func GenerateForumMessage(foundItems map[string][]string, messageText string) (* mylog.Printf("Error compressing image: %v", err) return nil, fmt.Errorf("error compressing image: %v", err) } - imageURL, err := images.UploadBase64ImageToServer(base64.StdEncoding.EncodeToString(compressedData)) + imageURL, _, _, _, err := images.UploadBase64ImageToServer("", base64.StdEncoding.EncodeToString(compressedData), "", apiv2) if err != nil { mylog.Printf("failed to upload base64 image: %v", err) return nil, fmt.Errorf("failed to upload base64 image: %v", err) diff --git a/handlers/send_msg.go b/handlers/send_msg.go index 9fe36bda..f95751f9 100644 --- a/handlers/send_msg.go +++ b/handlers/send_msg.go @@ -42,11 +42,11 @@ func HandleSendMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openapi.Ope var err error if message.Params.GroupID != "" { - idInt64, _ = ConvertToInt64(message.Params.GroupID) - idInt642, _ = ConvertToInt64(message.Params.UserID) + idInt64, err = ConvertToInt64(message.Params.GroupID) + idInt642, err = ConvertToInt64(message.Params.UserID) } else if message.Params.UserID != "" { - idInt64, _ = ConvertToInt64(message.Params.UserID) - idInt642, _ = ConvertToInt64(message.Params.GroupID) + idInt64, err = ConvertToInt64(message.Params.UserID) + idInt642, err = ConvertToInt64(message.Params.GroupID) } //设置递归 对直接向gsk发送action时有效果 diff --git a/handlers/send_private_msg.go b/handlers/send_private_msg.go index 65a64ae0..573e588b 100644 --- a/handlers/send_private_msg.go +++ b/handlers/send_private_msg.go @@ -147,7 +147,7 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open singleItem[imageType] = []string{imageUrl} msgseq := echo.GetMappingSeq(messageID) echo.AddMappingSeq(messageID, msgseq+1) - groupReply := generateGroupMessage(messageID, singleItem, "", msgseq+1) + groupReply := generateGroupMessage(messageID, singleItem, "", msgseq+1, apiv2, message.Params.GroupID.(string)) // 进行类型断言 richMediaMessage, ok := groupReply.(*dto.RichMediaMessage) if !ok { @@ -192,7 +192,7 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open if messageText != "" { msgseq := echo.GetMappingSeq(messageID) echo.AddMappingSeq(messageID, msgseq+1) - groupReply := generateGroupMessage(messageID, nil, messageText, msgseq+1) + groupReply := generateGroupMessage(messageID, nil, messageText, msgseq+1, apiv2, message.Params.GroupID.(string)) // 进行类型断言 groupMessage, ok := groupReply.(*dto.MessageToCreate) @@ -220,7 +220,7 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open //mylog.Println("singleItem:", singleItem) msgseq := echo.GetMappingSeq(messageID) echo.AddMappingSeq(messageID, msgseq+1) - groupReply := generateGroupMessage(messageID, singleItem, "", msgseq+1) + groupReply := generateGroupMessage(messageID, singleItem, "", msgseq+1, apiv2, message.Params.GroupID.(string)) // 进行类型断言 richMediaMessage, ok := groupReply.(*dto.RichMediaMessage) if !ok { @@ -233,7 +233,7 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open if config.GetSendError() { //把报错当作文本发出去 msgseq := echo.GetMappingSeq(messageID) echo.AddMappingSeq(messageID, msgseq+1) - groupReply := generateGroupMessage(messageID, nil, err.Error(), msgseq+1) + groupReply := generateGroupMessage(messageID, nil, err.Error(), msgseq+1, apiv2, message.Params.GroupID.(string)) // 进行类型断言 groupMessage, ok := groupReply.(*dto.MessageToCreate) if !ok { diff --git a/images/upload_api.go b/images/upload_api.go index 5018edb1..d7754870 100644 --- a/images/upload_api.go +++ b/images/upload_api.go @@ -1,34 +1,144 @@ package images import ( + "context" + "encoding/base64" "encoding/json" "errors" "fmt" "io" + "log" "net" "net/http" "net/url" + "regexp" "strings" "github.com/hoshinonyaruko/gensokyo/config" + "github.com/hoshinonyaruko/gensokyo/echo" + "github.com/hoshinonyaruko/gensokyo/idmap" "github.com/hoshinonyaruko/gensokyo/oss" + "github.com/hoshinonyaruko/gensokyo/protobuf" + "github.com/tencent-connect/botgo/dto" + "github.com/tencent-connect/botgo/openapi" + "google.golang.org/protobuf/proto" ) -// 将base64图片通过lotus转换成url -func UploadBase64ImageToServer(base64Image string) (string, error) { +// uploadMedia 上传媒体并返回FileInfo +func uploadMedia(ctx context.Context, groupID string, richMediaMessage *dto.RichMediaMessage, apiv2 openapi.OpenAPI) (string, error) { + // 调用API来上传媒体 + messageReturn, err := apiv2.PostGroupMessage(ctx, groupID, richMediaMessage) + if err != nil { + return "", err + } + // 返回上传后的FileInfo + return messageReturn.MediaResponse.FileInfo, nil +} + +func isNumeric(s string) bool { + // 使用正则表达式检查字符串是否只包含数字 + return regexp.MustCompile(`^\d+$`).MatchString(s) +} + +// UploadBase64ImageToServer 将base64图片通过lotus转换成url +func UploadBase64ImageToServer(msgid string, base64Image string, groupID string, apiv2 openapi.OpenAPI) (string, uint64, uint32, uint32, error) { + var picURL string + var err error + extraPicAuditingType := config.GetOssType() + + switch extraPicAuditingType { + case 0: + picURL, err = originalUploadBehavior(base64Image) + case 1: + picURL, err = oss.UploadAndAuditImage(base64Image) // 腾讯 + case 2: + picURL, err = oss.UploadAndAuditImageB(base64Image) // 百度 + case 3: + picURL, err = oss.UploadAndAuditImageA(base64Image) // 阿里 + default: + return "", 0, 0, 0, errors.New("invalid extraPicAuditingType") + } + if err != nil { + return "", 0, 0, 0, err + } + + if config.GetImgUpApiVtv2() && groupID != "" { + + if msgid == "" { + msgid = echo.GetLazyMessagesId(groupID) + } + if isNumeric(groupID) { + // 检查groupID是否为纯数字构成 + originalGroupID, err := idmap.RetrieveRowByIDv2(groupID) + if err != nil { + log.Printf("Error retrieving original GroupID: %v", err) + return "", 0, 0, 0, nil + } + log.Printf("通过idmap获取的originalGroupID: %v", originalGroupID) + + // 用originalGroupID更新groupID + groupID = originalGroupID + } + richMediaMessage := &dto.RichMediaMessage{ + EventID: msgid, + FileType: 1, // 1代表图片 + URL: picURL, + Content: "", // 这个字段文档没有了 + SrvSendMsg: false, + } + fileInfo, err := uploadMedia(context.TODO(), groupID, richMediaMessage, apiv2) + if err != nil { + return "", 0, 0, 0, err + } + + // 将Base64字符串解码为二进制 + fileInfoBytes, err := base64.StdEncoding.DecodeString(fileInfo) + if err != nil { + log.Fatalf("Failed to decode Base64 string: %v", err) + } + + // 初始化Proto消息类型 + var mainMessage protobuf.Main + + // 解析二进制数据到Proto消息 + err = proto.Unmarshal(fileInfoBytes, &mainMessage) + if err != nil { + log.Fatalf("Failed to unmarshal Proto message: %v", err) + } + + // 从Proto消息中读取值 + realGroupID := mainMessage.GetA().GetB().GetInfo().GetDetail().GetGroupInfo().GetGroupNumber() + downloadURL := mainMessage.GetA().GetImageData().GetImageInfo().GetUrl() + width := mainMessage.GetA().GetImageData().GetWidth() + height := mainMessage.GetA().GetImageData().GetHeight() + + // 打印读取的值 + log.Printf("RealGroup ID: %d\n", realGroupID) + log.Printf("Download URL: %s, Width: %d, Height: %d\n", downloadURL, width, height) + + // 根据需要返回适当的值 + return downloadURL, realGroupID, width, height, nil + + } + + return picURL, 0, 0, 0, nil +} + +// 将base64语音通过lotus转换成url +func UploadBase64RecordToServer(base64Record string) (string, error) { extraPicAuditingType := config.GetOssType() // 根据不同的extraPicAuditingType值来调整函数行为 switch extraPicAuditingType { case 0: // 原有的函数行为 - return originalUploadBehavior(base64Image) + return originalUploadBehaviorRecord(base64Record) case 1: - return oss.UploadAndAuditImage(base64Image) //腾讯 + return oss.UploadAndAuditRecord(base64Record) //腾讯 case 2: - return oss.UploadAndAuditImageB(base64Image) //百度 + return oss.UploadAndAuditRecord(base64Record) //百度 case 3: - return oss.UploadAndAuditImageA(base64Image) //阿里 + return oss.UploadAndAuditRecord(base64Record) //阿里 default: return "", errors.New("invalid extraPicAuditingType") } diff --git a/main.go b/main.go index 86e8e0aa..1cbe9545 100644 --- a/main.go +++ b/main.go @@ -318,6 +318,7 @@ func main() { r.GET("/getid", server.GetIDHandler) r.GET("/updateport", server.HandleIpupdate) r.POST("/uploadpic", server.UploadBase64ImageHandler(rateLimiter)) + r.POST("/uploadpicv2", server.UploadBase64ImageHandlerV2(rateLimiter, apiV2)) r.POST("/uploadrecord", server.UploadBase64RecordHandler(rateLimiter)) r.Static("/channel_temp", "./channel_temp") if config.GetFrpPort() == "0" && !config.GetDisableWebui() { diff --git a/protobuf/fileinfo.pb.go b/protobuf/fileinfo.pb.go new file mode 100644 index 00000000..6a041822 --- /dev/null +++ b/protobuf/fileinfo.pb.go @@ -0,0 +1,686 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.32.0 +// protoc v4.25.3 +// source: fileinfo.proto + +package protobuf + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// 定义主体消息 +type Main struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + A *Main_A `protobuf:"bytes,1,opt,name=a,proto3" json:"a,omitempty"` +} + +func (x *Main) Reset() { + *x = Main{} + if protoimpl.UnsafeEnabled { + mi := &file_fileinfo_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Main) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Main) ProtoMessage() {} + +func (x *Main) ProtoReflect() protoreflect.Message { + mi := &file_fileinfo_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Main.ProtoReflect.Descriptor instead. +func (*Main) Descriptor() ([]byte, []int) { + return file_fileinfo_proto_rawDescGZIP(), []int{0} +} + +func (x *Main) GetA() *Main_A { + if x != nil { + return x.A + } + return nil +} + +// 其他字段 +type Other struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OtherField uint32 `protobuf:"varint,2,opt,name=other_field,json=otherField,proto3" json:"other_field,omitempty"` // 仅示例,实际中可能不需要 +} + +func (x *Other) Reset() { + *x = Other{} + if protoimpl.UnsafeEnabled { + mi := &file_fileinfo_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Other) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Other) ProtoMessage() {} + +func (x *Other) ProtoReflect() protoreflect.Message { + mi := &file_fileinfo_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Other.ProtoReflect.Descriptor instead. +func (*Other) Descriptor() ([]byte, []int) { + return file_fileinfo_proto_rawDescGZIP(), []int{1} +} + +func (x *Other) GetOtherField() uint32 { + if x != nil { + return x.OtherField + } + return 0 +} + +type Main_A struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + B *Main_A_B `protobuf:"bytes,2,opt,name=b,proto3" json:"b,omitempty"` + ImageData *Main_A_E `protobuf:"bytes,3,opt,name=image_data,json=imageData,proto3" json:"image_data,omitempty"` +} + +func (x *Main_A) Reset() { + *x = Main_A{} + if protoimpl.UnsafeEnabled { + mi := &file_fileinfo_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Main_A) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Main_A) ProtoMessage() {} + +func (x *Main_A) ProtoReflect() protoreflect.Message { + mi := &file_fileinfo_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Main_A.ProtoReflect.Descriptor instead. +func (*Main_A) Descriptor() ([]byte, []int) { + return file_fileinfo_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *Main_A) GetB() *Main_A_B { + if x != nil { + return x.B + } + return nil +} + +func (x *Main_A) GetImageData() *Main_A_E { + if x != nil { + return x.ImageData + } + return nil +} + +type Main_A_B struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Info *Main_A_B_C `protobuf:"bytes,1,opt,name=info,proto3" json:"info,omitempty"` +} + +func (x *Main_A_B) Reset() { + *x = Main_A_B{} + if protoimpl.UnsafeEnabled { + mi := &file_fileinfo_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Main_A_B) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Main_A_B) ProtoMessage() {} + +func (x *Main_A_B) ProtoReflect() protoreflect.Message { + mi := &file_fileinfo_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Main_A_B.ProtoReflect.Descriptor instead. +func (*Main_A_B) Descriptor() ([]byte, []int) { + return file_fileinfo_proto_rawDescGZIP(), []int{0, 0, 0} +} + +func (x *Main_A_B) GetInfo() *Main_A_B_C { + if x != nil { + return x.Info + } + return nil +} + +type Main_A_E struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Width uint32 `protobuf:"varint,22,opt,name=width,proto3" json:"width,omitempty"` // 图片宽度 + Height uint32 `protobuf:"varint,23,opt,name=height,proto3" json:"height,omitempty"` // 图片高度 + ImageInfo *Main_A_E_F `protobuf:"bytes,34,opt,name=image_info,json=imageInfo,proto3" json:"image_info,omitempty"` +} + +func (x *Main_A_E) Reset() { + *x = Main_A_E{} + if protoimpl.UnsafeEnabled { + mi := &file_fileinfo_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Main_A_E) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Main_A_E) ProtoMessage() {} + +func (x *Main_A_E) ProtoReflect() protoreflect.Message { + mi := &file_fileinfo_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Main_A_E.ProtoReflect.Descriptor instead. +func (*Main_A_E) Descriptor() ([]byte, []int) { + return file_fileinfo_proto_rawDescGZIP(), []int{0, 0, 1} +} + +func (x *Main_A_E) GetWidth() uint32 { + if x != nil { + return x.Width + } + return 0 +} + +func (x *Main_A_E) GetHeight() uint32 { + if x != nil { + return x.Height + } + return 0 +} + +func (x *Main_A_E) GetImageInfo() *Main_A_E_F { + if x != nil { + return x.ImageInfo + } + return nil +} + +type Main_A_B_C struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Detail *Main_A_B_C_D `protobuf:"bytes,6,opt,name=detail,proto3" json:"detail,omitempty"` +} + +func (x *Main_A_B_C) Reset() { + *x = Main_A_B_C{} + if protoimpl.UnsafeEnabled { + mi := &file_fileinfo_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Main_A_B_C) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Main_A_B_C) ProtoMessage() {} + +func (x *Main_A_B_C) ProtoReflect() protoreflect.Message { + mi := &file_fileinfo_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Main_A_B_C.ProtoReflect.Descriptor instead. +func (*Main_A_B_C) Descriptor() ([]byte, []int) { + return file_fileinfo_proto_rawDescGZIP(), []int{0, 0, 0, 0} +} + +func (x *Main_A_B_C) GetDetail() *Main_A_B_C_D { + if x != nil { + return x.Detail + } + return nil +} + +type Main_A_B_C_D struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + GroupInfo *Main_A_B_C_D_E `protobuf:"bytes,202,opt,name=group_info,json=groupInfo,proto3" json:"group_info,omitempty"` +} + +func (x *Main_A_B_C_D) Reset() { + *x = Main_A_B_C_D{} + if protoimpl.UnsafeEnabled { + mi := &file_fileinfo_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Main_A_B_C_D) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Main_A_B_C_D) ProtoMessage() {} + +func (x *Main_A_B_C_D) ProtoReflect() protoreflect.Message { + mi := &file_fileinfo_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Main_A_B_C_D.ProtoReflect.Descriptor instead. +func (*Main_A_B_C_D) Descriptor() ([]byte, []int) { + return file_fileinfo_proto_rawDescGZIP(), []int{0, 0, 0, 0, 0} +} + +func (x *Main_A_B_C_D) GetGroupInfo() *Main_A_B_C_D_E { + if x != nil { + return x.GroupInfo + } + return nil +} + +type Main_A_B_C_D_E struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + GroupNumber uint64 `protobuf:"varint,1,opt,name=group_number,json=groupNumber,proto3" json:"group_number,omitempty"` // 群号 +} + +func (x *Main_A_B_C_D_E) Reset() { + *x = Main_A_B_C_D_E{} + if protoimpl.UnsafeEnabled { + mi := &file_fileinfo_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Main_A_B_C_D_E) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Main_A_B_C_D_E) ProtoMessage() {} + +func (x *Main_A_B_C_D_E) ProtoReflect() protoreflect.Message { + mi := &file_fileinfo_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Main_A_B_C_D_E.ProtoReflect.Descriptor instead. +func (*Main_A_B_C_D_E) Descriptor() ([]byte, []int) { + return file_fileinfo_proto_rawDescGZIP(), []int{0, 0, 0, 0, 0, 0} +} + +func (x *Main_A_B_C_D_E) GetGroupNumber() uint64 { + if x != nil { + return x.GroupNumber + } + return 0 +} + +type Main_A_E_F struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Url string `protobuf:"bytes,30,opt,name=url,proto3" json:"url,omitempty"` // 图片URL +} + +func (x *Main_A_E_F) Reset() { + *x = Main_A_E_F{} + if protoimpl.UnsafeEnabled { + mi := &file_fileinfo_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Main_A_E_F) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Main_A_E_F) ProtoMessage() {} + +func (x *Main_A_E_F) ProtoReflect() protoreflect.Message { + mi := &file_fileinfo_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Main_A_E_F.ProtoReflect.Descriptor instead. +func (*Main_A_E_F) Descriptor() ([]byte, []int) { + return file_fileinfo_proto_rawDescGZIP(), []int{0, 0, 1, 0} +} + +func (x *Main_A_E_F) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +var File_fileinfo_proto protoreflect.FileDescriptor + +var file_fileinfo_proto_rawDesc = []byte{ + 0x0a, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x22, 0xcd, 0x03, 0x0a, 0x04, 0x4d, + 0x61, 0x69, 0x6e, 0x12, 0x1e, 0x0a, 0x01, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x61, 0x69, 0x6e, 0x2e, 0x41, + 0x52, 0x01, 0x61, 0x1a, 0xa4, 0x03, 0x0a, 0x01, 0x41, 0x12, 0x20, 0x0a, 0x01, 0x62, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x4d, 0x61, 0x69, 0x6e, 0x2e, 0x41, 0x2e, 0x42, 0x52, 0x01, 0x62, 0x12, 0x31, 0x0a, 0x0a, 0x69, + 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x61, 0x69, 0x6e, 0x2e, + 0x41, 0x2e, 0x45, 0x52, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x1a, 0xca, + 0x01, 0x0a, 0x01, 0x42, 0x12, 0x28, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x61, + 0x69, 0x6e, 0x2e, 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x1a, 0x9a, + 0x01, 0x0a, 0x01, 0x43, 0x12, 0x2e, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x4d, 0x61, 0x69, 0x6e, 0x2e, 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x2e, 0x44, 0x52, 0x06, 0x64, 0x65, + 0x74, 0x61, 0x69, 0x6c, 0x1a, 0x65, 0x0a, 0x01, 0x44, 0x12, 0x38, 0x0a, 0x0a, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0xca, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x61, 0x69, 0x6e, 0x2e, 0x41, + 0x2e, 0x42, 0x2e, 0x43, 0x2e, 0x44, 0x2e, 0x45, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, + 0x6e, 0x66, 0x6f, 0x1a, 0x26, 0x0a, 0x01, 0x45, 0x12, 0x21, 0x0a, 0x0c, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x1a, 0x7d, 0x0a, 0x01, 0x45, + 0x12, 0x14, 0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x18, 0x17, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x33, + 0x0a, 0x0a, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x22, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x61, + 0x69, 0x6e, 0x2e, 0x41, 0x2e, 0x45, 0x2e, 0x46, 0x52, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x49, + 0x6e, 0x66, 0x6f, 0x1a, 0x15, 0x0a, 0x01, 0x46, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, + 0x1e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x28, 0x0a, 0x05, 0x4f, 0x74, + 0x68, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x68, 0x6f, 0x73, 0x68, 0x69, 0x6e, 0x6f, 0x6e, 0x79, 0x61, 0x72, 0x75, 0x6b, + 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x73, 0x6f, 0x6b, 0x79, 0x6f, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_fileinfo_proto_rawDescOnce sync.Once + file_fileinfo_proto_rawDescData = file_fileinfo_proto_rawDesc +) + +func file_fileinfo_proto_rawDescGZIP() []byte { + file_fileinfo_proto_rawDescOnce.Do(func() { + file_fileinfo_proto_rawDescData = protoimpl.X.CompressGZIP(file_fileinfo_proto_rawDescData) + }) + return file_fileinfo_proto_rawDescData +} + +var file_fileinfo_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_fileinfo_proto_goTypes = []interface{}{ + (*Main)(nil), // 0: protobuf.Main + (*Other)(nil), // 1: protobuf.Other + (*Main_A)(nil), // 2: protobuf.Main.A + (*Main_A_B)(nil), // 3: protobuf.Main.A.B + (*Main_A_E)(nil), // 4: protobuf.Main.A.E + (*Main_A_B_C)(nil), // 5: protobuf.Main.A.B.C + (*Main_A_B_C_D)(nil), // 6: protobuf.Main.A.B.C.D + (*Main_A_B_C_D_E)(nil), // 7: protobuf.Main.A.B.C.D.E + (*Main_A_E_F)(nil), // 8: protobuf.Main.A.E.F +} +var file_fileinfo_proto_depIdxs = []int32{ + 2, // 0: protobuf.Main.a:type_name -> protobuf.Main.A + 3, // 1: protobuf.Main.A.b:type_name -> protobuf.Main.A.B + 4, // 2: protobuf.Main.A.image_data:type_name -> protobuf.Main.A.E + 5, // 3: protobuf.Main.A.B.info:type_name -> protobuf.Main.A.B.C + 8, // 4: protobuf.Main.A.E.image_info:type_name -> protobuf.Main.A.E.F + 6, // 5: protobuf.Main.A.B.C.detail:type_name -> protobuf.Main.A.B.C.D + 7, // 6: protobuf.Main.A.B.C.D.group_info:type_name -> protobuf.Main.A.B.C.D.E + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_fileinfo_proto_init() } +func file_fileinfo_proto_init() { + if File_fileinfo_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_fileinfo_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Main); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fileinfo_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Other); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fileinfo_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Main_A); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fileinfo_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Main_A_B); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fileinfo_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Main_A_E); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fileinfo_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Main_A_B_C); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fileinfo_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Main_A_B_C_D); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fileinfo_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Main_A_B_C_D_E); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fileinfo_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Main_A_E_F); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_fileinfo_proto_rawDesc, + NumEnums: 0, + NumMessages: 9, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_fileinfo_proto_goTypes, + DependencyIndexes: file_fileinfo_proto_depIdxs, + MessageInfos: file_fileinfo_proto_msgTypes, + }.Build() + File_fileinfo_proto = out.File + file_fileinfo_proto_rawDesc = nil + file_fileinfo_proto_goTypes = nil + file_fileinfo_proto_depIdxs = nil +} diff --git a/server/uploadpic.go b/server/uploadpic.go index 1897cf17..b1fc1c77 100644 --- a/server/uploadpic.go +++ b/server/uploadpic.go @@ -18,7 +18,9 @@ import ( "github.com/gin-gonic/gin" "github.com/hoshinonyaruko/gensokyo/config" "github.com/hoshinonyaruko/gensokyo/idmap" + "github.com/hoshinonyaruko/gensokyo/images" "github.com/hoshinonyaruko/gensokyo/mylog" + "github.com/tencent-connect/botgo/openapi" ) const ( @@ -91,7 +93,7 @@ func UploadBase64ImageHandler(rateLimiter *RateLimiter) gin.HandlerFunc { } else { mylog.Println("File already exists, skipping save.") } - + var serverPort string serverAddress := config.GetServer_dir() frpport := config.GetFrpPort() @@ -122,6 +124,42 @@ func UploadBase64ImageHandler(rateLimiter *RateLimiter) gin.HandlerFunc { } } +func UploadBase64ImageHandlerV2(rateLimiter *RateLimiter, apiv2 openapi.OpenAPI) gin.HandlerFunc { + return func(c *gin.Context) { + ipAddress := c.ClientIP() + if !rateLimiter.CheckAndUpdateRateLimit(ipAddress) { + c.JSON(http.StatusTooManyRequests, gin.H{"error": "rate limit exceeded"}) + return + } + + // 从请求中获取必要的参数 + base64Image := c.PostForm("base64Image") + msgid := c.DefaultPostForm("msgid", "") // msgid可以为空 + groupID := c.PostForm("groupID") // groupID是必需的 + + if groupID == "" { + c.JSON(http.StatusBadRequest, gin.H{"error": "groupID is required"}) + return + } + + // 调用函数上传图片 + imageURL, groupid, width, height, err := images.UploadBase64ImageToServer(msgid, base64Image, groupID, apiv2) + if err != nil { + // 根据错误类型返回合适的HTTP状态码和错误信息 + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + // 如果上传成功,则返回图片的URL,群组ID,宽度和高度 + c.JSON(http.StatusOK, gin.H{ + "url": imageURL, + "groupid": groupid, + "width": width, + "height": height, + }) + } +} + // 闭包,网页后端,语音床逻辑,基于gin和www静态文件的简易语音床 func UploadBase64RecordHandler(rateLimiter *RateLimiter) gin.HandlerFunc { return func(c *gin.Context) { @@ -152,7 +190,7 @@ func UploadBase64RecordHandler(rateLimiter *RateLimiter) gin.HandlerFunc { c.JSON(http.StatusInternalServerError, gin.H{"error": "error creating directory"}) return } - + //如果文件存在则跳过 if _, err := os.Stat(savePath); os.IsNotExist(err) { err = os.WriteFile(savePath, RecordBytes, 0644) diff --git a/template/config_template.go b/template/config_template.go index c0e9af21..9769fef7 100644 --- a/template/config_template.go +++ b/template/config_template.go @@ -134,6 +134,7 @@ settings: shard_id: 0 #当前分片id 默认从0开始,详细请看 https://bot.q.qq.com/wiki/develop/api/gateway/reference.html auto_put_interaction : false #自动回应按钮回调的/interactions/{interaction_id} 注本api需要邮件申请,详细方法参考群公告:196173384 put_interaction_delay : 0 #单位毫秒 表示回应已收到回调类型的按钮的毫秒数 会按用户进行区分 非全局delay + img_up_api_ntv2: false #gsk内建图片上传api 是否将图片转换为ntqq图床url(md发图用,自行调用)文档: title : "Gensokyo © 2023 - Hoshinonyaruko" #程序的标题 如果多个机器人 可根据标题区分 custom_bot_name : "Gensokyo全域机器人" #自定义机器人名字,会在api调用中返回,默认Gensokyo全域机器人