diff --git a/extensions/appointments.py b/extensions/appointments.py
index 96b5643b0394320c886a8fe12ed5509fb72bc272..cbd4d850c61945587cbfd57ec6b523cb2f97a088 100644
--- a/extensions/appointments.py
+++ b/extensions/appointments.py
@@ -5,7 +5,7 @@ from datetime import datetime, timedelta
 from discord import app_commands, errors, Interaction
 from discord.ext import tasks, commands
 
-from models import Appointment
+from models import Appointment, Attendee
 from views.appointment_view import AppointmentView
 
 
@@ -84,6 +84,7 @@ class Appointments(commands.GroupCog, name="appointments", description="Handle A
         appointment = Appointment.create(channel=channel.id, message=0, date_time=date_time, reminder=reminder,
                                          title=title, description=description, author=author_id, recurring=recurring,
                                          reminder_sent=reminder == 0, uuid=uuid.uuid4())
+        Attendee.create(appointment=appointment, member_id=author_id)
 
         await interaction.response.send_message(embed=appointment.get_embed(0), view=AppointmentView())
         message = await interaction.original_response()
diff --git a/extensions/news.py b/extensions/news.py
index ad43ea280c1da902416cef79cb646bf2dd56ed9a..5b8fb39643dbf5275ec266659c7dc0cf6f1ecadf 100644
--- a/extensions/news.py
+++ b/extensions/news.py
@@ -1,8 +1,21 @@
+from typing import Optional
+from xml.etree.ElementTree import Element
+
 from aiohttp import ClientSession
 from bs4 import BeautifulSoup
+from discord import errors, Embed
 from discord.ext import commands, tasks
+from defusedxml.ElementTree import fromstring
+
+from models import NewsFeed, NewsArticle, Settings
+
+
+def find_text(parent: Element, tag_name: str):
+    element = parent.find(tag_name)
+    if element is not None:
+        return element.text
 
-import models
+    return None
 
 
 class News(commands.Cog):
@@ -12,39 +25,50 @@ class News(commands.Cog):
 
     @tasks.loop(hours=1)
     async def news_loop(self):
-        # ToDo: Add better handling for guild
-        guild = models.Settings.select()[0].guild_id
-        url = self.bot.get_settings(guild).news_url
-        channel_id = self.bot.get_settings(guild).news_channel_id
+        for feed in NewsFeed.select():
+            match feed.type:
+                case "RSS":
+                    await self.parse_rss(feed)
 
+    async def parse_rss(self, feed: NewsFeed):
         async with ClientSession() as session:
-            async with session.get(url) as r:
-                if r.status == 200:
-                    content = await r.read()
-                    soup = BeautifulSoup(content, "html.parser")
-                    channel = await self.bot.fetch_channel(channel_id)
-
-                    for news in soup.find("ul", attrs={"class": "fu-link-list"}).find_all("li"):
-                        date = news.span.text
-                        title = str(news.a.text)
-                        link = news.a['href']
-
-                        if link[0] == "/":
-                            link = f"https://www.fernuni-hagen.de" + link
-
-                        if news := models.News.get_or_none(link=link):
-                            if news.date != date:
-                                await self.announce_news(channel, date, title, link)
-                                news.update(date=date).where(models.News.link == link).execute()
-                        else:
-                            await self.announce_news(channel, date, title, link)
-                            models.News.create(link=link, date=date)
-
-    async def announce_news(self, channel, date, title, link):
-        guild = models.Settings.select()[0].guild_id
-        news_role = self.bot.get_settings(guild).news_role_id
-        await channel.send(
-            f":loudspeaker: <@&{news_role}> Neues aus der Fakultät vom {date} :loudspeaker: \n{title} \n{link}")
+            async with session.get(feed.url) as response:
+                if response.status == 200:
+                    content = str(await response.read(), encoding='utf-8')
+                    root = fromstring(content)
+                    for article in root.iter('item'):
+                        if news_article := await self.parse_article_rss(article, feed):
+                            await self.announce_news(news_article)
+
+    @staticmethod
+    async def parse_article_rss(article: Element, feed: NewsFeed) -> Optional[NewsArticle]:
+        title = find_text(article, "title")
+        description = find_text(article, "description")
+        link = find_text(article, "link")
+        pubDate = find_text(article, "pubDate")
+
+        if news_article := NewsArticle.get_or_none(link=link):
+            if news_article.pubDate != pubDate:
+                news_article.update(title=title, description=description, pubDate=pubDate).where(
+                    NewsArticle.link == link).execute()
+                return NewsArticle.get_or_none(link=link)
+            else:
+                return None
+        else:
+            return NewsArticle.create(news_feed=feed, title=title, description=description, link=link, pubDate=pubDate)
+
+    async def announce_news(self, news_article: NewsArticle):
+        settings = news_article.news_feed.settings
+        news_role = settings.news_role_id
+        try:
+            channel = await self.bot.fetch_channel(settings.news_channel_id)
+            embed = Embed(title=news_article.title, url=news_article.link)
+            if news_article.description:
+                embed.description = news_article.description
+            await channel.send(
+                f":loudspeaker: <@&{news_role}> Neues aus der Fakultät vom {news_article.pubDate} :loudspeaker:", embed=embed)
+        except errors.NotFound:
+            pass
 
 
 async def setup(bot: commands.Bot) -> None:
diff --git a/fernuni_bot.py b/fernuni_bot.py
index 3875c480360eef7dfedf7b2f208d672b33253c37..cbcebe0c9a01c2c481c1a767f63b42ef0b2ad315 100644
--- a/fernuni_bot.py
+++ b/fernuni_bot.py
@@ -1,6 +1,5 @@
 import logging
 import os
-from logging import DEBUG
 from typing import List
 
 import discord
@@ -21,7 +20,8 @@ OWNER = int(os.getenv('DISCORD_OWNER'))
 PIN_EMOJI = "📌"
 
 intents = Intents.all()
-extensions = ["welcome", "xkcd", "mod_mail", "module_information"]
+extensions = ["welcome", "xkcd", "mod_mail", "module_information", "links", "news", "appointments"]
+# ["learninggroups", "polls", "text_commends", "timer", "voice"]
 _log = logging.getLogger('discord.boty')
 
 
diff --git a/json_import.py b/json_import.py
index 7f02c5cd3bb7709aac874fb7f8ce352991c384d5..332e33c067919e2524468aed341f473bebc75dc9 100644
--- a/json_import.py
+++ b/json_import.py
@@ -1,6 +1,14 @@
 import json
+import os
+import uuid
+import datetime
+
+import discord
+from dotenv import load_dotenv
 
 import models
+from models import Appointment
+from views.appointment_view import AppointmentView
 
 
 def import_links(json_file: str) -> None:
@@ -43,11 +51,44 @@ def import_courses(json_file: str) -> None:
                                     role_id=int(course["role"]))
 
 
-if __name__ == "__main__":
+async def import_appointments(json_file: str) -> None:
+    file = open(json_file, mode="r")
+    appointments = json.load(file)
+
+    for channel_id, messages in appointments.items():
+        for message_id, appointment in messages.items():
+            date_time = datetime.datetime.strptime(appointment["date_time"], "%d.%m.%Y %H:%M")
+            reminder_sent = True if appointment["reminder"] == 0 and appointment.get(
+                "original_reminder") is not None else False
+
+            app = models.Appointment.create(channel=int(channel_id), message=int(message_id), date_time=date_time, appointment=appointment["reminder"], description="", author=appointment["author_id"],
+                                            recurring=appointment.get("recurring", 0), reminder_sent=reminder_sent,
+                                            uuid=uuid.uuid4())
+            channel = await client.fetch_channel(app.channel_id)
+            message = await channel.fetch_message(app.message)
+            for reaction in message.reactions:
+                    if reaction.emoji == "👍":
+                        async for user in reaction.users():
+                            if not user.bot:
+                                models.Attendee.create(appointment=app, member_id=user.id)
+            new_msg = await channel.send(embed=appointment.get_embed(0), view=AppointmentView())
+            Appointment.update(message=new_msg.id).where(Appointment.id == app.id).execute()
+
+
+load_dotenv()
+client = discord.Client(intents=discord.Intents.all())
+
+
+@client.event()
+async def on_ready():
     """
-    Make sure to create a database backup before you import data from json files.
+        Make sure to create a database backup before you import data from json files.
     """
     # import_links("data/links.json")
     # import_news("data/news.json")
     # import_commands("data/text_commands.json")
     # import_courses("data/courses_of_studies.json")
+    await import_appointments("data/appointments.json")
+
+
+client.run(os.getenv("DISCORD_TOKEN"))
diff --git a/models.py b/models.py
index 5decbfd5a2bee6a664f303a3a83adcb4afb1abfb..c1b224a7095d03646f214295576803257e703250 100644
--- a/models.py
+++ b/models.py
@@ -53,9 +53,19 @@ class Link(BaseModel):
     category = ForeignKeyField(LinkCategory, backref='links')
 
 
-class News(BaseModel):
+class NewsFeed(BaseModel):
+    settings = ForeignKeyField(Settings)
+    url = CharField()
+    type = CharField()
+
+
+class NewsArticle(BaseModel):
+    news_feed = ForeignKeyField(NewsFeed)
+    title = CharField(null=True)
+    description = CharField(null=True)
     link = CharField()
-    date = CharField()
+    pubDate = CharField()
+
 
 
 class Poll(BaseModel):
@@ -254,5 +264,5 @@ class Contact(BaseModel):
 
 
 db.create_tables(
-    [Settings, LinkCategory, Link, News, Poll, PollChoice, PollParticipant, Command, CommandText, Appointment,
+    [Settings, LinkCategory, Link, NewsFeed, NewsArticle, Poll, PollChoice, PollParticipant, Command, CommandText, Appointment,
      Attendee, Course, Module, Event, Support, Exam, Download, Contact], safe=True)
diff --git a/requirements.txt b/requirements.txt
index 2def8e82c68aa0953abef7c521b6a3ea7dee73e8..956218bbc087125890c2bb471779c6d50935a2b4 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,19 +1,21 @@
 aiohttp==3.10.5
 beautifulsoup4==4.12.3
+defusedxml==0.7.1
 discord.py==2.4.0
 emoji==2.12.1
 peewee==3.17.6
 PyNaCl==1.5.0
 python-dotenv==1.0.1
 
+
 aiohappyeyeballs==2.4.0
 aiosignal==1.3.1
 attrs==24.2.0
-cffi==1.17.0
+cffi==1.17.1
 frozenlist==1.4.1
 idna==3.8
 multidict==6.0.5
 pycparser==2.22
 soupsieve==2.6
 typing_extensions==4.12.2
-yarl==1.9.4
+yarl==1.10.0