feat: persist invite-joined channels for auto-rejoin on connect

When the bot accepts an admin INVITE, the channel is stored in
bot.state under chanmgmt/autojoin:<channel>. On reconnect, persisted
channels are rejoined alongside configured ones. If the bot is kicked,
the channel is removed from the auto-rejoin list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
user
2026-02-15 22:22:24 +01:00
parent 122785b1f3
commit 83a1d37b98
3 changed files with 37 additions and 2 deletions

View File

@@ -85,6 +85,23 @@ async def cmd_mode(bot, message):
await bot.mode(message.target, mode_str, *args)
@event("001")
async def on_connect(bot, message):
"""Rejoin channels persisted from previous invite-joins."""
from derp.irc import format_msg
configured = set(bot.config["bot"]["channels"])
for key in bot.state.keys("chanmgmt"):
if not key.startswith("autojoin:"):
continue
channel = key[len("autojoin:"):]
if channel in configured:
continue
log.info("rejoining %s (autojoin)", channel)
await bot.join(channel)
await bot.conn.send(format_msg("WHO", channel))
@event("INVITE")
async def on_invite(bot, message):
"""Join a channel when invited by an admin or IRC operator."""
@@ -96,3 +113,17 @@ async def on_invite(bot, message):
return
log.info("accepting invite to %s from %s", channel, message.nick)
await bot.join(channel)
bot.state.set("chanmgmt", f"autojoin:{channel}", message.nick)
@event("KICK")
async def on_kick(bot, message):
"""Remove autojoin if the bot is kicked from a channel."""
if len(message.params) < 2:
return
kicked = message.params[1]
if kicked != bot.nick:
return
channel = message.target
if bot.state.delete("chanmgmt", f"autojoin:{channel}"):
log.info("removed autojoin for %s (kicked)", channel)