Files
trbot/unuse_plugins/plugin_voicelist.go
Hubert Chen f1a106c6e8 add bot instance when register plugins
slash start command:
    fix notes
    remove prefix argument underline suffix check
2025-08-28 05:53:28 +08:00

196 lines
5.6 KiB
Go

package plugins
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"trbot/utils/configs"
"trbot/utils/handler_params"
"trbot/utils/inline_utils"
"trbot/utils/plugin_utils"
"trbot/utils/yaml"
"github.com/go-telegram/bot"
"github.com/go-telegram/bot/models"
"github.com/rs/zerolog"
)
var VoiceLists []VoicePack
var VoiceListErr error
var VoiceListDir string = filepath.Join(configs.YAMLDatabaseDir, "voices/")
func init() {
plugin_utils.AddInitializer(plugin_utils.Initializer{
Name: "VoiceList",
Func: func(ctx context.Context, thebot *bot.Bot) error{
return ReadVoicePackFromPath(ctx)
},
})
plugin_utils.AddDataBaseHandler(plugin_utils.DatabaseHandler{
Name: "Voice List",
Loader: ReadVoicePackFromPath,
})
plugin_utils.AddInlineHandlers(plugin_utils.InlineHandler{
Command: "voice",
InlineHandler: VoiceListHandler,
Description: "一些语音列表",
})
}
type VoicePack struct {
Name string `yaml:"name,omitempty"` // 语音包名称
Voices []struct {
ID string `yaml:"ID,omitempty"` // 语音 ID
Title string `yaml:"Title,omitempty"` // 行内模式时显示的标题
Caption string `yaml:"Caption,omitempty"` // 发送后在语音下方的文字
VoiceURL string `yaml:"VoiceURL,omitempty"` // 音频文件网络链接
} `yaml:"voices,omitempty"`
}
// 读取指定目录下所有结尾为 .yaml 或 .yml 的语音文件
func ReadVoicePackFromPath(ctx context.Context) error {
logger := zerolog.Ctx(ctx).
With().
Str("pluginName", "Voice List").
Str("funcName", "ReadVoicePackFromPath").
Logger()
var packs []VoicePack
_, err := os.Stat(VoiceListDir)
if err != nil {
if os.IsNotExist(err) {
logger.Warn().
Str("directory", VoiceListDir).
Msg("VoiceList directory not exist, now create it")
err = os.MkdirAll(VoiceListDir, 0755)
if err != nil {
logger.Error().
Err(err).
Str("directory", VoiceListDir).
Msg("Failed to create VoiceList data directory")
VoiceListErr = err
return err
}
} else {
logger.Error().
Err(err).
Str("directory", VoiceListDir).
Msg("Open VoiceList data directory failed")
VoiceListErr = err
return err
}
}
err = filepath.Walk(VoiceListDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
logger.Error().
Err(err).
Str("path", path).
Msg("Failed to read file use `filepath.Walk()`")
}
if strings.HasSuffix(info.Name(), ".yaml") || strings.HasSuffix(info.Name(), ".yml") {
var singlePack VoicePack
err = yaml.LoadYAML(path, &singlePack)
if err != nil {
logger.Error().
Err(err).
Str("path", path).
Msg("Failed to decode file use `yaml.NewDecoder()`")
}
packs = append(packs, singlePack)
}
return nil
})
if err != nil {
logger.Error().
Err(err).
Str("directory", VoiceListDir).
Msg("Failed to read voice packs in VoiceList directory")
VoiceListErr = err
return err
}
VoiceLists = packs
return nil
}
func VoiceListHandler(opts *handler_params.InlineQuery) []models.InlineQueryResult {
// 将 metadata 转换为 Inline Query 结果
var results []models.InlineQueryResult
if VoiceLists == nil {
zerolog.Ctx(opts.Ctx).Warn().
Str("pluginName", "Voice List").
Str("funcName", "VoiceListHandler").
Str("VoiceListDir", VoiceListDir).
Msg("No voices file in VoiceListDir")
return []models.InlineQueryResult{&models.InlineQueryResultVoice{
ID: "none",
Title: "无法读取到语音文件,请联系机器人管理员",
Caption: "由于无法读取到语音文件,此处被替换为预设的 `♿otto: 我是说的道理~` ",
VoiceURL: "https://alist.trle5.xyz/d/voices/otto/我是说的道理.ogg",
ParseMode: models.ParseModeMarkdownV1,
}}
}
keywordFields := inline_utils.ParseInlineFields(opts.Fields).Keywords
// 没有查询字符串或使用分页搜索符号,返回所有结果
if len(keywordFields) == 0 {
for _, voicePack := range VoiceLists {
for _, voice := range voicePack.Voices {
results = append(results, &models.InlineQueryResultVoice{
ID: voice.ID,
Title: voicePack.Name + ": " + voice.Title,
Caption: voice.Caption,
VoiceURL: voice.VoiceURL,
})
}
}
} else {
for _, voicePack := range VoiceLists {
for _, voice := range voicePack.Voices {
if inline_utils.MatchMultKeyword(keywordFields, []string{voicePack.Name, voice.Title, voice.Caption}) {
results = append(results, &models.InlineQueryResultVoice{
ID: voice.ID,
Title: voicePack.Name + ": " + voice.Title,
Caption: voice.Caption,
VoiceURL: voice.VoiceURL,
})
}
}
}
if len(results) == 0 {
results = append(results, &models.InlineQueryResultArticle{
ID: "none",
Title: "没有符合关键词的内容",
Description: fmt.Sprintf("没有找到包含 %s 的内容", keywordFields),
InputMessageContent: &models.InputTextMessageContent{
MessageText: "用户在找不到想看的东西时无奈点击了提示信息...",
ParseMode: models.ParseModeMarkdownV1,
},
})
}
}
if VoiceListErr != nil {
return append([]models.InlineQueryResult{&models.InlineQueryResultArticle{
ID: "none",
Title: "读取语音文件时发生错误,请联系机器人管理员",
Description: "点此显示错误信息",
InputMessageContent: &models.InputTextMessageContent{
MessageText: fmt.Sprintf("读取语音文件时发生错误<blockquote expandable>%s</blockquote>", VoiceListErr),
ParseMode: models.ParseModeHTML,
},
}}, results...)
}
return results
}