1
0
Fork 0

initial, incomplete work in IRC support

This commit is contained in:
Michał Rudowicz 2025-03-23 17:08:36 +01:00
parent 4c50b33e1c
commit 704d34d241
5 changed files with 123 additions and 1 deletions

View File

@ -38,6 +38,24 @@ type HttpCallbackConfig struct {
Method string `yaml:"method"`
}
type IrcConfig struct {
Server string `yaml:"server"`
Port int `yaml:"port"`
/// Nick which will be used. Users on IRC will see the bot as this nick.
Nick string `yaml:"nick"`
/// Username presented to the server
User string `yaml:"user"`
/// Name presented to the server
Name string `yaml:"name"`
/// Usually the username used for NickServ login
SaslUser string `yaml:"sasl-user"`
/// Usually the password used for NickServ password
SaslPass string `yaml:"sasl-pass"`
SSL bool `yaml:"ssl"`
/// Channels to which this bot will join, send status to and receive commands from
Channels []string `yaml:"channels"`
}
type AppConfig struct {
SatelAddr string `yaml:"satel-addr"`
ChatIds []int64 `yaml:"tg-chat-ids"`
@ -49,6 +67,7 @@ type AppConfig struct {
AlarmCallbacks []HttpCallbackConfig `yaml:"alarm-callbacks"`
WriteMemoryProfile bool `yaml:"write-memory-profile"`
Matterbridge []MatterbridgeConfig `yaml:"matterbridge"`
Irc []IrcConfig `yaml:"irc"`
TelegramApiKey string `yaml:"telegram-api-key"`
}
@ -182,5 +201,10 @@ func MakeConfig(logger *log.Logger) AppConfig {
}
getCmdLineParams(&config, logger)
if len(config.Irc) > 1 {
logger.Fatal("Configuring of more than one IRC connection is not supported.")
}
return config
}

View File

@ -1,6 +1,7 @@
package main
import (
"bytes"
"log"
"os"
"testing"
@ -50,6 +51,21 @@ matterbridge:
username: test_username_2
`
const ircConfig = `
irc:
- server: irc.libera.chat
port: 6697
nick: testbot
user: testbot
name: "Test Bot"
sasl-user: testbot
sasl-pass: testbotpassword
ssl: True
channels:
- "#hswro"
- "#testchannelpleaseignore"
`
func TestParseYamlConfig(t *testing.T) {
a := assert.New(t)
@ -76,4 +92,18 @@ func TestParseYamlConfig(t *testing.T) {
a.Equal(actualConfig.Matterbridge[1].Token, "test_token_2")
a.Equal(actualConfig.Matterbridge[1].Gateway, "test_gateway_2")
a.Equal(actualConfig.Matterbridge[1].Username, "test_username_2")
a.Nil(actualConfig.Irc)
}
func TestParseYamlConfig_IrcConfig(t *testing.T) {
a := assert.New(t)
actualConfig := parseConfigFromFile(
bytes.Join([][]byte{[]byte(data), []byte(ircConfig)}, []byte{}),
log.New(os.Stderr, "", log.Ltime))
a.ElementsMatch([]IrcConfig{{
"irc.libera.chat", 6697, "testbot", "testbot", "Test Bot", "testbot", "testbotpassword", true,
[]string{"#hswro", "#testchannelpleaseignore"}}}, actualConfig.Irc)
}

3
go.mod
View File

@ -5,14 +5,15 @@ go 1.19
require (
git.sr.ht/~michalr/go-satel v0.0.0-20240306182245-7ac13d8e4733
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
github.com/lrstanley/girc v0.0.0-20250219025855-423afa8a8828
github.com/stretchr/testify v1.8.4
gopkg.in/yaml.v3 v3.0.1
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/probakowski/go-satel => git.sr.ht/~michalr/go-satel v0.0.0-20211120120346-bed9818777ce

2
go.sum
View File

@ -15,6 +15,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc=
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8=
github.com/lrstanley/girc v0.0.0-20250219025855-423afa8a8828 h1:tJcJDAvGGM1xy1gt6A/7jzTLOnjJsDTxOkykzEgoh9w=
github.com/lrstanley/girc v0.0.0-20250219025855-423afa8a8828/go.mod h1:lgrnhcF8bg/Bd5HA5DOb4Z+uGqUqGnp4skr+J2GwVgI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=

65
irc.go Normal file
View File

@ -0,0 +1,65 @@
package main
import (
"html/template"
"log"
"time"
"github.com/lrstanley/girc"
)
type IrcBot struct {
client *girc.Client
logger *log.Logger
s SatelNameGetter
config AppConfig
}
func MakeIrcBot(config AppConfig, logger *log.Logger, s SatelNameGetter) *IrcBot {
if config.Irc == nil {
return nil
}
client := girc.New(girc.Config{
Server: config.Irc[0].Server,
Port: config.Irc[0].Port,
Nick: config.Irc[0].Nick,
User: config.Irc[0].User,
Name: config.Irc[0].Name,
Out: logger.Writer(),
})
return &IrcBot{client, logger, s, config}
}
func (bot *IrcBot) GetInterestingChannels() []girc.Channel {
return []girc.Channel{}
}
func (bot *IrcBot) SendMessageToAllChannels(msg string) {
for i, channel := range bot.GetInterestingChannels() {
if i != 0 {
// to avoid sending too many messages at once
// do it only if we have more than one message to send
time.Sleep(time.Millisecond * 500)
}
bot.client.Cmd.Message(channel.Name, msg)
}
}
type NotifyViaIRCSync struct {
SyncFilterImpl[GenericMessage]
bot *IrcBot
tpl *template.Template
}
func (bot *IrcBot) GetNotifyViaIRC(tpl *template.Template) *NotifyViaIRCSync {
return &NotifyViaIRCSync{SyncFilterImpl[GenericMessage]{}, bot, tpl}
}
func (notifyViaIRC *NotifyViaIRCSync) Call(msg GenericMessage) {
notifyViaIRC.bot.SendMessageToAllChannels(
msg.Format(notifyViaIRC.tpl, notifyViaIRC.bot.s, notifyViaIRC.bot.logger))
notifyViaIRC.CallNext(msg)
}