|
|
package bot
import ( "context" "log" "strings" "time"
"git.aiterp.net/gisle/irc" "git.aiterp.net/rpdata/logbot3/internal/models/channels" )
var botKey = "git.aiterp.net/rpdata/logbot.Bot.key"
// The Bot is the IRC client.
type Bot struct { commandChannel string client *irc.Client ctx context.Context ctxCancel context.CancelFunc }
// New creates a new Bot.
func New(ctx context.Context, nick string, alternatives []string) *Bot { client := irc.New(ctx, irc.Config{ Nick: nick, Alternatives: alternatives, SendRate: 2, SkipSSLVerification: false, })
bot := &Bot{ client: client, }
client.SetValue(botKey, bot)
return bot }
// Connect connects the bot to the IRC server. This will disconnect already
// established connections.
func (bot *Bot) Connect(server string, ssl bool) error { if bot.ctxCancel != nil { bot.ctxCancel() } bot.ctx, bot.ctxCancel = context.WithCancel(bot.client.Context())
return bot.client.Connect(server, ssl) }
func (bot *Bot) loop() { ticker := time.NewTicker(time.Second * 10) defer ticker.Stop()
log.Println("Client ready.")
for { select { case <-ticker.C: { bot.syncChannels() }
case <-bot.ctx.Done(): { log.Println("Spinning down bot main loop.") return } } } }
func (bot *Bot) syncChannels() { channels, err := channels.ListOpen(bot.ctx) if err != nil { log.Println("Failed to update channel-list:", err) return }
names := make([]string, 0, len(channels)) joins := make([]string, 0, len(channels)) leaves := make([]string, 0, len(names))
// Add new channels to join list.
for _, channel := range channels { name := channel.Name names = append(names, name)
if bot.client.Channel(name) == nil { joins = append(joins, name) } }
// Add no longer logged channels to leave list.
LeaveLoop: for _, channel := range bot.client.Channels() { for _, name := range names { if strings.ToLower(channel.Name()) == strings.ToLower(name) { continue LeaveLoop } } }
// Join channels.
if len(joins) > 0 { log.Println("Joining", strings.Join(joins, ", ")) bot.client.SendQueuedf("JOIN %s", strings.Join(joins, ",")) }
// leave channels.
if len(leaves) > 0 { log.Println("Leaving", strings.Join(leaves, ", ")) bot.client.SendQueuedf("PART %s :Channel removed.", strings.Join(leaves, ",")) } }
func (bot *Bot) stopLoop() { if bot.ctxCancel != nil { bot.ctxCancel() } }
|