Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beta71 #204

Merged
merged 6 commits into from
Dec 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Processor/ProcessC2CMessage.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,11 @@ func (p *Processors) ProcessC2CMessage(data *dto.WSC2CMessageData) error {
//映射str的userid到int
var userid64 int64
var err error
var magic int64
if config.GetIdmapPro() {
//将真实id转为int userid64
_, userid64, err = idmap.StoreIDv2Pro("group_private", data.Author.ID)
magic, userid64, err = idmap.StoreIDv2Pro("group_private", data.Author.ID)
mylog.Printf("魔法数字:%v", magic) //690426430
if err != nil {
mylog.Fatalf("Error storing ID: %v", err)
}
Expand Down
17 changes: 10 additions & 7 deletions Processor/Processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,12 @@ func (p *Processors) Autobind(data interface{}) error {
mylog.Printf("Error storing ID: %v", err)
return nil
}
//转换idmap-pro 虚拟值
//将真实id转为int userid64
_, _, err = idmap.StoreIDv2Pro(groupID, realID)
if err != nil {
mylog.Fatalf("Error storing ID689: %v", err)
}
// 单独检查vuin和gid的绑定状态
vuinBound := strconv.FormatInt(userid64, 10) == vuinstr
gidBound := strconv.FormatInt(GroupID64, 10) == idValuestr
Expand All @@ -692,9 +698,10 @@ func (p *Processors) Autobind(data interface{}) error {
return err
}
// idmaps pro也更新
idmap.UpdateVirtualValuev2Pro(GroupID64, idValue, userid64, vuinValue)
// 处理同一个群群友的gid刷新
idmap.UpdateKeysWithNewID(groupID, idValuestr)
err = idmap.UpdateVirtualValuev2Pro(GroupID64, idValue, userid64, vuinValue)
if err != nil {
mylog.Fatalf("Error storing ID703: %v", err)
}
} else if !vuinBound {
// 只有vuin未绑定,更新vuin映射
if err := idmap.UpdateVirtualValuev2(userid64, vuinValue); err != nil {
Expand All @@ -703,8 +710,6 @@ func (p *Processors) Autobind(data interface{}) error {
}
// idmaps pro也更新,但只更新vuin
idmap.UpdateVirtualValuev2Pro(GroupID64, idValue, userid64, vuinValue)
// 处理同一个群群友的gid刷新
idmap.UpdateKeysWithNewID(groupID, idValuestr)
} else if !gidBound {
// 只有gid未绑定,更新gid映射
if err := idmap.UpdateVirtualValuev2(GroupID64, idValue); err != nil {
Expand All @@ -713,8 +718,6 @@ func (p *Processors) Autobind(data interface{}) error {
}
// idmaps pro也更新,但只更新gid
idmap.UpdateVirtualValuev2Pro(GroupID64, idValue, userid64, vuinValue)
// 处理同一个群群友的gid刷新
idmap.UpdateKeysWithNewID(groupID, idValuestr)
} else {
// 两者都已绑定,不执行任何操作
mylog.Errorf("Both vuin and gid are already binded")
Expand Down
8 changes: 7 additions & 1 deletion botgo/dto/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,18 @@ type MediaResponse struct {
TTL int `json:"ttl"`
}

//新增
//群信息结构
type GroupMessageResponse struct {
MediaResponse *MediaResponse
Message *Message
}

// C2CMessageResponse 用于包装 C2C 消息的响应
type C2CMessageResponse struct {
Message *Message `json:"message,omitempty"`
MediaResponse *MediaResponse `json:"media_response,omitempty"`
}

// Embed 结构
type Embed struct {
Title string `json:"title,omitempty"`
Expand Down
2 changes: 1 addition & 1 deletion botgo/openapi/iface.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ type MessageAPI interface {
// PostGroupMessage 发送群消息
PostGroupMessage(ctx context.Context, groupID string, msg dto.APIMessage) (*dto.GroupMessageResponse, error)
// PostC2CMessage 发送C2C消息
PostC2CMessage(ctx context.Context, userID string, msg dto.APIMessage) (*dto.Message, error)
PostC2CMessage(ctx context.Context, userID string, msg dto.APIMessage) (*dto.C2CMessageResponse, error)
}

// GuildAPI guild 相关接口
Expand Down
38 changes: 31 additions & 7 deletions botgo/openapi/v1/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"strconv"

"github.com/go-resty/resty/v2"
"github.com/tidwall/gjson"

"github.com/tencent-connect/botgo/dto"
Expand Down Expand Up @@ -221,14 +222,37 @@ func getC2CURLBySendType(msgType dto.SendType) uri {
}

// PostC2CMessage 回复C2C消息
func (o *openAPI) PostC2CMessage(ctx context.Context, userID string, msg dto.APIMessage) (*dto.Message, error) {
resp, err := o.request(ctx).
SetResult(dto.Message{}).
SetPathParam("user_id", userID).
SetBody(msg).
Post(o.getURL(getC2CURLBySendType(msg.GetSendType())))
func (o *openAPI) PostC2CMessage(ctx context.Context, userID string, msg dto.APIMessage) (*dto.C2CMessageResponse, error) {
var resp *resty.Response
var err error

msgType := msg.GetSendType()
switch msgType {
case dto.RichMedia:
resp, err = o.request(ctx).
SetResult(dto.MediaResponse{}). // 设置为媒体响应类型
SetPathParam("user_id", userID).
SetBody(msg).
Post(o.getURL(getC2CURLBySendType(msgType)))
default:
resp, err = o.request(ctx).
SetResult(dto.Message{}). // 设置为消息类型
SetPathParam("user_id", userID).
SetBody(msg).
Post(o.getURL(getC2CURLBySendType(msgType)))
}

if err != nil {
return nil, err
}
return resp.Result().(*dto.Message), nil

result := &dto.C2CMessageResponse{}
switch msgType {
case dto.RichMedia:
result.MediaResponse = resp.Result().(*dto.MediaResponse)
default:
result.Message = resp.Result().(*dto.Message)
}

return result, nil
}
37 changes: 30 additions & 7 deletions botgo/openapi/v2/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,14 +237,37 @@ func getC2CURLBySendType(msgType dto.SendType) uri {
}

// PostC2CMessage 回复C2C消息
func (o *openAPIv2) PostC2CMessage(ctx context.Context, userID string, msg dto.APIMessage) (*dto.Message, error) {
resp, err := o.request(ctx).
SetResult(dto.Message{}).
SetPathParam("user_id", userID).
SetBody(msg).
Post(o.getURL(getC2CURLBySendType(msg.GetSendType())))
func (o *openAPIv2) PostC2CMessage(ctx context.Context, userID string, msg dto.APIMessage) (*dto.C2CMessageResponse, error) {
var resp *resty.Response
var err error

msgType := msg.GetSendType()
switch msgType {
case dto.RichMedia:
resp, err = o.request(ctx).
SetResult(dto.MediaResponse{}). // 设置为媒体响应类型
SetPathParam("user_id", userID).
SetBody(msg).
Post(o.getURL(getC2CURLBySendType(msgType)))
default:
resp, err = o.request(ctx).
SetResult(dto.Message{}). // 设置为消息类型
SetPathParam("user_id", userID).
SetBody(msg).
Post(o.getURL(getC2CURLBySendType(msgType)))
}

if err != nil {
return nil, err
}
return resp.Result().(*dto.Message), nil

result := &dto.C2CMessageResponse{}
switch msgType {
case dto.RichMedia:
result.MediaResponse = resp.Result().(*dto.MediaResponse)
default:
result.Message = resp.Result().(*dto.Message)
}

return result, nil
}
26 changes: 26 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ type Settings struct {
IdmapPro bool `yaml:"idmap_pro"`
CardAndNick string `yaml:"card_nick"`
AutoBind bool `yaml:"auto_bind"`
CustomBotName string `yaml:"custom_bot_name"`
SendDelay int `yaml:"send_delay"`
}

// LoadConfig 从文件中加载配置并初始化单例配置
Expand Down Expand Up @@ -1015,3 +1017,27 @@ func GetAutoBind() bool {
}
return instance.Settings.AutoBind
}

// 获取GetCustomBotName的值
func GetCustomBotName() string {
mu.Lock()
defer mu.Unlock()

if instance == nil {
mylog.Println("Warning: instance is nil when trying to GetCustomBotName value.")
return "Gensokyo全域机器人"
}
return instance.Settings.CustomBotName
}

// 获取send_delay的值
func GetSendDelay() int {
mu.Lock()
defer mu.Unlock()

if instance == nil {
mylog.Println("Warning: instance is nil when trying to GetSendDelay value.")
return 300
}
return instance.Settings.SendDelay
}
4 changes: 3 additions & 1 deletion handlers/get_login_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ func init() {
func getLoginInfo(client callapi.Client, api openapi.OpenAPI, apiv2 openapi.OpenAPI, message callapi.ActionMessage) {

var response LoginInfoResponse
var botname string

// Assuming 全局_botid is a global or environment variable
globalBotID := config.GetAppID() // Replace with the actual global variable or value
userIDStr := fmt.Sprintf("%d", globalBotID)
botname = config.GetCustomBotName()

response.Data = LoginInfoData{
Nickname: "gensokyo全域机器人",
Nickname: botname,
UserID: userIDStr,
}
response.Message = ""
Expand Down
6 changes: 4 additions & 2 deletions handlers/handle_quick_operation.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package handlers

import (
"strconv"

"github.com/hoshinonyaruko/gensokyo/callapi"
"github.com/tencent-connect/botgo/openapi"
)
Expand Down Expand Up @@ -30,7 +32,7 @@ func CreateSendGroupMsgAction(originalMsg callapi.ActionMessage) *callapi.Action
return &callapi.ActionMessage{
Action: "send_group_msg",
Params: callapi.ParamsContent{
GroupID: originalMsg.Params.Context.GroupID,
GroupID: strconv.Itoa(originalMsg.Params.Context.GroupID), // 将int转换为string
Message: originalMsg.Params.Operation.Reply,
},
}
Expand All @@ -39,7 +41,7 @@ func CreateSendGroupMsgAction(originalMsg callapi.ActionMessage) *callapi.Action
return &callapi.ActionMessage{
Action: "send_private_msg",
Params: callapi.ParamsContent{
UserID: originalMsg.Params.Context.UserID,
UserID: strconv.Itoa(originalMsg.Params.Context.UserID), // 将int转换为string
Message: originalMsg.Params.Operation.Reply,
},
}
Expand Down
2 changes: 2 additions & 0 deletions handlers/message_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ func parseMessageContent(paramsMessage callapi.ParamsContent) (string, map[strin
urlImagePattern := regexp.MustCompile(`\[CQ:image,file=https?://(.+)\]`)
base64ImagePattern := regexp.MustCompile(`\[CQ:image,file=base64://(.+)\]`)
base64RecordPattern := regexp.MustCompile(`\[CQ:record,file=base64://(.+)\]`)
urlRecordPattern := regexp.MustCompile(`\[CQ:record,file=https?://(.+)\]`)

patterns := []struct {
key string
Expand All @@ -160,6 +161,7 @@ func parseMessageContent(paramsMessage callapi.ParamsContent) (string, map[strin
{"base64_image", base64ImagePattern},
{"base64_record", base64RecordPattern},
{"local_record", localRecordPattern},
{"url_record", urlRecordPattern},
}

foundItems := make(map[string][]string)
Expand Down
83 changes: 72 additions & 11 deletions handlers/send_group_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"github.com/hoshinonyaruko/gensokyo/images"
"github.com/hoshinonyaruko/gensokyo/mylog"
"github.com/hoshinonyaruko/gensokyo/silk"
"github.com/hoshinonyaruko/gensokyo/url"
"github.com/tencent-connect/botgo/dto"
"github.com/tencent-connect/botgo/openapi"
)
Expand Down Expand Up @@ -340,7 +339,8 @@ func handleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap
tryMessageTypes := []string{"group", "guild", "guild_private"}
messageCopy := message // 创建message的副本
echo.AddMsgType(config.GetAppIDStr(), idInt64, tryMessageTypes[echo.GetMapping(idInt64)-1])
time.Sleep(300 * time.Millisecond)
delay := config.GetSendDelay()
time.Sleep(time.Duration(delay) * time.Millisecond)
handleSendGroupMsg(client, api, apiv2, messageCopy)
}
}
Expand Down Expand Up @@ -481,15 +481,15 @@ func generateGroupMessage(id string, foundItems map[string][]string, messageText
}
}
// 将图片链接缩短 避免 url not allow
if config.GetLotusValue() {
// 连接到另一个gensokyo
newURL = url.GenerateShortURL(newURL)
} else {
// 自己是主节点
newURL = url.GenerateShortURL(newURL)
// 使用getBaseURL函数来获取baseUrl并与newURL组合
newURL = url.GetBaseURL() + "/url/" + newURL
}
// if config.GetLotusValue() {
// // 连接到另一个gensokyo
// newURL = url.GenerateShortURL(newURL)
// } else {
// // 自己是主节点
// newURL = url.GenerateShortURL(newURL)
// // 使用getBaseURL函数来获取baseUrl并与newURL组合
// newURL = url.GetBaseURL() + "/url/" + newURL
// }
newpiclink = newURL
} else {
newpiclink = "http://" + imageURLs[0]
Expand Down Expand Up @@ -540,6 +540,67 @@ func generateGroupMessage(id string, foundItems map[string][]string, messageText
SrvSendMsg: false,
}
}
} else if imageURLs, ok := foundItems["url_record"]; ok && len(imageURLs) > 0 {
// 从URL下载语音
resp, err := http.Get("http://" + imageURLs[0])
if err != nil {
mylog.Printf("Error downloading the record: %v", err)
return &dto.MessageToCreate{
Content: "错误: 下载语音失败",
MsgID: id,
MsgSeq: msgseq,
MsgType: 0, // 默认文本类型
}
}
defer resp.Body.Close()

// 读取语音数据
recordData, err := io.ReadAll(resp.Body)
if err != nil {
mylog.Printf("Error reading the record data: %v", err)
return &dto.MessageToCreate{
Content: "错误: 读取语音数据失败",
MsgID: id,
MsgSeq: msgseq,
MsgType: 0,
}
}
//判断并转码
if !silk.IsAMRorSILK(recordData) {
mt, ok := silk.CheckAudio(bytes.NewReader(recordData))
if !ok {
mylog.Errorf("voice type error: " + mt)
return nil
}
recordData = silk.EncoderSilk(recordData)
mylog.Errorf("音频转码ing")
if err != nil {
return nil
}
}
// 转换为base64
base64Encoded := base64.StdEncoding.EncodeToString(recordData)

// 上传语音并获取新的URL
newURL, err := images.UploadBase64RecordToServer(base64Encoded)
if err != nil {
mylog.Printf("Error uploading base64 encoded image: %v", err)
return &dto.MessageToCreate{
Content: "错误: 上传图片失败",
MsgID: id,
MsgSeq: msgseq,
MsgType: 0,
}
}

// 发链接语音
return &dto.RichMediaMessage{
EventID: id,
FileType: 3, // 3代表语音
URL: newURL, // 新语音链接
Content: "", // 这个字段文档没有了
SrvSendMsg: false,
}
} else if base64_image, ok := foundItems["base64_image"]; ok && len(base64_image) > 0 {
// todo 适配base64图片
//因为QQ群没有 form方式上传,所以在gensokyo内置了图床,需公网,或以lotus方式连接位于公网的gensokyo
Expand Down
Loading
Loading