diff --git a/apps/participation/management/commands/setup_third_phase.py b/apps/participation/management/commands/setup_third_phase.py
new file mode 100644
index 0000000..cab873e
--- /dev/null
+++ b/apps/participation/management/commands/setup_third_phase.py
@@ -0,0 +1,42 @@
+from django.core.management import BaseCommand
+
+from corres2math.matrix import Matrix, RoomVisibility
+from participation.models import Participation
+
+
+class Command(BaseCommand):
+ def handle(self, *args, **options):
+ for participation in Participation.objects.filter(valid=True).all():
+ for i, question in enumerate(participation.questions.order_by("id").all()):
+ solution_author = participation.received_participation.team
+ alias = f"equipe-{solution_author.trigram.lower()}-question-{i}"
+ room_id = f"#{alias}:correspondances-maths.fr"
+ Matrix.create_room(
+ visibility=RoomVisibility.public,
+ alias=alias,
+ name=f"Solution équipe {solution_author.trigram} - question {i+1}",
+ topic=f"Échange entre l'équipe {solution_author.name} ({solution_author.trigram}) "
+ f"et l'équipe {participation.team.name} ({participation.team.trigram}) "
+ f"autour de la question {i+1} sur le problème {participation.problem}",
+ federate=False,
+ invite=[f"@{registration.matrix_username}:correspondances-maths.fr" for registration in
+ list(participation.team.students.all()) + list(participation.team.coachs.all()) +
+ list(solution_author.students.all()) + list(solution_author.coachs.all())],
+ )
+ Matrix.set_room_power_level_event(room_id, "events_default", 21)
+ for registration in solution_author.students.all():
+ Matrix.set_room_power_level(room_id,
+ f"@{registration.matrix_username}:correspondances-maths.fr", 42)
+
+ Matrix.send_message(room_id, "Bienvenue dans la troisième phase des Correspondances !")
+ Matrix.send_message(room_id, f"L'équipe {participation.team.name} a visionné la vidéo de l'équipe "
+ f"{solution_author.name} sur le problème {participation.problem}, et a posé "
+ "une série de questions.")
+ Matrix.send_message(room_id, "L'équipe ayant composé la vidéo doit maintenant proposer une réponse.")
+ Matrix.send_message(room_id, "Une fois la réponse apportée, vous pourrez ensuite échanger plus "
+ "librement autour de la question, au travers de ce canal.")
+ Matrix.send_message(room_id, "**Question posée :**", formatted_body="Question posée :")
+ Matrix.send_message(room_id, question.question,
+ formatted_body=f"{question.question}")
+
+ # TODO Setup the bot the set the power level of all members of the room to 42
diff --git a/corres2math/matrix.py b/corres2math/matrix.py
index 1f340d8..ddf76c6 100644
--- a/corres2math/matrix.py
+++ b/corres2math/matrix.py
@@ -238,6 +238,29 @@ class Matrix:
room_id = await cls.resolve_room_alias(room_id)
return await client.room_invite(room_id, user_id)
+ @classmethod
+ @async_to_sync
+ async def send_message(cls, room_id: str, body: str, formatted_body: str = None,
+ msgtype: str = "m.text", html: bool = True):
+ """
+ Send a message to a room.
+ """
+ client = await cls._get_client()
+ if room_id.startswith("#"):
+ room_id = await cls.resolve_room_alias(room_id)
+ content = {
+ "msgtype": msgtype,
+ "body": body,
+ "formatted_body": formatted_body or body,
+ }
+ if html:
+ content["format"] = "org.matrix.custom.html"
+ return await client.room_send(
+ room_id=room_id,
+ message_type="m.room.message",
+ content=content,
+ )
+
@classmethod
@async_to_sync
async def kick(cls, room_id: str, user_id: str, reason: str = None) -> Union[RoomKickResponse, RoomInviteError]: