package main import ( "html/template" "log" "slices" "sync" "time" "github.com/lrstanley/girc" ) type IrcBot struct { client *girc.Client logger *log.Logger s SatelNameGetter config AppConfig wg *sync.WaitGroup connected bool } func MakeIrcBot(config AppConfig, logger *log.Logger, s SatelNameGetter, wg *sync.WaitGroup) *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(), SSL: config.Irc[0].SSL, SASL: &girc.SASLPlain{ User: config.Irc[0].SaslUser, Pass: config.Irc[0].SaslPass, }, }) client.Cmd.Join(config.Irc[0].Channels...) return &IrcBot{client, logger, s, config, wg, false} } func (bot *IrcBot) Connect() { if bot.connected { log.Fatal("Tried to connect again to an already connected IRC session! This is a bug.") } bot.connected = true bot.wg.Add(1) go func() { for { if err := bot.client.Connect(); err != nil { log.Printf("Connect error: %s, reconnecting in 30 seconds...", err) time.Sleep(30 * time.Second) } else { bot.wg.Done() return } } }() } func (bot *IrcBot) Close() { bot.client.Close() } func (bot IrcBot) filterOutNotConfiguredChannels(in []string) []string { return slices.DeleteFunc(in, func(channel string) bool { return !slices.Contains(bot.config.Irc[0].Channels, channel) }) } func (bot *IrcBot) GetInterestingChannels() []string { return bot.filterOutNotConfiguredChannels(bot.client.ChannelList()) } 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, 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) }