Skip to content

Commit

Permalink
Beta133 (#307)
Browse files Browse the repository at this point in the history
* beta122

* beta123

* beta124

* beta124

* beta124

* beta127

* beta128

* beta129

* beta130

* beta131

* beta132

* beta133
  • Loading branch information
Hoshinonyaruko authored Jan 16, 2024
1 parent e4b019c commit 86a712a
Show file tree
Hide file tree
Showing 4 changed files with 302 additions and 1 deletion.
223 changes: 223 additions & 0 deletions Processor/Processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ import (
"github.com/hoshinonyaruko/gensokyo/echo"
"github.com/hoshinonyaruko/gensokyo/handlers"
"github.com/hoshinonyaruko/gensokyo/idmap"
"github.com/hoshinonyaruko/gensokyo/images"
"github.com/hoshinonyaruko/gensokyo/mylog"
"github.com/hoshinonyaruko/gensokyo/wsclient"
"github.com/tencent-connect/botgo/dto"
"github.com/tencent-connect/botgo/dto/keyboard"
"github.com/tencent-connect/botgo/openapi"
)

Expand Down Expand Up @@ -552,6 +554,13 @@ func (p *Processors) HandleFrameworkCommand(messageText string, data interface{}
mylog.Printf("您没有权限,使用临时指令:%s 忽略权限检查,或将masterid设置为空数组", tempCmd)
SendMessage("您没有权限,请配置config.yml或查看日志,使用临时指令", data, Type, p.Api, p.Apiv2)
}

//link指令
if Type == "group" && strings.HasPrefix(cleanedMessage, config.GetLinkPrefix()) {
md, kb := generateMdByConfig()
SendMessageMd(md, kb, data, Type, p.Api, p.Apiv2)
}

return nil
}

Expand Down Expand Up @@ -789,6 +798,113 @@ func SendMessage(messageText string, data interface{}, messageType string, api o
return nil
}

// SendMessageMd 发送Md消息根据不同的类型
func SendMessageMd(md *dto.Markdown, kb *keyboard.MessageKeyboard, data interface{}, messageType string, api openapi.OpenAPI, apiv2 openapi.OpenAPI) error {
// 强制类型转换,获取Message结构
var msg *dto.Message
switch v := data.(type) {
case *dto.WSGroupATMessageData:
msg = (*dto.Message)(v)
case *dto.WSATMessageData:
msg = (*dto.Message)(v)
case *dto.WSMessageData:
msg = (*dto.Message)(v)
case *dto.WSDirectMessageData:
msg = (*dto.Message)(v)
case *dto.WSC2CMessageData:
msg = (*dto.Message)(v)
default:
return nil
}
switch messageType {
case "guild":
// 处理公会消息
msgseq := echo.GetMappingSeq(msg.ID)
echo.AddMappingSeq(msg.ID, msgseq+1)
Message := &dto.MessageToCreate{
Content: "markdown",
MsgID: msg.ID,
MsgSeq: msgseq,
Markdown: md,
Keyboard: kb,
MsgType: 2, //md信息
}
Message.Timestamp = time.Now().Unix() // 设置时间戳
if _, err := api.PostMessage(context.TODO(), msg.ChannelID, Message); err != nil {
mylog.Printf("发送文本信息失败: %v", err)
return err
}

case "group":
// 处理群组消息
msgseq := echo.GetMappingSeq(msg.ID)
echo.AddMappingSeq(msg.ID, msgseq+1)
Message := &dto.MessageToCreate{
Content: "markdown",
MsgID: msg.ID,
MsgSeq: msgseq,
Markdown: md,
Keyboard: kb,
MsgType: 2, //md信息
}
Message.Timestamp = time.Now().Unix() // 设置时间戳
_, err := apiv2.PostGroupMessage(context.TODO(), msg.GroupID, Message)
if err != nil {
mylog.Printf("发送文本群组信息失败: %v", err)
return err
}

case "guild_private":
// 处理私信
timestamp := time.Now().Unix()
timestampStr := fmt.Sprintf("%d", timestamp)
dm := &dto.DirectMessage{
GuildID: msg.GuildID,
ChannelID: msg.ChannelID,
CreateTime: timestampStr,
}
msgseq := echo.GetMappingSeq(msg.ID)
echo.AddMappingSeq(msg.ID, msgseq+1)
Message := &dto.MessageToCreate{
Content: "markdown",
MsgID: msg.ID,
MsgSeq: msgseq,
Markdown: md,
Keyboard: kb,
MsgType: 2, //md信息
}
Message.Timestamp = time.Now().Unix() // 设置时间戳
if _, err := apiv2.PostDirectMessage(context.TODO(), dm, Message); err != nil {
mylog.Printf("发送文本信息失败: %v", err)
return err
}

case "group_private":
// 处理群组私聊消息
msgseq := echo.GetMappingSeq(msg.ID)
echo.AddMappingSeq(msg.ID, msgseq+1)
Message := &dto.MessageToCreate{
Content: "markdown",
MsgID: msg.ID,
MsgSeq: msgseq,
Markdown: md,
Keyboard: kb,
MsgType: 2, //md信息
}
Message.Timestamp = time.Now().Unix() // 设置时间戳
_, err := apiv2.PostC2CMessage(context.TODO(), msg.Author.ID, Message)
if err != nil {
mylog.Printf("发送文本私聊信息失败: %v", err)
return err
}

default:
return errors.New("未知的消息类型")
}

return nil
}

// autobind 函数接受 interface{} 类型的数据
// commit by 紫夜 2023-11-19
func (p *Processors) Autobind(data interface{}) error {
Expand Down Expand Up @@ -922,3 +1038,110 @@ func GenerateAvatarURL(userID int64) (string, error) {
// 构建并返回 URL
return fmt.Sprintf("http://q%d.qlogo.cn/g?b=qq&nk=%d&s=640", qNumber, userID), nil
}

// 生成link卡片
func generateMdByConfig() (md *dto.Markdown, kb *keyboard.MessageKeyboard) {
//相关配置获取
mdtext := config.GetLinkText()
mdtext = "\r" + mdtext
CustomTemplateID := config.GetCustomTemplateID()
linkBots := config.GetLinkBots()
imgURL := config.GetLinkPic()

//超过16个时候随机显示
if len(linkBots) > 16 {
linkBots = getRandomSelection(linkBots, 16)
}

//组合 mdParams
var mdParams []*dto.MarkdownParams
if imgURL != "" {
height, width, err := images.GetImageDimensions(imgURL)
if err != nil {
mylog.Printf("获取图片宽高出错")
}
imgDesc := fmt.Sprintf("图片 #%dpx #%dpx", width, height)
// 创建 MarkdownParams 的实例
mdParams = []*dto.MarkdownParams{
{Key: "img_dec", Values: []string{imgDesc}},
{Key: "img_url", Values: []string{imgURL}},
{Key: "text_end", Values: []string{mdtext}},
}
} else {
mdParams = []*dto.MarkdownParams{
{Key: "text_end", Values: []string{mdtext}},
}
}

// 组合模板 Markdown
md = &dto.Markdown{
CustomTemplateID: CustomTemplateID,
Params: mdParams,
}

// 创建自定义键盘
customKeyboard := &keyboard.CustomKeyboard{}
var currentRow *keyboard.Row
var buttonCount int

for _, bot := range linkBots {
parts := strings.SplitN(bot, "-", 3)
if len(parts) < 3 {
continue // 跳过无效的格式
}
name := parts[2]
botuin := parts[1]
botappid := parts[0]
boturl := handlers.BuildQQBotShareLink(botuin, botappid)

button := &keyboard.Button{
RenderData: &keyboard.RenderData{
Label: name,
VisitedLabel: name,
Style: 1, // 蓝色边缘
},
Action: &keyboard.Action{
Type: 0, // 链接类型
Permission: &keyboard.Permission{Type: 2}, // 所有人可操作
Data: boturl,
UnsupportTips: "请升级新版手机QQ",
},
}

// 如果当前行为空或已满(4个按钮),则创建一个新行
if currentRow == nil || buttonCount == 4 {
currentRow = &keyboard.Row{}
customKeyboard.Rows = append(customKeyboard.Rows, currentRow)
buttonCount = 0
}

// 将按钮添加到当前行
currentRow.Buttons = append(currentRow.Buttons, button)
buttonCount++
}

// 创建 MessageKeyboard 并设置其 Content
kb = &keyboard.MessageKeyboard{
Content: customKeyboard,
}

return md, kb
}

func getRandomSelection(slice []string, max int) []string {
if len(slice) <= max {
return slice
}

selected := make(map[int]bool)
var result []string
for len(result) < max {
index, _ := rand.Int(rand.Reader, big.NewInt(int64(len(slice))))
idx := int(index.Int64())
if !selected[idx] {
selected[idx] = true
result = append(result, slice[idx])
}
}
return result
}
52 changes: 52 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ type Settings struct {
Uin int64 `yaml:"uin"`
VwhitePrefixMode bool `yaml:"v_white_prefix_mode"`
Enters []string `yaml:"enters"`
LinkPrefix string `yaml:"link_prefix"`
LinkBots []string `yaml:"link_bots"`
LinkText string `yaml:"link_text"`
LinkPic string `yaml:"link_pic"`
}

// LoadConfig 从文件中加载配置并初始化单例配置
Expand Down Expand Up @@ -1711,3 +1715,51 @@ func GetEnters() []string {
}
return nil // 返回nil,如果instance为nil
}

// 获取 LinkPrefix
func GetLinkPrefix() string {
mu.Lock()
defer mu.Unlock()

if instance == nil {
mylog.Println("Warning: instance is nil when trying to get LinkPrefix.")
return ""
}
return instance.Settings.LinkPrefix
}

// 获取 LinkBots 数组
func GetLinkBots() []string {
mu.Lock()
defer mu.Unlock()

if instance == nil {
mylog.Println("Warning: instance is nil when trying to get LinkBots.")
return nil
}
return instance.Settings.LinkBots
}

// 获取 LinkText
func GetLinkText() string {
mu.Lock()
defer mu.Unlock()

if instance == nil {
mylog.Println("Warning: instance is nil when trying to get LinkText.")
return ""
}
return instance.Settings.LinkText
}

// 获取 LinkPic
func GetLinkPic() string {
mu.Lock()
defer mu.Unlock()

if instance == nil {
mylog.Println("Warning: instance is nil when trying to get LinkPic.")
return ""
}
return instance.Settings.LinkPic
}
24 changes: 23 additions & 1 deletion handlers/send_group_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -1147,13 +1147,35 @@ func auto_md(message callapi.ActionMessage, messageText string, richMediaMessage
dataLabel = matchedPrefix.Prefix + whiteLabel
}

//在虚拟二级指令白名单,设置*前缀,代表不真实添加,仅再来一次
if strings.HasPrefix(whiteLabel, "*") {
//移除whiteLabel前端的*,*仅作为判断,不作为显示
whiteLabel = strings.TrimPrefix(whiteLabel, "*")
dataLabel = matchedPrefix.Prefix
}

//在虚拟二级指令白名单,设置&前缀,代表仅触发其本身
//如果&前缀指令包含了空格 则只显示空格右侧的文本
if strings.HasPrefix(whiteLabel, "&") {
//移除whiteLabel前端的*,*仅作为判断,不作为显示
whiteLabel = strings.TrimPrefix(whiteLabel, "&")
//这里是实际填充到data的
dataLabel = whiteLabel
// 找到最后一个空格的位置 显示空格右边的文本 没有找到空格则不变
lastSpaceIndex := strings.LastIndex(whiteLabel, " ")
if lastSpaceIndex != -1 && lastSpaceIndex < len(whiteLabel)-1 {
// 获取空格右侧的子字符串
whiteLabel = whiteLabel[lastSpaceIndex+1:]
}
}

var actiontype keyboard.ActionType
var permission *keyboard.Permission
var actiondata string
//检查是否设置了enter数组
enter := checkDataLabelPrefix(dataLabel)
switch whiteLabel {
case "邀请机器人":
case "邀请机器人", "邀请我", "添加我":
botuin := config.GetUinStr()
botappid := config.GetAppIDStr()
boturl := BuildQQBotShareLink(botuin, botappid)
Expand Down
4 changes: 4 additions & 0 deletions template/config_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ settings:
bind_prefix : "/bind" #需设置 #增强配置项 master_id 可触发
me_prefix : "/me" #需设置 #增强配置项 master_id 可触发
unlock_prefix : "/unlock" #频道私信卡住了? gsk可以帮到你 在任意子频道发送unlock 你会收到来自机器人的频道私信
link_prefix : "/link" #友情链接配置 配置custom_template_id后可用(https://www.yuque.com/km57bt/hlhnxg/tzbr84y59dbz6pib)
link_bots : ["",""] #发送友情链接时 下方按钮携带的机器人 格式 "appid-qq-name","appid-qq-name"
link_text : "" #友情链接文本 不可为空!
link_pic : "" #友情链接图片 可为空 需url图片 可带端口 不填可能会有显示错误
#穿透\cos\oss类配置(可选!)
frp_port : "0" #不使用请保持为0,frp的端口,frp有内外端口,请在frp软件设置gensokyo的port,并将frp显示的对外端口填入这里
Expand Down

0 comments on commit 86a712a

Please sign in to comment.