This commit is contained in:
William Kray
2025-04-04 13:31:14 -07:00
parent 84a1b3157b
commit 2cd234a7ee
2 changed files with 172 additions and 173 deletions
+9 -10
View File
@@ -1,12 +1,15 @@
# the room-id of the matrix room or space to use as your "full user list" # the room-id of the matrix room or space to use as your "full user list"
# changes to user power levelsin this room will affect all rooms in the space
parent_room: "!somerandomcharacters:server.tld" parent_room: "!somerandomcharacters:server.tld"
# sleep time between actions. you can drop this to 0 if your bot has no # sleep time between actions. you can drop this to 0 if your bot has no
# ratelimits imposed on its homeserver, otherwise you may want to increase this # ratelimits imposed on its homeserver, otherwise you may want to increase this
# to avoid errors. # to avoid errors.
sleep: 1 sleep: 5
# whether to encrypt rooms when using the room creation commands # whether to encrypt rooms when using the room creation commands
# when this is false, you can still use the --encrypt flag to force encryption
# when creating new rooms
encrypt: False encrypt: False
# number of days of inactivity to be considered in the "warning zone" # number of days of inactivity to be considered in the "warning zone"
@@ -27,18 +30,14 @@ track_messages: True
track_reactions: True track_reactions: True
# list of users who can use administrative commands. these users will also be made room admins (PL100) # list of users who can use administrative commands. these users will also be made room admins (PL100)
# DEPRECATED: set powerlevels in the parent room instead. # DEPRECATED: set user powerlevels in the parent room instead.
admins: admins: []
- '@user1:server.tld'
- '@user2:server.tld'
# list of users who should be considered community moderators. these users will be made room mods (PL50) # list of users who should be considered community moderators. these users will be made room mods (PL50)
# DEPRECATED: set powerlevels in the parent room instead. # DEPRECATED: set userpowerlevels in the parent room instead.
moderators: moderators: []
- '@user3:server.tld'
- '@user4:server.tld'
# list of users who should be invited to new rooms immediately (other bots perhaps) # list of users who should be invited to new rooms immediately (other bots, moderators, perhaps)
invitees: invitees:
- "@mybot:server.tld" - "@mybot:server.tld"
- "@secondaryadmin:server.tld" - "@secondaryadmin:server.tld"
+162 -162
View File
@@ -943,21 +943,21 @@ class CommunityBot(Plugin):
await evt.reply("You don't have permission to use this command") await evt.reply("You don't have permission to use this command")
return return
if not self.config["track_users"]: if not self.config["track_users"]:
await evt.reply("user tracking is disabled") await evt.reply("user tracking is disabled")
return return
try: try:
Client.parse_user_id(mxid) Client.parse_user_id(mxid)
await self.database.execute( await self.database.execute(
"UPDATE user_events SET ignore_inactivity = 1 WHERE \ "UPDATE user_events SET ignore_inactivity = 1 WHERE \
mxid = $1", mxid = $1",
mxid, mxid,
) )
self.log.info(f"{mxid} set to ignore inactivity") self.log.info(f"{mxid} set to ignore inactivity")
await evt.react("") await evt.react("")
except Exception as e: except Exception as e:
await evt.respond(f"{e}") await evt.respond(f"{e}")
@community.subcommand( @community.subcommand(
"unignore", help="re-enable activity tracking for a specific matrix ID" "unignore", help="re-enable activity tracking for a specific matrix ID"
@@ -968,21 +968,21 @@ class CommunityBot(Plugin):
await evt.reply("You don't have permission to use this command") await evt.reply("You don't have permission to use this command")
return return
if not self.config["track_users"]: if not self.config["track_users"]:
await evt.reply("user tracking is disabled") await evt.reply("user tracking is disabled")
return return
try: try:
Client.parse_user_id(mxid) Client.parse_user_id(mxid)
await self.database.execute( await self.database.execute(
"UPDATE user_events SET ignore_inactivity = 0 WHERE \ "UPDATE user_events SET ignore_inactivity = 0 WHERE \
mxid = $1", mxid = $1",
mxid, mxid,
) )
self.log.info(f"{mxid} set to track inactivity") self.log.info(f"{mxid} set to track inactivity")
await evt.react("") await evt.react("")
except Exception as e: except Exception as e:
await evt.respond(f"{e}") await evt.respond(f"{e}")
@community.subcommand( @community.subcommand(
"report", help="generate a list of matrix IDs that have been inactive" "report", help="generate a list of matrix IDs that have been inactive"
@@ -992,22 +992,22 @@ class CommunityBot(Plugin):
await evt.reply("You don't have permission to use this command") await evt.reply("You don't have permission to use this command")
return return
if not self.config["track_users"]: if not self.config["track_users"]:
await evt.reply("user tracking is disabled") await evt.reply("user tracking is disabled")
return return
sync_results = await self.do_sync() sync_results = await self.do_sync()
report = await self.generate_report() report = await self.generate_report()
await evt.respond( await evt.respond(
f"<p><b>Users inactive for between {self.config['warn_threshold_days']} and \ f"<p><b>Users inactive for between {self.config['warn_threshold_days']} and \
{self.config['kick_threshold_days']} days:</b><br /> \ {self.config['kick_threshold_days']} days:</b><br /> \
{'<br />'.join(report['warn_inactive'])} <br /></p>\ {'<br />'.join(report['warn_inactive'])} <br /></p>\
<p><b>Users inactive for at least {self.config['kick_threshold_days']} days:</b><br /> \ <p><b>Users inactive for at least {self.config['kick_threshold_days']} days:</b><br /> \
{'<br />'.join(report['kick_inactive'])} <br /></p> \ {'<br />'.join(report['kick_inactive'])} <br /></p> \
<p><b>Ignored users:</b><br /> \ <p><b>Ignored users:</b><br /> \
{'<br />'.join(report['ignored'])}</p>", {'<br />'.join(report['ignored'])}</p>",
allow_html=True, allow_html=True,
) )
@community.subcommand("purge", help="kick users for excessive inactivity") @community.subcommand("purge", help="kick users for excessive inactivity")
async def kick_users(self, evt: MessageEvent) -> None: async def kick_users(self, evt: MessageEvent) -> None:
@@ -1016,49 +1016,49 @@ class CommunityBot(Plugin):
await evt.reply("You don't have permission to use this command") await evt.reply("You don't have permission to use this command")
return return
msg = await evt.respond("starting the purge...") msg = await evt.respond("starting the purge...")
report = await self.generate_report() report = await self.generate_report()
purgeable = report["kick_inactive"] purgeable = report["kick_inactive"]
roomlist = await self.get_space_roomlist() roomlist = await self.get_space_roomlist()
# don't forget to kick from the space itself # don't forget to kick from the space itself
roomlist.append(self.config["parent_room"]) roomlist.append(self.config["parent_room"])
purge_list = {} purge_list = {}
error_list = {} error_list = {}
for user in purgeable: for user in purgeable:
purge_list[user] = [] purge_list[user] = []
for room in roomlist: for room in roomlist:
try: try:
roomname = None roomname = None
roomnamestate = await self.client.get_state_event( roomnamestate = await self.client.get_state_event(
room, "m.room.name" room, "m.room.name"
) )
roomname = roomnamestate["name"] roomname = roomnamestate["name"]
await self.client.get_state_event( await self.client.get_state_event(
room, EventType.ROOM_MEMBER, user room, EventType.ROOM_MEMBER, user
) )
await self.client.kick_user(room, user, reason="inactivity") await self.client.kick_user(room, user, reason="inactivity")
if roomname: if roomname:
purge_list[user].append(roomname) purge_list[user].append(roomname)
else: else:
purge_list[user].append(room) purge_list[user].append(room)
time.sleep("sleep") time.sleep("sleep")
except MNotFound: except MNotFound:
pass pass
except Exception as e: except Exception as e:
self.log.warning(e) self.log.warning(e)
error_list[user] = [] error_list[user] = []
error_list[user].append(roomname or room) error_list[user].append(roomname or room)
results = "the following users were purged:<p><code>{purge_list}</code></p>the following errors were \ results = "the following users were purged:<p><code>{purge_list}</code></p>the following errors were \
recorded:<p><code>{error_list}</code></p>".format( recorded:<p><code>{error_list}</code></p>".format(
purge_list=purge_list, error_list=error_list purge_list=purge_list, error_list=error_list
) )
await evt.respond(results, allow_html=True, edits=msg) await evt.respond(results, allow_html=True, edits=msg)
# sync our database after we've made changes to room memberships # sync our database after we've made changes to room memberships
await self.do_sync() await self.do_sync()
@community.subcommand( @community.subcommand(
"kick", help="kick a specific user from the community and all rooms" "kick", help="kick a specific user from the community and all rooms"
@@ -1070,45 +1070,45 @@ class CommunityBot(Plugin):
await evt.reply("You don't have permission to use this command") await evt.reply("You don't have permission to use this command")
return return
user = mxid user = mxid
msg = await evt.respond("starting the purge...") msg = await evt.respond("starting the purge...")
roomlist = await self.get_space_roomlist() roomlist = await self.get_space_roomlist()
# don't forget to kick from the space itself # don't forget to kick from the space itself
roomlist.append(self.config["parent_room"]) roomlist.append(self.config["parent_room"])
purge_list = {} purge_list = {}
error_list = {} error_list = {}
purge_list[user] = [] purge_list[user] = []
for room in roomlist: for room in roomlist:
try: try:
roomname = None roomname = None
roomnamestate = await self.client.get_state_event( roomnamestate = await self.client.get_state_event(
room, "m.room.name" room, "m.room.name"
) )
roomname = roomnamestate["name"] roomname = roomnamestate["name"]
await self.client.get_state_event(room, EventType.ROOM_MEMBER, user) await self.client.get_state_event(room, EventType.ROOM_MEMBER, user)
await self.client.kick_user(room, user, reason="kicked") await self.client.kick_user(room, user, reason="kicked")
if roomname: if roomname:
purge_list[user].append(roomname) purge_list[user].append(roomname)
else: else:
purge_list[user].append(room) purge_list[user].append(room)
time.sleep(self.config["sleep"]) time.sleep(self.config["sleep"])
except MNotFound: except MNotFound:
pass pass
except Exception as e: except Exception as e:
self.log.warning(e) self.log.warning(e)
error_list[user] = [] error_list[user] = []
error_list[user].append(roomname or room) error_list[user].append(roomname or room)
results = "the following users were kicked:<p><code>{purge_list}</code></p>the following errors were \ results = "the following users were kicked:<p><code>{purge_list}</code></p>the following errors were \
recorded:<p><code>{error_list}</code></p>".format( recorded:<p><code>{error_list}</code></p>".format(
purge_list=purge_list, error_list=error_list purge_list=purge_list, error_list=error_list
) )
await evt.respond(results, allow_html=True, edits=msg) await evt.respond(results, allow_html=True, edits=msg)
# sync our database after we've made changes to room memberships # sync our database after we've made changes to room memberships
await self.do_sync() await self.do_sync()
@community.subcommand( @community.subcommand(
"ban", help="kick and ban a specific user from the community and all rooms" "ban", help="kick and ban a specific user from the community and all rooms"
@@ -1120,18 +1120,18 @@ class CommunityBot(Plugin):
await evt.reply("You don't have permission to use this command") await evt.reply("You don't have permission to use this command")
return return
user = mxid user = mxid
msg = await evt.respond("starting the ban...") msg = await evt.respond("starting the ban...")
results_map = await self.ban_this_user(user, all_rooms=True) results_map = await self.ban_this_user(user, all_rooms=True)
results = "the following users were kicked and banned:<p><code>{ban_list}</code></p>the following errors were \ results = "the following users were kicked and banned:<p><code>{ban_list}</code></p>the following errors were \
recorded:<p><code>{error_list}</code></p>".format( recorded:<p><code>{error_list}</code></p>".format(
ban_list=results_map["ban_list"], error_list=results_map["error_list"] ban_list=results_map["ban_list"], error_list=results_map["error_list"]
) )
await evt.respond(results, allow_html=True, edits=msg) await evt.respond(results, allow_html=True, edits=msg)
# sync our database after we've made changes to room memberships # sync our database after we've made changes to room memberships
await self.do_sync() await self.do_sync()
@community.subcommand( @community.subcommand(
"unban", help="unban a specific user from the community and all rooms" "unban", help="unban a specific user from the community and all rooms"
@@ -1143,45 +1143,45 @@ class CommunityBot(Plugin):
await evt.reply("You don't have permission to use this command") await evt.reply("You don't have permission to use this command")
return return
user = mxid user = mxid
msg = await evt.respond("starting the unban...") msg = await evt.respond("starting the unban...")
roomlist = await self.get_space_roomlist() roomlist = await self.get_space_roomlist()
# don't forget to kick from the space itself # don't forget to kick from the space itself
roomlist.append(self.config["parent_room"]) roomlist.append(self.config["parent_room"])
unban_list = {} unban_list = {}
error_list = {} error_list = {}
unban_list[user] = [] unban_list[user] = []
for room in roomlist: for room in roomlist:
try: try:
roomname = None roomname = None
roomnamestate = await self.client.get_state_event( roomnamestate = await self.client.get_state_event(
room, "m.room.name" room, "m.room.name"
) )
roomname = roomnamestate["name"] roomname = roomnamestate["name"]
await self.client.get_state_event(room, EventType.ROOM_MEMBER, user) await self.client.get_state_event(room, EventType.ROOM_MEMBER, user)
await self.client.unban_user(room, user, reason="unbanned") await self.client.unban_user(room, user, reason="unbanned")
if roomname: if roomname:
unban_list[user].append(roomname) unban_list[user].append(roomname)
else: else:
unban_list[user].append(room) unban_list[user].append(room)
time.sleep(self.config["sleep"]) time.sleep(self.config["sleep"])
except MNotFound: except MNotFound:
pass pass
except Exception as e: except Exception as e:
self.log.warning(e) self.log.warning(e)
error_list[user] = [] error_list[user] = []
error_list[user].append(roomname or room) error_list[user].append(roomname or room)
results = "the following users were unbanned:<p><code>{unban_list}</code></p>the following errors were \ results = "the following users were unbanned:<p><code>{unban_list}</code></p>the following errors were \
recorded:<p><code>{error_list}</code></p>".format( recorded:<p><code>{error_list}</code></p>".format(
unban_list=unban_list, error_list=error_list unban_list=unban_list, error_list=error_list
) )
await evt.respond(results, allow_html=True, edits=msg) await evt.respond(results, allow_html=True, edits=msg)
# sync our database after we've made changes to room memberships # sync our database after we've made changes to room memberships
await self.do_sync() await self.do_sync()
@community.subcommand( @community.subcommand(
"redact", "redact",