commands to initialize a community from scratch, with sane default base-config to allow this action
This commit is contained in:
@@ -33,16 +33,38 @@ with this plugin's capabilities:
|
||||
to the space
|
||||
|
||||
by following this structure, you reduce the amount of surface area you have to spend time defending against spam and
|
||||
implementing censorship rules.
|
||||
implementing censorship rules. the handy `!community initialize <some name for your community>` command will get you
|
||||
from zero to an opinionated community structured this way quickly and easily.
|
||||
|
||||
if that doesn't sound like how you want to structure your online community, you might be better off using something like
|
||||
Draupnir or Mjolnir.
|
||||
Draupnir, Meowlnir, or Mjolnir.
|
||||
|
||||
# features
|
||||
|
||||
please read through the comments in the `base-config.yaml` for more thorough explanations, but this covers the high
|
||||
points.
|
||||
|
||||
## initialize a community from scratch
|
||||
|
||||
just installed the plugin for the first time, and want to get started on the right foot? start a DM with your bot and run:
|
||||
|
||||
`!community initialize <your community name>`
|
||||
|
||||
this will perform several actions on your behalf:
|
||||
|
||||
1. create a space named for your community, with an appropriate alias on the homeserver, and save the config with this parent room ID
|
||||
2. add you to the "invitee" list in the config to be invited to all new rooms
|
||||
3. set the bot's power level to 1000, and invite you as an administrator with power level 100
|
||||
4. create a room within the space for admins/moderators to execute bot commands, this room is invite only
|
||||
5. create a publicly facing room called the waiting room to allow newcomers to join and ask for invitation to your space
|
||||
6. enable basic keyword and file upload censorship only on the waiting room
|
||||
7. all rooms will require moderator permissions to invite additional users, to prevent rogue invitations or unexpected guests
|
||||
|
||||
once these actions have been taken, you can manage moderators, change room avatars, etc as you like, and add more rooms with
|
||||
other commands. happy community-managing!
|
||||
|
||||
attempts to run this command once a parent room has been set will fail.
|
||||
|
||||
## greet new users on joining a room
|
||||
|
||||
configure your bot to send a custom greeting to users whenever they join a room! configuration file provides a greeting
|
||||
@@ -70,7 +92,9 @@ purging admin accounts, backup accounts, rarely used bots, etc.
|
||||
members to the space automatically trigger a sync, as do most other commands. this command is mostly deprecated but you
|
||||
may want to run it just to see what it does.
|
||||
|
||||
generate a report with the `report` subcommand (i.e. `!community report`) to see your inactive users.
|
||||
generate a report with the `report` subcommand (i.e. `!community report`) to see your inactive users. you can also
|
||||
generate more specific reports using the `inactive`, `purgable`, and `ignored` commands to see users in those specific
|
||||
categories.
|
||||
|
||||
## user management
|
||||
|
||||
|
||||
+20
-9
@@ -1,7 +1,9 @@
|
||||
# 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
|
||||
# some features may not work if this is a regular room. use a space.
|
||||
parent_room: "!somerandomcharacters:server.tld"
|
||||
# leave this empty to use the initialize command to create a new community to manage,
|
||||
# based on opinionated defaults.
|
||||
parent_room: ''
|
||||
|
||||
# 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
|
||||
@@ -13,10 +15,19 @@ sleep: 5
|
||||
# when creating new rooms
|
||||
encrypt: False
|
||||
|
||||
# when creating a new room, what power-level should be required to invite users?
|
||||
# this is helpful to prevent malicious accounts from inviting spam bots by restricting
|
||||
# room defaults to moderators being the only people who can invite new users from outside
|
||||
# of your managed community. otherwise, you must be a space member to join the rooms.
|
||||
invite_power_level: 50
|
||||
|
||||
# number of days of inactivity to be considered in the "warning zone"
|
||||
# users in this category will appear in the report as inactive
|
||||
warn_threshold_days: 30
|
||||
|
||||
# number of days of inactivity to be considered in the "danger zone"
|
||||
# users in this category will appear in the purgable report and are
|
||||
# subject to removal by the purge command.
|
||||
kick_threshold_days: 60
|
||||
|
||||
# track users? if false, will disable all tracking and avoid writing anything to the database.
|
||||
@@ -39,9 +50,8 @@ admins: []
|
||||
moderators: []
|
||||
|
||||
# list of users who should be invited to new rooms immediately (other bots, moderators, perhaps)
|
||||
invitees:
|
||||
- "@mybot:server.tld"
|
||||
- "@secondaryadmin:server.tld"
|
||||
# use full matrix IDs here
|
||||
invitees: []
|
||||
|
||||
# auto-greet users in rooms with these messages
|
||||
# map greeting messages to a room
|
||||
@@ -66,7 +76,7 @@ greeting_rooms:
|
||||
'!someotherroom:server.tld': generic
|
||||
'!myencryptedroomid:server.tld': encrypted
|
||||
|
||||
# how long to wait (in seconds) before sending a greeting to a new
|
||||
# how long to wait (in seconds) before sending a greeting to a new joiner
|
||||
welcome_sleep: 0
|
||||
|
||||
# add a room ID here to send a message to when someone joins the above rooms
|
||||
@@ -109,13 +119,14 @@ censor_wordlist_instaban: []
|
||||
banlists:
|
||||
- '#community-moderation-effort-bl:neko.dev'
|
||||
|
||||
# should we ban proactively? this will generate ban events across all rooms every time
|
||||
# the ban lists have a new policy added, which may be noisy. however, without this enabled,
|
||||
# should we ban proactively? this will ban users in your rooms if a new ban event is added to
|
||||
# the banlist policy room for their account. however, without this enabled,
|
||||
# an account may join your rooms, THEN get added to the banlist, and you will have to manually
|
||||
# ban them from your rooms.
|
||||
proactive_banning: true
|
||||
|
||||
# should we redact messages when a user is banned?
|
||||
# should we redact messages when a user is banned? limited to their last 100 messages in each room.
|
||||
# redactions are processed every minute, they are not immediate.
|
||||
redact_on_ban: true
|
||||
|
||||
# should we verify that users are human before allowing them to send messages?
|
||||
@@ -146,4 +157,4 @@ verification_attempts: 3
|
||||
verification_message: |
|
||||
Thank you for joining {room}. As an anti-spam measure, you must demonstrate that you are a real person before you can send messages in its rooms.
|
||||
|
||||
Please send a message to this chat with the phrase: "{phrase}"
|
||||
Please send a message to this chat with the content: "{phrase}"
|
||||
|
||||
+229
-41
@@ -78,6 +78,7 @@ class Config(BaseProxyConfig):
|
||||
helper.copy("verification_phrases")
|
||||
helper.copy("verification_attempts")
|
||||
helper.copy("verification_message")
|
||||
helper.copy("invite_power_level")
|
||||
|
||||
|
||||
class CommunityBot(Plugin):
|
||||
@@ -1109,11 +1110,22 @@ class CommunityBot(Plugin):
|
||||
async def community(self) -> None:
|
||||
pass
|
||||
|
||||
async def check_parent_room(self, evt: MessageEvent) -> bool:
|
||||
"""Check if parent room is configured and handle the response if not."""
|
||||
if not self.config["parent_room"]:
|
||||
await evt.reply(
|
||||
"No parent room configured. Please use the 'initialize' command to set up your community space first."
|
||||
)
|
||||
return False
|
||||
return True
|
||||
|
||||
@community.subcommand(
|
||||
"bancheck", help="check subscribed banlists for a user's mxid"
|
||||
)
|
||||
@command.argument("mxid", "full matrix ID", required=True)
|
||||
async def check_banlists(self, evt: MessageEvent, mxid: UserID) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
ban_status = await self.check_if_banned(mxid)
|
||||
await evt.reply(f"user on banlist: {ban_status}")
|
||||
|
||||
@@ -1123,6 +1135,8 @@ class CommunityBot(Plugin):
|
||||
in case they are missing",
|
||||
)
|
||||
async def sync_space_members(self, evt: MessageEvent) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
if not await self.user_permitted(evt.sender):
|
||||
await evt.reply("You don't have permission to use this command")
|
||||
return
|
||||
@@ -1189,6 +1203,8 @@ class CommunityBot(Plugin):
|
||||
)
|
||||
@command.argument("mxid", "full matrix ID", required=True)
|
||||
async def ignore_inactivity(self, evt: MessageEvent, mxid: UserID) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
if not await self.user_permitted(evt.sender):
|
||||
await evt.reply("You don't have permission to use this command")
|
||||
return
|
||||
@@ -1214,6 +1230,8 @@ class CommunityBot(Plugin):
|
||||
)
|
||||
@command.argument("mxid", "full matrix ID", required=True)
|
||||
async def unignore_inactivity(self, evt: MessageEvent, mxid: UserID) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
if not await self.user_permitted(evt.sender):
|
||||
await evt.reply("You don't have permission to use this command")
|
||||
return
|
||||
@@ -1238,6 +1256,8 @@ class CommunityBot(Plugin):
|
||||
"report", help="generate a full list of activity tracking status"
|
||||
)
|
||||
async def get_report(self, evt: MessageEvent) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
if not await self.user_permitted(evt.sender):
|
||||
await evt.reply("You don't have permission to use this command")
|
||||
return
|
||||
@@ -1263,6 +1283,8 @@ class CommunityBot(Plugin):
|
||||
"inactive", help="generate a list of mxids who have been inactive"
|
||||
)
|
||||
async def get_inactive_report(self, evt: MessageEvent) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
if not await self.user_permitted(evt.sender):
|
||||
await evt.reply("You don't have permission to use this command")
|
||||
return
|
||||
@@ -1284,6 +1306,8 @@ class CommunityBot(Plugin):
|
||||
"purgable", help="generate a list of matrix IDs that have been inactive long enough to be purged"
|
||||
)
|
||||
async def get_purgable_report(self, evt: MessageEvent) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
if not await self.user_permitted(evt.sender):
|
||||
await evt.reply("You don't have permission to use this command")
|
||||
return
|
||||
@@ -1304,6 +1328,8 @@ class CommunityBot(Plugin):
|
||||
"ignored", help="generate a list of matrix IDs that have activity tracking disabled"
|
||||
)
|
||||
async def get_ignored_report(self, evt: MessageEvent) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
if not await self.user_permitted(evt.sender):
|
||||
await evt.reply("You don't have permission to use this command")
|
||||
return
|
||||
@@ -1323,6 +1349,8 @@ class CommunityBot(Plugin):
|
||||
|
||||
@community.subcommand("purge", help="kick users for excessive inactivity")
|
||||
async def kick_users(self, evt: MessageEvent) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
await evt.mark_read()
|
||||
if not await self.user_permitted(evt.sender):
|
||||
await evt.reply("You don't have permission to use this command")
|
||||
@@ -1377,6 +1405,8 @@ class CommunityBot(Plugin):
|
||||
)
|
||||
@command.argument("mxid", "full matrix ID", required=True)
|
||||
async def kick_user(self, evt: MessageEvent, mxid: UserID) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
await evt.mark_read()
|
||||
if not await self.user_permitted(evt.sender):
|
||||
await evt.reply("You don't have permission to use this command")
|
||||
@@ -1427,6 +1457,8 @@ class CommunityBot(Plugin):
|
||||
)
|
||||
@command.argument("mxid", "full matrix ID", required=True)
|
||||
async def ban_user(self, evt: MessageEvent, mxid: UserID) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
await evt.mark_read()
|
||||
if not await self.user_permitted(evt.sender):
|
||||
await evt.reply("You don't have permission to use this command")
|
||||
@@ -1450,6 +1482,8 @@ class CommunityBot(Plugin):
|
||||
)
|
||||
@command.argument("mxid", "full matrix ID", required=True)
|
||||
async def unban_user(self, evt: MessageEvent, mxid: UserID) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
await evt.mark_read()
|
||||
if not await self.user_permitted(evt.sender):
|
||||
await evt.reply("You don't have permission to use this command")
|
||||
@@ -1504,6 +1538,8 @@ class CommunityBot(Plugin):
|
||||
async def mark_for_redaction(
|
||||
self, evt: MessageEvent, mxid: UserID, room: str
|
||||
) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
await evt.mark_read()
|
||||
if not await self.user_permitted(evt.sender):
|
||||
await evt.reply("You don't have permission to use this command")
|
||||
@@ -1532,12 +1568,14 @@ class CommunityBot(Plugin):
|
||||
)
|
||||
await evt.respond(f"Queued {len(messages)} messages for redaction in {room_id}")
|
||||
|
||||
async def create_room(self, roomname: str, evt: MessageEvent = None) -> None:
|
||||
async def create_room(self, roomname: str, evt: MessageEvent = None, power_level_override: Optional[PowerLevelStateEventContent] = None, creation_content: Optional[dict] = None) -> None:
|
||||
"""Create a new room and add it to the parent space.
|
||||
|
||||
Args:
|
||||
roomname: The name for the new room
|
||||
evt: Optional MessageEvent for progress updates. If provided, will send status messages.
|
||||
power_level_override: Optional power levels to use. If not provided, will try to get from parent room.
|
||||
creation_content: Optional creation content to use when creating the room.
|
||||
|
||||
Returns:
|
||||
tuple: (room_id, room_alias) if successful, None if failed
|
||||
@@ -1552,16 +1590,25 @@ class CommunityBot(Plugin):
|
||||
parent_room = self.config["parent_room"]
|
||||
server = self.client.parse_user_id(self.client.mxid)[1]
|
||||
|
||||
# Get parent room power levels to use as template
|
||||
power_levels = await self.client.get_state_event(
|
||||
self.config["parent_room"], EventType.ROOM_POWER_LEVELS
|
||||
)
|
||||
|
||||
user_power_levels = power_levels.users
|
||||
|
||||
# ensure bot has highest power
|
||||
user_power_levels[self.client.mxid] = 1000
|
||||
self.log.debug(f"DEBUG user power levels: {user_power_levels}")
|
||||
# Get power levels from parent room if not provided
|
||||
if not power_level_override and parent_room:
|
||||
power_levels = await self.client.get_state_event(
|
||||
parent_room, EventType.ROOM_POWER_LEVELS
|
||||
)
|
||||
user_power_levels = power_levels.users
|
||||
# ensure bot has highest power
|
||||
user_power_levels[self.client.mxid] = 1000
|
||||
power_levels.users = user_power_levels
|
||||
power_level_override = power_levels
|
||||
elif not power_level_override:
|
||||
# If no parent room and no override provided, create default power levels
|
||||
power_levels = PowerLevelStateEventContent()
|
||||
power_levels.users = {
|
||||
self.client.mxid: 1000, # Bot gets highest power
|
||||
}
|
||||
# Set invite power level from config
|
||||
power_levels.invite = self.config["invite_power_level"]
|
||||
power_level_override = power_levels
|
||||
|
||||
if evt:
|
||||
mymsg = await evt.respond(
|
||||
@@ -1569,26 +1616,30 @@ class CommunityBot(Plugin):
|
||||
)
|
||||
|
||||
# Prepare initial state events
|
||||
initial_state = [
|
||||
{
|
||||
"type": str(EventType.SPACE_PARENT),
|
||||
"state_key": parent_room,
|
||||
"content": {
|
||||
"via": [server],
|
||||
"canonical": True
|
||||
initial_state = []
|
||||
|
||||
# Only add space parent state if we have a parent room
|
||||
if parent_room:
|
||||
initial_state.extend([
|
||||
{
|
||||
"type": str(EventType.SPACE_PARENT),
|
||||
"state_key": parent_room,
|
||||
"content": {
|
||||
"via": [server],
|
||||
"canonical": True
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": str(EventType.ROOM_JOIN_RULES),
|
||||
"content": {
|
||||
"join_rule": "restricted",
|
||||
"allow": [{
|
||||
"type": "m.room_membership",
|
||||
"room_id": parent_room
|
||||
}]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": str(EventType.ROOM_JOIN_RULES),
|
||||
"content": {
|
||||
"join_rule": "restricted",
|
||||
"allow": [{
|
||||
"type": "m.room_membership",
|
||||
"room_id": parent_room
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
])
|
||||
|
||||
# Add encryption if needed
|
||||
if self.config["encrypt"] or force_encryption:
|
||||
@@ -1605,20 +1656,22 @@ class CommunityBot(Plugin):
|
||||
name=roomname,
|
||||
invitees=invitees,
|
||||
initial_state=initial_state,
|
||||
power_level_override={"users": user_power_levels}
|
||||
power_level_override=power_level_override,
|
||||
creation_content=creation_content
|
||||
)
|
||||
|
||||
# The space child relationship needs to be set in the parent room separately
|
||||
await self.client.send_state_event(
|
||||
parent_room,
|
||||
EventType.SPACE_CHILD,
|
||||
{
|
||||
"via": [server],
|
||||
"suggested": False
|
||||
},
|
||||
state_key=room_id
|
||||
)
|
||||
await asyncio.sleep(self.config["sleep"])
|
||||
if parent_room:
|
||||
await self.client.send_state_event(
|
||||
parent_room,
|
||||
EventType.SPACE_CHILD,
|
||||
{
|
||||
"via": [server],
|
||||
"suggested": False
|
||||
},
|
||||
state_key=room_id
|
||||
)
|
||||
await asyncio.sleep(self.config["sleep"])
|
||||
|
||||
if evt:
|
||||
await evt.respond(
|
||||
@@ -1643,6 +1696,8 @@ class CommunityBot(Plugin):
|
||||
)
|
||||
@command.argument("roomname", pass_raw=True, required=True)
|
||||
async def create_that_room(self, evt: MessageEvent, roomname: str) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
if (roomname == "help") or len(roomname) == 0:
|
||||
await evt.reply(
|
||||
'pass me a room name (like "cool topic") and i will create it and add it to the space. \
|
||||
@@ -1662,6 +1717,8 @@ class CommunityBot(Plugin):
|
||||
@community.subcommand("archive", help="archive a room")
|
||||
@command.argument("room", required=False)
|
||||
async def archive_room(self, evt: MessageEvent, room: str) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
await evt.mark_read()
|
||||
|
||||
if not await self.user_permitted(evt.sender):
|
||||
@@ -1697,6 +1754,8 @@ class CommunityBot(Plugin):
|
||||
@community.subcommand("replaceroom", help="replace a room with a new one")
|
||||
@command.argument("room", required=False)
|
||||
async def replace_room(self, evt: MessageEvent, room: str) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
await evt.mark_read()
|
||||
|
||||
if not await self.user_permitted(evt.sender):
|
||||
@@ -1857,6 +1916,8 @@ class CommunityBot(Plugin):
|
||||
)
|
||||
@command.argument("room", required=False)
|
||||
async def get_guestlist(self, evt: MessageEvent, room: str) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
space_members_obj = await self.client.get_joined_members(
|
||||
self.config["parent_room"]
|
||||
)
|
||||
@@ -1895,6 +1956,8 @@ class CommunityBot(Plugin):
|
||||
)
|
||||
@command.argument("room", required=False)
|
||||
async def get_roomid(self, evt: MessageEvent, room: str) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
room_id = None
|
||||
if room:
|
||||
if room.startswith("#"):
|
||||
@@ -1922,6 +1985,8 @@ class CommunityBot(Plugin):
|
||||
evt: MessageEvent,
|
||||
target_room: str = None
|
||||
) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
await evt.mark_read()
|
||||
if not await self.user_permitted(evt.sender, min_level=100):
|
||||
await evt.reply("You don't have permission to use this command")
|
||||
@@ -2021,6 +2086,8 @@ class CommunityBot(Plugin):
|
||||
help="migrate a room to a verification-based permission model, ensuring current members can still send messages while new joiners require verification",
|
||||
)
|
||||
async def verify_migrate(self, evt: MessageEvent) -> None:
|
||||
if not await self.check_parent_room(evt):
|
||||
return
|
||||
await evt.mark_read()
|
||||
if not await self.user_permitted(evt.sender):
|
||||
await evt.reply("You don't have permission to use this command")
|
||||
@@ -2137,6 +2204,8 @@ class CommunityBot(Plugin):
|
||||
# If we can't check the state, assume it's stale
|
||||
await self.delete_verification_state(state["dm_room_id"])
|
||||
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_db_upgrade_table(cls) -> None:
|
||||
return upgrade_table
|
||||
@@ -2144,3 +2213,122 @@ class CommunityBot(Plugin):
|
||||
@classmethod
|
||||
def get_config_class(cls) -> Type[BaseProxyConfig]:
|
||||
return Config
|
||||
|
||||
@community.subcommand(
|
||||
"initialize",
|
||||
help="initialize a new community space with the given name. this command can only be used if no parent room is configured."
|
||||
)
|
||||
@command.argument("community_name", pass_raw=True, required=True)
|
||||
async def initialize_community(self, evt: MessageEvent, community_name: str) -> None:
|
||||
await evt.mark_read()
|
||||
|
||||
# Check if parent room is already configured
|
||||
if self.config["parent_room"]:
|
||||
await evt.reply("Cannot initialize: a parent room is already configured. Please remove the parent_room configuration first.")
|
||||
return
|
||||
|
||||
# Validate community name
|
||||
if not community_name or community_name.isspace():
|
||||
await evt.reply("Please provide a community name. Usage: !community initialize <community_name>")
|
||||
return
|
||||
|
||||
msg = await evt.respond("Initializing new community space...")
|
||||
|
||||
try:
|
||||
# Add initiator to invitees list if not already there
|
||||
if evt.sender not in self.config["invitees"]:
|
||||
self.config["invitees"].append(evt.sender)
|
||||
# Save the updated config
|
||||
self.config.save()
|
||||
|
||||
# Create the space
|
||||
server = self.client.parse_user_id(self.client.mxid)[1]
|
||||
sanitized_name = re.sub(r"[^a-zA-Z0-9]", "", community_name).lower()
|
||||
|
||||
# Set up power levels for the space
|
||||
power_levels = PowerLevelStateEventContent()
|
||||
power_levels.users = {
|
||||
self.client.mxid: 1000, # Bot gets highest power
|
||||
evt.sender: 100 # Initiator gets admin power
|
||||
}
|
||||
# Set invite power level from config
|
||||
power_levels.invite = self.config["invite_power_level"]
|
||||
|
||||
# Create the space with appropriate metadata and power levels
|
||||
space_id, space_alias = await self.create_room(
|
||||
community_name,
|
||||
evt,
|
||||
power_level_override=power_levels,
|
||||
creation_content={"type": "m.space"}
|
||||
)
|
||||
|
||||
# Set the space as the parent room in config
|
||||
self.config["parent_room"] = space_id
|
||||
|
||||
# Save the updated config
|
||||
self.config.save()
|
||||
|
||||
# Verify the space exists and has correct power levels
|
||||
try:
|
||||
space_power_levels = await self.client.get_state_event(space_id, EventType.ROOM_POWER_LEVELS)
|
||||
if space_power_levels.users.get(self.client.mxid) != 1000:
|
||||
raise Exception("Space power levels not set correctly")
|
||||
except Exception as e:
|
||||
error_msg = f"Failed to verify space setup: {e}"
|
||||
self.log.error(error_msg)
|
||||
await evt.respond(error_msg, edits=msg)
|
||||
return
|
||||
|
||||
# Create moderators room
|
||||
mod_room_id, mod_room_alias = await self.create_room(
|
||||
f"{community_name} Moderators",
|
||||
evt
|
||||
)
|
||||
|
||||
# Set moderators room to invite-only
|
||||
await self.client.send_state_event(
|
||||
mod_room_id,
|
||||
EventType.ROOM_JOIN_RULES,
|
||||
JoinRulesStateEventContent(join_rule=JoinRule.INVITE)
|
||||
)
|
||||
|
||||
# Create waiting room
|
||||
waiting_room_id, waiting_room_alias = await self.create_room(
|
||||
f"{community_name} Waiting Room",
|
||||
evt
|
||||
)
|
||||
|
||||
# Set waiting room to be joinable by anyone
|
||||
await self.client.send_state_event(
|
||||
waiting_room_id,
|
||||
EventType.ROOM_JOIN_RULES,
|
||||
JoinRulesStateEventContent(join_rule=JoinRule.PUBLIC)
|
||||
)
|
||||
|
||||
# Update censor configuration based on current value
|
||||
current_censor = self.config["censor"]
|
||||
if current_censor is False:
|
||||
# If censor is false, set it to a list with just the waiting room
|
||||
self.config["censor"] = [waiting_room_id]
|
||||
elif isinstance(current_censor, list) and waiting_room_id not in current_censor:
|
||||
# If censor is already a list and waiting room isn't in it, append it
|
||||
current_censor.append(waiting_room_id)
|
||||
self.config["censor"] = current_censor
|
||||
# If censor is True or waiting room is already in the list, leave it as is
|
||||
|
||||
# Save the updated config
|
||||
self.config.save()
|
||||
|
||||
await evt.respond(
|
||||
f"Community space initialized successfully!\n\n"
|
||||
f"Space: <a href='https://matrix.to/#/{space_alias}'>{space_alias}</a>\n"
|
||||
f"Moderators Room: <a href='https://matrix.to/#/{mod_room_alias}'>{mod_room_alias}</a>\n"
|
||||
f"Waiting Room: <a href='https://matrix.to/#/{waiting_room_alias}'>{waiting_room_alias}</a>",
|
||||
edits=msg,
|
||||
allow_html=True
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Failed to initialize community: {e}"
|
||||
self.log.error(error_msg)
|
||||
await evt.respond(error_msg, edits=msg)
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
maubot: 0.1.0
|
||||
id: org.jobmachine.communitybot
|
||||
version: 0.2.7
|
||||
version: 0.2.8
|
||||
license: MIT
|
||||
modules:
|
||||
- community
|
||||
|
||||
Reference in New Issue
Block a user