@@ -86,6 +86,10 @@ class PolicyList extends EventEmitter {
8686 // Events that we have already informed the batcher about, that we haven't loaded from the room state yet.
8787 private batchedEvents = new Set < string /* event id */ > ( ) ;
8888
89+ /** MSC3784 support. Please note that policy lists predate room types. So there will be lists in the wild without this type. */
90+ public static readonly ROOM_TYPE = "support.feline.policy.lists.msc.v1" ;
91+ public static readonly ROOM_TYPE_VARIANTS = [ PolicyList . ROOM_TYPE ]
92+
8993 /**
9094 * This is used to annotate state events we store with the rule they are associated with.
9195 * If we refactor this, it is important to also refactor any listeners to 'PolicyList.update'
@@ -105,6 +109,65 @@ class PolicyList extends EventEmitter {
105109 this . batcher = new UpdateBatcher ( this ) ;
106110 }
107111
112+ /**
113+ * Create a new policy list.
114+ * @param client A MatrixClient that will be used to create the list.
115+ * @param shortcode A shortcode to refer to the list with.
116+ * @param invite A list of users to invite to the list and make moderator.
117+ * @param createRoomOptions Additional room create options such as an alias.
118+ * @returns The room id for the newly created policy list.
119+ */
120+ public static async createList (
121+ client : MatrixClient ,
122+ shortcode : string ,
123+ invite : string [ ] ,
124+ createRoomOptions = { }
125+ ) : Promise < string /* room id */ > {
126+ const powerLevels : { [ key : string ] : any } = {
127+ "ban" : 50 ,
128+ "events" : {
129+ "m.room.name" : 100 ,
130+ "m.room.power_levels" : 100 ,
131+ } ,
132+ "events_default" : 50 , // non-default
133+ "invite" : 0 ,
134+ "kick" : 50 ,
135+ "notifications" : {
136+ "room" : 20 ,
137+ } ,
138+ "redact" : 50 ,
139+ "state_default" : 50 ,
140+ "users" : {
141+ [ await client . getUserId ( ) ] : 100 ,
142+ ...invite . reduce ( ( users , mxid ) => ( { ...users , [ mxid ] : 50 } ) , { } ) ,
143+ } ,
144+ "users_default" : 0 ,
145+ } ;
146+ const finalRoomCreateOptions = {
147+ // Support for MSC3784.
148+ creation_content : {
149+ type : PolicyList . ROOM_TYPE
150+ } ,
151+ preset : "public_chat" ,
152+ invite,
153+ initial_state : [
154+ {
155+ type : SHORTCODE_EVENT_TYPE ,
156+ state_key : "" ,
157+ content : { shortcode : shortcode }
158+ }
159+ ] ,
160+ power_level_content_override : powerLevels ,
161+ ...createRoomOptions
162+ } ;
163+ // Guard room type in case someone overwrites it when declaring custom creation_content in future code.
164+ if ( ! PolicyList . ROOM_TYPE_VARIANTS . includes ( finalRoomCreateOptions . creation_content . type ) ) {
165+ throw new TypeError ( `Creating a policy room with a type other than the policy room type is not supported, you probably don't want to do this.` ) ;
166+ }
167+ const listRoomId = await client . createRoom ( finalRoomCreateOptions ) ;
168+ return listRoomId
169+ }
170+
108171 /**
109172 * The code that can be used to refer to this banlist in Mjolnir commands.
110173 */
0 commit comments