diff --git a/.env.template b/.env.template
index 14d809a1f04bd8efe90617ecaa35ef3e1042ee91..a9a427544e3f95d75fbfd3fa88b7745286896096 100644
--- a/.env.template
+++ b/.env.template
@@ -17,6 +17,8 @@ DISCORD_ROLE_MSG=<ID of role assignment message>
 DISCORD_SUPPORT_CHANNEL=<ID of channel where modmail & user news should be forwarded>
 DISCORD_WELCOME_CHANNEL=<ID of welcome channel>
 DISCORD_WELCOME_MSG=<ID of welcome message>
+DISCORD_SEASONAL_EVENTS_CATEGORY=<ID of Seasonal Events Category>
+DISCORD_ADVENT_CALENDAR_CHANNEL_2021=<ID of advent calendar chanel for 2021>
 
 # JSON Files
 DISCORD_CALMDOWN_FILE=<File name for calmdowns JSON file>
@@ -25,6 +27,8 @@ DISCORD_ROLES_FILE=<File name for roles JSON file>
 DISCORD_TEXT_COMMANDS_FILE=<File name for text commands JSON file>
 DISCORD_TIMER_FILE=<File name for running timers JSON file>
 DISCORD_APPOINTMENTS_FILE=<File name for running appointments JSON file>
+DISCORD_ADVENT_CALENDAR_FILE=<File name for advent calendar JSON file>
 
 # Misc
 DISCORD_DATE_TIME_FORMAT=<Date and time format used for commands like %d.%m.%Y %H:%M>
+DISCORD_ADVENT_CALENDAR_START=<Start date and time for advent calendar. Something like "01.12.2021 00:00">
diff --git a/cogs/christmas.py b/cogs/christmas.py
new file mode 100644
index 0000000000000000000000000000000000000000..9c530f52b33cb2263233e1b1b6e85f4d1aa64d3d
--- /dev/null
+++ b/cogs/christmas.py
@@ -0,0 +1,169 @@
+import asyncio
+import json
+import os
+from datetime import datetime, timedelta
+
+from disnake import ApplicationCommandInteraction, Member
+from disnake.ext import commands, tasks
+from dotenv import load_dotenv
+
+import utils
+
+load_dotenv()
+
+
+def create_advent_calendar():
+    advent_calendar = []
+    startdate = utils.date_from_string(os.getenv("DISCORD_ADVENT_CALENDAR_START")).astimezone()
+
+    for i in range(0, 24):
+        advent_calendar.append({
+            "number": i + 1,
+            "date": utils.date_to_string(startdate + timedelta(days=i)),
+            "assigned": False,
+            "opened": False
+        })
+
+    return advent_calendar
+
+
+class Christmas(commands.Cog):
+    def __init__(self, bot):
+        self.bot = bot
+        self.seasonal_events_category = int(os.getenv("DISCORD_SEASONAL_EVENTS_CATEGORY"))
+        self.advent_calendar_channel = int(os.getenv("DISCORD_ADVENT_CALENDAR_CHANNEL_2021"))
+        self.file_name = os.getenv("DISCORD_ADVENT_CALENDAR_FILE")
+        self.advent_calendar = self.load()
+        self.advent_calendar_loop.start()
+
+    def load(self):
+        with open(self.file_name, mode='r') as f:
+            advent_calendar = json.load(f)
+
+        if len(advent_calendar) == 0:
+            advent_calendar = create_advent_calendar()
+
+        return advent_calendar
+
+    def save(self):
+        with open(self.file_name, mode='w') as f:
+            json.dump(self.advent_calendar, f)
+
+    @commands.slash_command(name="advent", guild_ids=[int(os.getenv('DISCORD_GUILD'))])
+    async def cmd_advent(self, interaction: ApplicationCommandInteraction):
+        pass
+
+    @cmd_advent.sub_command(name="list", description="Erhalte die Liste aller Türchen mit Zuordnung und Thema")
+    @commands.check(utils.is_mod)
+    async def cmd_advent_list(self, interaction: ApplicationCommandInteraction):
+        message = f"__**Adventskalender 2021**__\n\n"
+
+        for day in self.advent_calendar:
+            message += f"{day['number']}. "
+            if day["assigned"]:
+                message += f"<@!{day['assignee']}>: \"{day['name']}\""
+            else:
+                message += f"noch nicht zugewiesen"
+
+            message += "\n"
+
+        await interaction.response.send_message(message, ephemeral=True)
+
+    @cmd_advent.sub_command(name="assign", description="Einer Person ein Türchen zuweisen",
+                            guild_ids=[int(os.getenv('DISCORD_GUILD'))])
+    @commands.check(utils.is_mod)
+    async def cmd_advent_assign(self, interaction: ApplicationCommandInteraction, day: int, member: Member, name: str):
+        if self.advent_calendar[day - 1]["assigned"]:
+            await interaction.response.send_message("Das gewählte Türchen ist bereits vergeben. \n"
+                                                    "Wenn du das Türchen an jemand anderen vergeben möchtest, oder das "
+                                                    "Thema ändern möchtest, verwende `/advent reassign`.",
+                                                    ephemeral=True)
+        else:
+            await interaction.response.defer(ephemeral=True)
+            await self.assign_day(day, member, name)
+            await interaction.edit_original_message(content="Das gewählte Türchen wurde vergeben.")
+
+    @cmd_advent.sub_command(name="reassign", description="Ein Türchen neu zuweisen",
+                            guild_ids=[int(os.getenv('DISCORD_GUILD'))])
+    @commands.check(utils.is_mod)
+    async def cmd_advent_reassign(self, interaction: ApplicationCommandInteraction, day: int, member: Member,
+                                  name: str):
+        if not self.advent_calendar[day - 1]["assigned"]:
+            await interaction.response.send_message("Das gewählte Türchen ist noch nicht vergeben. \n"
+                                                    "Bitte verwende `/advent assign` um das Türchen an "
+                                                    "jemanden zu vergeben.", ephemeral=True)
+        else:
+            await interaction.response.defer(ephemeral=True)
+            channel = await self.bot.fetch_channel(self.advent_calendar[day - 1]["channel"])
+            old_member = await self.bot.fetch_user(self.advent_calendar[day - 1]["assignee"])
+            await channel.set_permissions(old_member, overwrite=None)
+            await self.assign_day(day, member, name)
+            await interaction.edit_original_message(content="Das gewählte Türchen wurde neu vergeben.")
+
+    @cmd_advent.sub_command(name="remaining", description="Noch nicht zugewiesene Türchen ausgeben lassen.",
+                            guild_ids=[int(os.getenv('DISCORD_GUILD'))])
+    @commands.check(utils.is_mod)
+    async def cmd_advent_remaining(self, interaction: ApplicationCommandInteraction):
+        message = f"Noch verfügbare Türchen: "
+
+        for day in self.advent_calendar:
+            if not day["assigned"]:
+                message += f"{day['number']}, "
+
+        await interaction.response.send_message(message[:-2], ephemeral=True)
+
+    async def assign_day(self, day: int, member: Member, name: str):
+        category = await self.bot.fetch_channel(self.seasonal_events_category)
+        channel = await category.create_text_channel(f"{day}-{name}")
+        await channel.set_permissions(member.roles[0], view_channel=False)
+        await channel.set_permissions(member, view_channel=True)
+        await channel.send(f"Vielen Dank {member.mention}, dass du für das {day}. Türchen etwas zum Thema {name} "
+                           f"vorbereiten möchtest. Dieser Channel ist für dich gedacht. Du kannst hier deinen Beitrag "
+                           f"vorbereiten.\n\n"
+                           f"Am {day}.12.2021 um 00:00 werden alle Nachrichten von dir, die in diesem Channel bis "
+                           f"dahin geschrieben wurden, in einen eigenen Thread für diesen Tag übernommen.\n\n"
+                           f"Beachte bitte, dass Sticker nicht verwendet werden können. Das gleiche gilt für Emojis, "
+                           f"die nicht von diesem Server sind.\n\n"
+                           f"Das Mod-Team wünscht dir viel Spaß bei der Vorbereitung.")
+        self.advent_calendar[day - 1]["channel"] = channel.id
+        self.advent_calendar[day - 1]["assigned"] = True
+        self.advent_calendar[day - 1]["assignee"] = member.id
+        self.advent_calendar[day - 1]["name"] = name
+        self.save()
+
+    async def open(self, day):
+        source_channel = await self.bot.fetch_channel(day["channel"])
+        assignee = await self.bot.fetch_user(day["assignee"])
+        target_channel = await self.bot.fetch_channel(self.advent_calendar_channel)
+        thread_name = f"{day['number']}. {day['name']}"
+
+        message = await target_channel.send(f"{day['number']}. \"{day['name']}\", ein Beitrag von {assignee.mention}:")
+        thread = await message.create_thread(name=thread_name, auto_archive_duration=1440)
+        day["thread"] = thread.id
+        day["opened"] = True
+
+        async for msg in source_channel.history(limit=None, oldest_first=True):
+            if msg.author == assignee:
+                if len(msg.stickers) > 0:
+                    continue
+                files = await utils.files_from_attachments(msg.attachments)
+                await thread.send(content=msg.content, embeds=msg.embeds, files=files)
+
+        await thread.send("--------------------------\nBeginn der Diskussion\n--------------------------")
+
+        self.save()
+
+    @tasks.loop(seconds=10)
+    async def advent_calendar_loop(self):
+        now = datetime.now()
+        for day in self.advent_calendar:
+            if not day["opened"]:
+                due_date = utils.date_from_string(day["date"])
+                if due_date <= now:
+                    await self.open(day)
+                else:
+                    return
+
+    @advent_calendar_loop.before_loop
+    async def before_advent_calendar_loop(self):
+        await asyncio.sleep(10 - datetime.now().second % 10)
diff --git a/root.py b/root.py
index 76127b1b95704f6f3fcbb9d14b7b9b0f13297ebb..384ff54544844fe78888f02a8a5c4147b73bb04a 100644
--- a/root.py
+++ b/root.py
@@ -4,7 +4,7 @@ import disnake
 from disnake.ext import commands
 from dotenv import load_dotenv
 
-from cogs import appointments, calmdown, help, links, polls, roles, support, text_commands, timer, welcome
+from cogs import appointments, calmdown, help, links, polls, roles, support, text_commands, timer, welcome, christmas
 
 # .env file is necessary in the same directory, that contains several strings.
 load_dotenv()
@@ -38,6 +38,7 @@ class Root(commands.Bot):
         self.add_cog(text_commands.TextCommands(self))
         self.add_cog(timer.Timer(self))
         self.add_cog(welcome.Welcome(self))
+        self.add_cog(christmas.Christmas(self))
 
 
 bot = Root()
diff --git a/utils.py b/utils.py
index 28283e453d7bc62a42dab4fe6dfc400fde295a1b..01ee764a104abda7fafc5b35f98057d3aff5b825 100644
--- a/utils.py
+++ b/utils.py
@@ -1,7 +1,12 @@
 import os
 import re
+from datetime import datetime
 
 import disnake
+from dotenv import load_dotenv
+
+load_dotenv()
+DATE_TIME_FMT = os.getenv("DISCORD_DATE_TIME_FORMAT")
 
 
 async def send_dm(user, message, embed=None):
@@ -41,3 +46,19 @@ def to_minutes(time):
         return h * 60
 
     return int(time)
+
+
+def date_to_string(date: datetime):
+    return date.strftime(DATE_TIME_FMT)
+
+
+def date_from_string(date: str):
+    return datetime.strptime(date, DATE_TIME_FMT)
+
+
+async def files_from_attachments(attachments):
+    files = []
+    for attachment in attachments:
+        files.append(await attachment.to_file(spoiler=attachment.is_spoiler()))
+
+    return files