Add per-chat nick setting, update README.md

This commit is contained in:
eleksir
2023-11-05 16:33:17 +03:00
parent d88f08479d
commit 31490b0922
7 changed files with 47 additions and 20 deletions

View File

@@ -7,14 +7,15 @@
## Что он может?
Имеет возможность соединяться с сервером по протоколу xmpp как с шифрованием, так и без. (Пока что) Шифрование
* Имеет возможность соединяться с сервером по протоколу xmpp как с шифрованием, так и без. (Пока что) Шифрование
работает по классическим механикам (шифрованный канал связи, без возможности коммуникации в незашифрованном виде),
без поддержки механизма start tls. Что-то в гошке или на стороне сервера при выборе StartTLS не работает.
Имеет возможность заносить пользователей в бан-лист, согласно заданным в чёрном списке правилам: по совпадению с
регулярными выражениями в nick-е или jid-е злодея, а также по регулярным выражениям характерных фраз. Правила можно
настроить как глобально, для всех комнат, где присутствует бот, так и для каждой комнаты отдельно. При изменении списка
правил бота не надо перезапускать, достаточно отдать ему команду rehash либо в приват, либо прям в чатике.
без поддержки механизма start tls. (Что-то в гошке или на стороне сервера при выборе StartTLS не работает.)
* Имеет возможность заносить пользователей в бан-лист, согласно заданным в чёрном списке правилам:
- по совпадению с регулярными выражениями в nick-е или jid-е злодея
- по регулярным выражениям характерных фраз.
- Правила можно настроить как глобально, для всех комнат, где присутствует бот, так и для каждой комнаты отдельно.
- При изменении списка правил бота не надо перезапускать, достаточно отдать ему команду rehash либо в приват, либо прям в чатике.
* Есть настройка заходить в разные комнаты под разными никами
## Что он не может?

View File

@@ -5,7 +5,7 @@
"room_name": "",
# Записывать ли в reason в банлисте комнаты сообщение вида autoban at yyyy.MM.dd hh:mm:ss.
# Если не задано, то false
# Если не задано, то false.
"reason_enable": false,
# Список регулярок JID-ов, которых надо банить.

View File

@@ -71,6 +71,10 @@
# Название канала, обязательное поле
"name" : "my_channel@conference.jabber.tld",
# Под каким ником бот зайдёт конкретно на этот канал. Если не задано, будет использован ник, заданный в
# общих настройках Jabber, выше по конфигу.
"nick" : "sailormoon",
# Настройки байесовского классификатора. В виду вероятности ложного срабатывания возможно, имеет смысл
# воздержаться от использования. Зависит от использования и от словарей.
"bayes": {

View File

@@ -33,11 +33,14 @@ func parseEvent(e interface{}) { //nolint:maintidx,gocognit,gocyclo
// Групповой чятик
case "groupchat":
log.Debugf("Message from public chat: %s", v.Text)
// room := strings.SplitN(v.Remote, "/", 2)[0]
nick := strings.SplitN(v.Remote, "/", 2)[1]
var (
room = strings.SplitN(v.Remote, "/", 2)[0]
nick = strings.SplitN(v.Remote, "/", 2)[1]
)
if nick == config.Jabber.Nick {
log.Debugf("Message from public chat: %s", v.Text)
if nick == getBotNickFromRoomConfig(room) {
log.Debug("Skipping message from myself")
return
@@ -361,7 +364,7 @@ func parseEvent(e interface{}) { //nolint:maintidx,gocognit,gocyclo
mucNickMatch := false
for _, room := range roomsConnected {
mucNick := fmt.Sprintf("%s/%s", room, config.Jabber.Nick)
mucNick := fmt.Sprintf("%s/%s", room, getBotNickFromRoomConfig(room))
if v.From == mucNick {
mucNickMatch = true
@@ -384,7 +387,7 @@ func parseEvent(e interface{}) { //nolint:maintidx,gocognit,gocyclo
mucNickMatch := false
for _, room := range roomsConnected {
mucNick := fmt.Sprintf("%s/%s", room, config.Jabber.Nick)
mucNick := fmt.Sprintf("%s/%s", room, getBotNickFromRoomConfig(room))
if v.From == mucNick {
mucNickMatch = true
@@ -484,8 +487,11 @@ func parseEvent(e interface{}) { //nolint:maintidx,gocognit,gocyclo
if err := xml.Unmarshal(v.Query, &iqErrorCancelNotAcceptable); err == nil {
if v.To == talk.JID() {
nick := strings.SplitN(v.From, "/", 2)[1]
room := strings.SplitN(v.From, "/", 2)[0]
if slices.Contains(roomsConnected, iqErrorCancelNotAcceptable.By) &&
nick == getBotNickFromRoomConfig(room) {
if slices.Contains(roomsConnected, iqErrorCancelNotAcceptable.By) && nick == config.Jabber.Nick {
log.Errorf(
"Got Iq error message from: %s to: %s. Looks like i'm not in MUC anymore",
v.From, v.To,
@@ -577,7 +583,7 @@ func parseEvent(e interface{}) { //nolint:maintidx,gocognit,gocyclo
// Это наш собственный Presence
if v.Show == "" && v.Status == "" {
if nick == config.Jabber.Nick {
if nick == getBotNickFromRoomConfig(room) {
roomsConnected = append(roomsConnected, room)
// На всякий случай дедуплицируем список комнат, к которым мы заджойнились.
sort.Strings(roomsConnected)

16
lib.go
View File

@@ -355,7 +355,8 @@ func joinMuc(room string) {
}
}
if _, err := talk.JoinMUCNoHistory(room, config.Jabber.Nick); err != nil {
// Заходим в конфу, наконец-то
if _, err := talk.JoinMUCNoHistory(room, getBotNickFromRoomConfig(room)); err != nil {
log.Errorf("Unable to join to MUC: %s", room)
gTomb.Kill(err)
@@ -551,14 +552,13 @@ func probeMUCLiveness() { //nolint:gocognit
sleepTime := time.Duration(rand.Int63n(1000*config.Jabber.PingSplayDelay)) * time.Millisecond //nolint:gosec
time.Sleep(sleepTime)
if err := talk.PingS2S(talk.JID(), room+"/"+config.Jabber.Nick); err != nil {
if err := talk.PingS2S(talk.JID(), room+"/"+getBotNickFromRoomConfig(room)); err != nil {
gTomb.Kill(err)
return
}
}(room)
*/
var roomMap interface{}
roomMap, exist = mucCapsList.Get(room)
@@ -697,4 +697,14 @@ func getRealJIDfromNick(fullNick string) string {
return ""
}
func getBotNickFromRoomConfig(room string) string {
for _, roomStruct := range config.Jabber.Channels {
if roomStruct.Name == room {
return roomStruct.Nick
}
}
return config.Jabber.Nick
}
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */

View File

@@ -187,11 +187,15 @@ func readConfig() error { //nolint:gocognit,gocyclo
return errors.New("no jabber channels/rooms defined in config, quitting") //nolint:goerr113
}
for _, channel := range sampleConfig.Jabber.Channels {
for n, channel := range sampleConfig.Jabber.Channels {
if channel.Name == "" {
return errors.New("no \"name\" entry in jabber channel config")
}
if channel.Nick == "" {
sampleConfig.Jabber.Channels[n].Nick = sampleConfig.Jabber.Nick
}
// channel.Password может быть пустым, тогда пароля нет
// channel.Bayes.Enabled будет false, если не проставлен
@@ -260,6 +264,7 @@ func readConfig() error { //nolint:gocognit,gocyclo
config = sampleConfig
configLoaded = true
log.Infof("Using %s as config file", location) //nolint:wsl
break

View File

@@ -26,6 +26,7 @@ type myConfig struct {
BotMasters []string `json:"bot_masters,omitempty"`
Channels []struct {
Name string `json:"name,omitempty"`
Nick string `json:"nick,omitempty"`
Password string `json:"password,omitempty"`
Bayes struct {
Enabled bool `json:"enabled,omitempty"`