mqttim

MQTT ↔ Instant Messaging Bridge
git clone https://git.instinctive.eu/mqttim.git
Log | Files | Refs | README | LICENSE

commit cc737330ab46d0b4412f6704d8b847271c0d0eec
parent c5df43eb23a1e5f0da4d6b8bf30c64dc8788bb66
Author: Natasha Kerensikova <natgh@instinctive.eu>
Date:   Sun, 16 Jun 2024 09:14:31 +0000

First draft with basic functionalities
Diffstat:
Amain.go | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 114 insertions(+), 0 deletions(-)

diff --git a/main.go b/main.go @@ -0,0 +1,114 @@ +package main + +import ( + "errors" + "fmt" + "github.com/go-mqtt/mqtt" + "github.com/pelletier/go-toml/v2" + "github.com/thoj/go-ircevent" + "log" + "os" + "strings" + "time" +) + +type IrcConfig struct { + Channel string + Server string + Nick string + CmdStart string + CmdMid string + CmdEnd string +} + +type MqttConfig struct { + Server string + UserName string + Password string +} + +type Config struct { + Irc IrcConfig + Mqtt MqttConfig +} + +func readConfig(path string, config *Config) (err error) { + var f *os.File + f, err = os.Open("mqttim.toml") + if err != nil { + log.Fatal(err) + return err + } + defer f.Close() + + d := toml.NewDecoder(f) + err = d.Decode(config) + if err != nil { + log.Fatal(err) + } + + return err +} + +func main() { + var err error + var config Config + var m *mqtt.Client + + err = readConfig("mqttim.toml", &config) + if err != nil { + return + } + + m, err = mqtt.VolatileSession("mqttim", &mqtt.Config{ + Dialer: mqtt.NewDialer("tcp", config.Mqtt.Server), + PauseTimeout: 4 * time.Second, + UserName: config.Mqtt.UserName, + Password: []byte(config.Mqtt.Password), + }) + if err != nil { + log.Fatal(err) + return + } + go m.Subscribe(nil, "#") + + i := irc.IRC(config.Irc.Nick, "mqttim") +// i.VerboseCallbackHandler = true +// i.Debug = true + i.AddCallback("001", func(e *irc.Event) { i.Join(config.Irc.Channel) }) + i.AddCallback("366", func(e *irc.Event) {}) + i.AddCallback("PRIVMSG", func(e *irc.Event) { + msg := e.Message() + if !strings.HasPrefix(msg, config.Irc.CmdStart) || !strings.HasSuffix(msg, config.Irc.CmdEnd) { + return + } + topic, payload, found := strings.Cut(msg, config.Irc.CmdMid) + if found { + go m.Publish(nil, []byte(payload), topic) + } + }) + err = i.Connect(config.Irc.Server) + if err != nil { + fmt.Printf("Err %s", err) + return + } + go mqtt2irc(m, i, &config) + i.Loop() +} + +func mqtt2irc(m *mqtt.Client, i *irc.Connection, config *Config) error { + var big *mqtt.BigMessage + + for { + message, topic, err := m.ReadSlices() + switch { + case err == nil: + i.Privmsgf(config.Irc.Channel, "%s: %s", topic, message) + case errors.As(err, &big): + i.Privmsgf(config.Irc.Channel, "Big message from %s", big.Topic) + default: + log.Print(err) + return err + } + } +}