3 Commits

Author SHA1 Message Date
90e2f38c18 v0.3.6; answerCallbackQuery 2026-02-03 14:51:57 +03:00
0921d306fd some fixes 2026-01-29 12:08:28 +03:00
6970c37c6b bump slog to v1.0.2 2026-01-29 11:59:38 +03:00
9 changed files with 91 additions and 97 deletions

12
bot.go
View File

@@ -30,8 +30,8 @@ type Bot struct {
logger *slog.Logger
requestLogger *slog.Logger
plugins []*Plugin
middlewares []*Middleware
plugins []Plugin
middlewares []Middleware
prefixes []string
runners []Runner
@@ -75,7 +75,7 @@ func LoadPrefixesFromEnv() []string {
func NewBot(settings *BotSettings) *Bot {
updateQueue := CreateQueue[*Update](256)
bot := &Bot{
updateOffset: 0, plugins: make([]*Plugin, 0), debug: settings.Debug, errorTemplate: "%s",
updateOffset: 0, plugins: make([]Plugin, 0), debug: settings.Debug, errorTemplate: "%s",
prefixes: settings.Prefixes, updateTypes: make([]string, 0), runners: make([]Runner, 0),
updateQueue: updateQueue,
token: settings.Token,
@@ -171,20 +171,20 @@ func (b *Bot) Debug(debug bool) *Bot {
b.debug = debug
return b
}
func (b *Bot) AddPlugins(plugin ...*Plugin) *Bot {
func (b *Bot) AddPlugins(plugin ...Plugin) *Bot {
b.plugins = append(b.plugins, plugin...)
for _, p := range plugin {
b.logger.Debugln(fmt.Sprintf("plugins with name \"%s\" registered", p.Name))
}
return b
}
func (b *Bot) AddMiddleware(middleware ...*Middleware) *Bot {
func (b *Bot) AddMiddleware(middleware ...Middleware) *Bot {
b.middlewares = append(b.middlewares, middleware...)
for _, m := range middleware {
b.logger.Debugln(fmt.Sprintf("middleware with name \"%s\" registered", m.Name))
}
sort.Slice(&b.middlewares, func(i, j int) bool {
sort.Slice(b.middlewares, func(i, j int) bool {
first := b.middlewares[i]
second := b.middlewares[j]
if first.Order == second.Order {

2
go.mod
View File

@@ -3,7 +3,7 @@ module git.nix13.pw/scuroneko/laniakea
go 1.25
require (
git.nix13.pw/scuroneko/slog v1.0.0
git.nix13.pw/scuroneko/slog v1.0.2
github.com/redis/go-redis/v9 v9.17.3
github.com/vinovest/sqlx v1.7.1
go.mongodb.org/mongo-driver/v2 v2.5.0

4
go.sum
View File

@@ -1,7 +1,7 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
git.nix13.pw/scuroneko/slog v1.0.0 h1:PI0YePrmCopjrljUfwCtBIEwNYB+PBgDzPcCXbetpcE=
git.nix13.pw/scuroneko/slog v1.0.0/go.mod h1:3Qm2wzkR5KjwOponMfG7TcGSDjmYaFqRAmLvSPTuWJI=
git.nix13.pw/scuroneko/slog v1.0.2 h1:vZyUROygxC2d5FJHUQM/30xFEHY1JT/aweDZXA4rm2g=
git.nix13.pw/scuroneko/slog v1.0.2/go.mod h1:3Qm2wzkR5KjwOponMfG7TcGSDjmYaFqRAmLvSPTuWJI=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=

View File

@@ -57,6 +57,7 @@ func (b *Bot) handleCallback(update *Update, ctx *MsgContext) {
ctx.From = update.CallbackQuery.From
ctx.Msg = update.CallbackQuery.Message
ctx.CallbackMsgId = update.CallbackQuery.Message.MessageID
ctx.CallbackQueryId = update.CallbackQuery.ID
ctx.Args = data.Args
for _, plugin := range b.plugins {

View File

@@ -130,7 +130,28 @@ type DeleteMessageP struct {
MessageID int `json:"message_id"`
}
func (b *Bot) DeleteMessage(params *DeleteMessageP) (*Message, error) {
req := NewRequest[Message]("deleteMessage", params)
return req.Do(b)
func (b *Bot) DeleteMessage(params *DeleteMessageP) (bool, error) {
req := NewRequest[bool]("deleteMessage", params)
ok, err := req.Do(b)
if err != nil {
return false, err
}
return *ok, err
}
type AnswerCallbackQueryP struct {
CallbackQueryID string `json:"callback_query_id"`
Text string `json:"text,omitempty"`
ShowAlert bool `json:"show_alert,omitempty"`
URL string `json:"url,omitempty"`
CacheTime int `json:"cache_time,omitempty"`
}
func (b *Bot) AnswerCallbackQuery(params *AnswerCallbackQueryP) (bool, error) {
req := NewRequest[bool]("answerCallbackQuery", params)
ok, err := req.Do(b)
if err != nil {
return false, err
}
return *ok, err
}

View File

@@ -8,6 +8,7 @@ type MsgContext struct {
Update *Update
From *User
CallbackMsgId int
CallbackQueryId string
FromID int
Prefix string
Text string
@@ -151,14 +152,41 @@ func (ctx *MsgContext) CallbackDelete() {
ctx.delete(ctx.CallbackMsgId)
}
func (ctx *MsgContext) Error(err error) {
_, sendErr := ctx.Bot.SendMessage(&SendMessageP{
ChatID: ctx.Msg.Chat.ID,
Text: fmt.Sprintf(ctx.Bot.errorTemplate, EscapeMarkdown(err.Error())),
func (ctx *MsgContext) answerCallbackQuery(url, text string, showAlert bool) {
if len(ctx.CallbackQueryId) == 0 {
return
}
_, err := ctx.Bot.AnswerCallbackQuery(&AnswerCallbackQueryP{
CallbackQueryID: ctx.CallbackQueryId,
Text: text, ShowAlert: showAlert, URL: url,
})
if err != nil {
ctx.Bot.logger.Errorln(err)
if sendErr != nil {
ctx.Bot.logger.Errorln(sendErr)
}
}
func (ctx *MsgContext) AnswerCbQuery() {
ctx.answerCallbackQuery("", "", false)
}
func (ctx *MsgContext) AnswerCbQueryText(text string) {
ctx.answerCallbackQuery("", text, false)
}
func (ctx *MsgContext) AnswerCbQueryAlert(text string) {
ctx.answerCallbackQuery("", text, true)
}
func (ctx *MsgContext) AnswerCbQueryUrl(u string) {
ctx.answerCallbackQuery(u, "", false)
}
func (ctx *MsgContext) error(err error) {
text := fmt.Sprintf(ctx.Bot.errorTemplate, EscapeMarkdown(err.Error()))
if ctx.CallbackQueryId != "" {
ctx.answerCallbackQuery("", text, false)
} else {
ctx.answer(text, nil)
}
ctx.Bot.logger.Errorln(err)
}
func (ctx *MsgContext) Error(err error) {
ctx.error(err)
}

View File

@@ -45,17 +45,16 @@ func (p *PluginBuilder) UpdateListener(listener CommandExecutor) *PluginBuilder
return p
}
func (p *PluginBuilder) Build() *Plugin {
func (p *PluginBuilder) Build() Plugin {
if len(p.commands) == 0 && len(p.payloads) == 0 {
log.Println("no command or payloads")
}
plugin := &Plugin{
return Plugin{
Name: p.name,
Commands: p.commands,
Payloads: p.payloads,
UpdateListener: p.updateListener,
}
return plugin
}
func (p *Plugin) Execute(cmd string, ctx *MsgContext, dbContext *DatabaseContext) {
@@ -68,13 +67,13 @@ func (p *Plugin) ExecutePayload(payload string, ctx *MsgContext, dbContext *Data
type Middleware struct {
Name string
Executor *CommandExecutor
Executor CommandExecutor
Order int
Async bool
}
type MiddlewareBuilder struct {
name string
executor *CommandExecutor
executor CommandExecutor
order int
async bool
}
@@ -87,7 +86,7 @@ func (m *MiddlewareBuilder) SetName(name string) *MiddlewareBuilder {
return m
}
func (m *MiddlewareBuilder) SetExecutor(executor CommandExecutor) *MiddlewareBuilder {
m.executor = &executor
m.executor = executor
return m
}
func (m *MiddlewareBuilder) SetOrder(order int) *MiddlewareBuilder {
@@ -98,19 +97,18 @@ func (m *MiddlewareBuilder) SetAsync(async bool) *MiddlewareBuilder {
m.async = async
return m
}
func (m *MiddlewareBuilder) Build() *Middleware {
return &Middleware{
func (m *MiddlewareBuilder) Build() Middleware {
return Middleware{
Name: m.name,
Executor: m.executor,
Order: m.order,
Async: m.async,
}
}
func (m *Middleware) Execute(ctx *MsgContext, db *DatabaseContext) {
exec := *m.Executor
func (m Middleware) Execute(ctx *MsgContext, db *DatabaseContext) {
if m.Async {
go exec(ctx, db)
go m.Executor(ctx, db)
} else {
exec(ctx, db)
m.Execute(ctx, db)
}
}

View File

@@ -73,57 +73,3 @@ func EscapeMarkdownV2(s string) string {
}
return s
}
func GetUnclosedTag(markdown string) string {
// order is important!
var tags = []string{
"```",
"`",
"*",
"_",
}
var currentTag = ""
markdownRunes := []rune(markdown)
var i = 0
outer:
for i < len(markdownRunes) {
// skip escaped characters (only outside tags)
if markdownRunes[i] == '\\' && currentTag == "" {
i += 2
continue
}
if currentTag != "" {
if strings.HasPrefix(string(markdownRunes[i:]), currentTag) {
// turn a tag off
i += len(currentTag)
currentTag = ""
continue
}
} else {
for _, tag := range tags {
if strings.HasPrefix(string(markdownRunes[i:]), tag) {
// turn a tag on
currentTag = tag
i += len(currentTag)
continue outer
}
}
}
i++
}
return currentTag
}
func IsValid(markdown string) bool {
return GetUnclosedTag(markdown) == ""
}
func FixMarkdown(markdown string) string {
tag := GetUnclosedTag(markdown)
if tag == "" {
return markdown
}
return markdown + tag
}

View File

@@ -1,8 +1,8 @@
package laniakea
const (
VersionString = "0.3.2"
VersionString = "0.3.6"
VersionMajor = 0
VersionMinor = 3
VersionPatch = 2
VersionPatch = 6
)