Files
buny-jabber-bot/internal/jabber/commands.go
2025-11-15 16:15:00 +03:00

262 lines
6.2 KiB
Go

package jabber
import (
"buny-jabber-bot/internal/log"
"fmt"
"slices"
"strings"
"github.com/davecgh/go-spew/spew"
"github.com/eleksir/go-xmpp"
)
// Cmd парсит команды из чятика.
func (j *Jabber) Cmd(v xmpp.Chat) error {
var err error
switch v.Text {
case j.C.CSign + "help", j.C.CSign + "помощь":
var (
answer string
chosenOneTalks = false
)
realJID := j.GetRealJIDfromNick(v.Remote)
for _, master := range j.C.Jabber.BotMasters {
if (strings.SplitN(realJID, "/", 2))[0] == master {
chosenOneTalks = true
}
}
if chosenOneTalks {
answer = j.C.CSign + "помощь - этот список команд\n"
answer += j.C.CSign + "help - this commands list\n"
answer += j.C.CSign + "rehash - reload white and black lists (available to bot admins only)\n"
answer += j.C.CSign + "ver | " + j.C.CSign + "version - prints version of software"
} else {
answer = "Ничем помочь не могу. Луна не светит на тебя."
}
dest := v.Remote
if v.Type == "groupchat" {
dest = (strings.SplitN(v.Remote, "/", 2))[0]
}
if _, err := j.Talk.Send(
xmpp.Chat{ //nolint:exhaustruct
Remote: dest,
Text: strings.TrimSpace(answer),
Type: v.Type,
},
); err != nil {
err = fmt.Errorf("unable to send message to %s: %w", v.Remote, err)
return err
}
case j.C.CSign + "rehash":
/* Эта команда может прилетать из приватной беседы с realjid-ом, из приватной беседы с chat-nick-ом, а также из
* чятика.
* Groupchat мы можем определить по v.Type (groupchat) и тогда понятно что делать.
* А вот, например, приватные притязания определить несколько сложно-вато. Но можно попробовать, например,
* пытаться по списку presence-ов находить персонажа и его real jid и уже из этого определять master он или нет.
*/
// Попробуем определить каков алгоритм наших действий, в зависимости от типа сообщения.
switch v.Type {
case "groupchat":
// Проверим, является ли "командир" избранным или это самозванец?
var (
chosenOneTalks = false
listsLoaded = true
)
realJID := j.GetRealJIDfromNick(v.Remote)
for _, master := range j.C.Jabber.BotMasters {
if (strings.SplitN(realJID, "/", 2))[0] == master {
chosenOneTalks = true
}
}
if !chosenOneTalks {
log.Infof(
"Command %srehash given by non-bot_master user %s(%s), ignoring",
j.C.CSign,
realJID,
v.Remote,
)
var msg xmpp.Chat
msg.Remote = v.Remote
msg.Type = v.Type
msg.Text = "Ничем помочь не могу. Луна не светит на тебя."
_, err := j.Talk.Send(msg)
return err
}
if err := j.ReadWhitelist(); err != nil {
listsLoaded = false
var msg xmpp.Chat
msg.Remote = v.Remote
msg.Type = "chat" // private message.
msg.Text = fmt.Sprint(err)
if _, err := j.Talk.Send(msg); err != nil {
return err
}
}
if err := j.ReadBlacklist(); err != nil {
listsLoaded = false
var msg xmpp.Chat
msg.Remote = v.Remote
msg.Type = "chat" // private message.
msg.Text = fmt.Sprint(err)
if _, err := j.Talk.Send(msg); err != nil {
return err
}
}
if listsLoaded {
room := (strings.SplitN(v.Remote, "/", 2))[0]
var msg xmpp.Chat
msg.Remote = room
msg.Type = v.Type
msg.Text = "Сделано"
if _, err := j.Talk.Send(msg); err != nil {
return err
}
}
case "chat":
room := (strings.SplitN(v.Remote, "/", 2))[0]
// Реагировать на приватную команду "из комнаты", только если бот в комнате.
if slices.Contains(j.RoomsConnected, room) {
var (
chosenOneTalks = false
listsLoaded = true
)
// Реагировать на rehash только если собеседник является bot master-ом.
realJID := j.GetRealJIDfromNick(v.Remote)
for _, master := range j.C.Jabber.BotMasters {
if (strings.SplitN(realJID, "/", 2))[0] == master {
chosenOneTalks = true
}
}
if !chosenOneTalks {
log.Infof(
"Command %srehash given by non-bot_master user %s(%s), ignoring",
j.C.CSign,
realJID,
v.Remote,
)
var msg xmpp.Chat
msg.Remote = v.Remote
msg.Type = v.Type
msg.Text = "Ничем помочь не могу. Луна не светит на тебя."
_, err := j.Talk.Send(msg)
return err
}
if err := j.ReadWhitelist(); err != nil {
listsLoaded = false
var msg xmpp.Chat
msg.Remote = v.Remote
msg.Type = v.Type
msg.Text = fmt.Sprint(err)
if _, err := j.Talk.Send(msg); err != nil {
return err
}
}
if err := j.ReadBlacklist(); err != nil {
listsLoaded = false
var msg xmpp.Chat
msg.Remote = v.Remote
msg.Type = v.Type
msg.Text = fmt.Sprint(err)
if _, err := j.Talk.Send(msg); err != nil {
return err
}
}
if listsLoaded {
var msg xmpp.Chat
msg.Remote = v.Remote
msg.Type = v.Type
msg.Text = "Сделано"
if _, err := j.Talk.Send(msg); err != nil {
return err
}
}
}
default:
log.Infof("Rehash command from outer space: %s", spew.Sdump(v))
}
return err
case j.C.CSign + "ver", j.C.CSign + "version":
var (
answer = "Version " + j.C.Version
)
dest := v.Remote
if v.Type == "groupchat" {
dest = (strings.SplitN(v.Remote, "/", 2))[0]
}
if _, err := j.Talk.Send(
xmpp.Chat{ //nolint:exhaustruct
Remote: dest,
Text: strings.TrimSpace(answer),
Type: v.Type,
},
); err != nil {
err = fmt.Errorf("unable to send message to %s: %w", v.Remote, err)
return err
}
default:
return err
}
return err
}
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */