diff --git a/.env.template b/.env.template
index 3ecd2f42e570d18533e024c24d4c51d24b2e2079..549da084cf1c473fff95a46295a507ad975f5ea8 100644
--- a/.env.template
+++ b/.env.template
@@ -10,28 +10,23 @@ DISCORD_PROD=<True, if running in an productive environment, otherwise False>
 # IDs
 DISCORD_OWNER=<ID of Server owner>
 DISCORD_MOD_ROLE=<ID of Mod Role>
-DISCORD_MOD_CHANNEL=<ID of Mod only channel>
 DISCORD_CATEGORY_LERNGRUPPEN=<Channel category for learning group voice channels>
 DISCORD_WELCOME_CHANNEL=<ID of Welcome channel, where Welcome Message should be posted>
 DISCORD_WELCOME_MSG=<ID of Welcome message>
 DISCORD_VORSTELLUNGSCHANNEL=<ID of Channel used for introductions of new users>
 DISCORD_ROLLEN_CHANNEL=<ID of role assignment channel>
-DISCORD_DEGREE_PROGRAM_MSG=<ID of Message that can be used for assignement of degree program roles>
-DISCORD_COLOR_MSG=<ID of Message that can be used for assignment of color roles>
-DISCORD_SPECIAL_MSG=<ID of Message that can be used for assignment of special roles>
-DISCORD_STUDENTIN_ROLE=<ID of "Studentin" role>
-DISCORD_ADVENT_CALENDAR_CHANNEL=<ID of Advent calendar channel>
 DISCORD_SUPPORT_CHANNEL=<ID of support channel, where the Bot posts all DMs sent by users>
 DISCORD_GREETING_CHANNEL=<ID of greeting channel, where new users are welcomed>
-DISCORD_ADVENT_CALENDAR_MESSAGE=<ID of Advent calendar message>
 DISCORD_NEWS_CHANNEL=<ID of News Channel, where news from faculty are posted>
 DISCORD_POLL_SUGG_CHANNEL=<ID of Channel, where poll suggestions are posted>
 DISCORD_NEWS_ROLE=<ID of news role>
 DISCORD_CHANGE_LOG_CHANNEL=<ID of channel used by change log feature>
-DISCORD_LEARNINGGROUPS_OPEN=<ID of Channel category for open learning groups>
-DISCORD_LEARNINGGROUPS_CLOSE=<ID of Channel category for closed learning groups>
-DISCORD_LEARNINGGROUPS_REQUEST=<ID of Channel category for learning group requests>
-DISCORD_LEARNINGGROUPS_INFO=<ID of Channel category for open learning groups>
+DISCORD_LEARNINGGROUPS_OPEN=<ID of the channel category for open learning groups>
+DISCORD_LEARNINGGROUPS_CLOSE=<ID of the channel category for closed learning groups>
+DISCORD_LEARNINGGROUPS_PRIVATE=<ID of the channel category for private learning groups>
+DISCORD_LEARNINGGROUPS_ARCHIVE=<ID of the channel category for archived learning groups>
+DISCORD_LEARNINGGROUPS_REQUEST=<ID of the channel category for learning group requests made via the bot>
+DISCORD_LEARNINGGROUPS_INFO=<ID of the channel category for posting or updating information about the learning group>
 DISCORD_IDEE_CHANNEL=<ID of Channel, where bot ideas can be submitted>
 DISCORD_IDEE_EMOJI=<ID of Idee Emoji, used for reactions>
 DISCORD_CALMDOWN_ROLE=<ID of "Calmdown" role>
@@ -40,22 +35,25 @@ DISCORD_ELM_STREET_CHANNEL=<ID of elm street channel>
 DISCORD_HALLOWEEN_CATEGORY=<ID of Halloween category>
 DISCORD_SEASONAL_EVENTS_CATEGORY=<ID of Seasonal Events Category>
 DISCORD_ADVENT_CALENDAR_CHANNEL_2021=<ID of advent calendar chanel for 2021>
+DISCORD_JOBOFFERS_CHANNEL=<ID of "Stellenangebote" Channel>
 
 # JSON Files
 DISCORD_ROLES_FILE=<File name for roles JSON file>
 DISCORD_HELP_FILE=<File name for help JSON file>
-DISCORD_TOPS_FILE=<File name for TOPS JSON file>
 DISCORD_APPOINTMENTS_FILE=<File name for appointments JSON file>
 DISCORD_TEXT_COMMANDS_FILE=<File name for text commands JSON file>
-DISCORD_LEARNINGGROUPS_FILE=<File name for learning groups JSON file>
-DISCORD_LEARNINGGROUPS_COURSE_FILE=<File name for leaarning groups courses JSON file>
+DISCORD_LEARNINGGROUPS_FILE=<Name of the JSON file for administering learning groups>
+DISCORD_LEARNINGGROUPS_COURSE_FILE=<Name of the JSON file that contains the course names used in the learning group information>
 DISCORD_CALMDOWN_FILE=<File name for calmdowns JSON file>
 DISCORD_MODULE_COURSE_FILE=<File name for module course JSON file>
 DISCORD_MODULE_DATA_FILE=<File name for module data JSON file>
 DISCORD_TIMER_FILE=<File name for running timers JSON file>
 DISCORD_ADVENT_CALENDAR_FILE=<File name for advent calendar JSON file>
+DISCORD_JOBOFFERS_FILE=<File name for job offers JSON file>
 
 # Misc
 DISCORD_DATE_TIME_FORMAT=<Date and time format used for commands like %d.%m.%Y %H:%M>
-DISCORD_IDEE_REACT_QTY=<Amount of reactions to a submitted idea, neccessary to create a github issue (amount is including botys own reaction)>
+DISCORD_IDEE_REACT_QTY=<Amount of reactions to a submitted idea, neccessary to create a github issue (amount is including Boty's own reaction)>
 DISCORD_ADVENT_CALENDAR_START=<Start date and time for advent calendar. Something like "01.12.2021 00:00">
+DISCORD_JOBOFFERS_URL=<url from which job offers are fetched, atm "https://www.fernuni-hagen.de/uniintern/arbeitsthemen/karriere/stellen/include/hk.shtml">
+DISCORD_JOBOFFERS_STD_FAK=<faculty for which job offers should be posted, one of [mi|rewi|wiwi|ksw|psy|other|all]>
diff --git a/.idea/fernuni-bot.iml b/.idea/fernuni-bot.iml
index 7ad0d735c6a577ba054a8af3bfe23c05b1453573..6b3214ed4bb27c60df903757034ff0cdaa7b1d3e 100644
--- a/.idea/fernuni-bot.iml
+++ b/.idea/fernuni-bot.iml
@@ -4,7 +4,7 @@
     <content url="file://$MODULE_DIR$">
       <excludeFolder url="file://$MODULE_DIR$/venv" />
     </content>
-    <orderEntry type="jdk" jdkName="Python 3.9 (fernuni-bot)" jdkType="Python SDK" />
+    <orderEntry type="jdk" jdkName="Python 3.10 (fernuni-bot)" jdkType="Python SDK" />
     <orderEntry type="sourceFolder" forTests="false" />
   </component>
 </module>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 266752ff953bd95855d279ee84b13f71da4ca44a..0fb7607056aaf6fa8258d09a35a49cac44d4c344 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,5 +3,5 @@
   <component name="JavaScriptSettings">
     <option name="languageLevel" value="ES6" />
   </component>
-  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (fernuni-bot)" project-jdk-type="Python SDK" />
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (fernuni-bot)" project-jdk-type="Python SDK" />
 </project>
\ No newline at end of file
diff --git a/README.md b/README.md
index 14e9a9bee25b7a970044c1d57d4da84601728419..05babe4ff6a7d27a525388b277615891f06137ab 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@ Zu dem Zeitpunkt kann Boty:
 
 * [Lerngruppenverwaltung](https://github.com/FU-Hagen-Discord/fernuni-bot/tree/master/cogs/learninggroups.py)
   * Anfragen/ Erstellen/ Umbenennen/ Löschen
-  * Ownership -> Toggle: 🛑vollzählig/ 🌲offen für neue Mitglieder
+  * Organisatorenrolle -> Lerngruppenstatus als öffentlich sichtbar und 🌲offen für neue Mitglieder oder 🛑vollzählig, oder als unsichtbare 🚪private Gruppe festlegen.
 
 * [Kalenderfunktion](https://github.com/FU-Hagen-Discord/fernuni-bot/tree/master/cogs/appointments.py)
 
diff --git a/cogs/components/module_information/scraper.py b/cogs/components/module_information/scraper.py
index 2a795a2db1f9132831535788ad201f1aee8e12db..0665e5374848441ec3562b1ec861ab1fb0028c65 100644
--- a/cogs/components/module_information/scraper.py
+++ b/cogs/components/module_information/scraper.py
@@ -124,7 +124,7 @@ class Scraper:
     def parse_support(self, soup):
         try:
             support_source = soup.find('h2', text=re.compile(
-                r'Mentorielle Betreuung an den Campusstandorten')).findNext('div').findAll('li')
+                r'Mentorielle Betreuung an den Campusstandorten')).findNext('ul').findAll('li')
         except:
             return None
 
diff --git a/cogs/job_offers.py b/cogs/job_offers.py
new file mode 100644
index 0000000000000000000000000000000000000000..d477aedbf7cfefb9f44c85cb2191d66d80f29a25
--- /dev/null
+++ b/cogs/job_offers.py
@@ -0,0 +1,196 @@
+import json
+import os
+from copy import deepcopy
+
+import aiohttp
+from bs4 import BeautifulSoup
+import disnake
+from disnake import ApplicationCommandInteraction, MessageInteraction
+from disnake.ext import commands, tasks
+from disnake.ui import View, Button
+
+from cogs.help import help
+from views import joboffers_view
+
+"""
+  Environment Variablen:
+  DISCORD_JOBOFFERS_FILE - json file mit allen aktuellen 
+  DISCORD_JOBOFFERS_CHANNEL - Channel-ID für Stellenangebote
+  DISCORD_JOBOFFERS_URL - URL von der die Stellenangebote geholt werde
+  DISCORD_JOBOFFERS_STD_FAK  - Fakultät deren Stellenangebote standardmäßig gepostet werden
+  
+  Struktur der json:
+  {fak:{id:{title:..., info:..., link:..., deadline:...}}
+  mit fak = [mi|rewi|wiwi|ksw|psy|other]
+"""
+
+JOBS_URL = os.getenv("DISCORD_JOBOFFERS_URL")
+STD_FAK = os.getenv("DISCORD_JOBOFFERS_STD_FAK")
+
+class Joboffers(commands.Cog):
+    def __init__(self, bot):
+        self.bot = bot
+        self.joboffers = {}
+        self.joboffers_channel_id = int(os.getenv("DISCORD_JOBOFFERS_CHANNEL"))
+        self.joboffers_file = os.getenv("DISCORD_JOBOFFERS_FILE")
+        self.load_joboffers()
+        self.update_loop.start()
+
+    @tasks.loop(hours=24)
+    async def update_loop(self):
+        await self.fetch_joboffers()
+
+    @update_loop.before_loop
+    async def before_update_loop(self):
+        await self.bot.wait_until_ready()
+
+    def save_joboffers(self):
+        with open(self.joboffers_file, mode='w') as joboffers_file:
+            json.dump(self.joboffers, joboffers_file)
+
+    def load_joboffers(self):
+        try:
+            with open(self.joboffers_file, mode='r') as joboffers_file:
+                self.joboffers = json.load(joboffers_file)
+        except FileNotFoundError:
+            self.joboffers = {}
+
+    @help(
+        syntax="/jobs <fak?>",
+        parameters={
+            "fak": "Fakultät für die die studentische Hilfskraft Jobs ausgegeben werden sollen "
+                   "(mi, rewi, wiwi, ksw, psy)"
+        },
+        brief="Ruft Jobangebote für Studiernde der Fernuni Hagen auf."
+    )
+    @commands.slash_command(name="jobs", aliases=["offers","stellen","joboffers"],
+                            description="Liste Jobangebote der Uni auf")
+    async def cmd_jobs(self, interaction: ApplicationCommandInteraction,
+                       chosen_faculty: str = commands.Param(default=STD_FAK,
+                                                            name='faculty',
+                                                            choices=['mi','rewi','wiwi','ksw','psy','other','all'])):
+        await self.fetch_joboffers()
+
+        fak_text = "aller Fakultäten" if chosen_faculty == 'all' else f"der Fakultät {chosen_faculty}"
+        description = f"Ich habe folgende Stellenangebote {fak_text} gefunden:"
+
+        pages = []
+        page = []
+        for fak, fak_offers in self.joboffers.items():
+            if chosen_faculty != 'all' and fak != chosen_faculty:
+                continue
+
+            for offer_id, offer_data in fak_offers.items():
+                descr = f"{offer_data['info']}\nDeadline: {offer_data['deadline']}\n{offer_data['link']}"
+                field = {'name': offer_data['title'], 'value': descr, 'inline': False}
+                if len(page) < 5:
+                    page.append(field)
+                else:
+                    pages.append(deepcopy(page))
+                    page = []
+        if len(page) > 0:
+            pages.append(deepcopy(page))
+
+        page_nr = 1
+        embed = self.get_embed(description, pages[page_nr-1], page_nr, len(pages))
+        view = joboffers_view.JobOffersView(self.on_page_skip, pages, page_nr, description)
+
+        await interaction.response.send_message(embed=embed, view=view, ephemeral=True)
+
+    def get_embed(self, description, page_content, page_nr, all_pages_nr):
+        embed = disnake.Embed(title="Stellenangebote der Uni",
+                              description=f"Ich habe folgende Stellenangebote {description} gefunden:")
+        for field in page_content:
+            embed.add_field(**field)
+        embed.set_footer(text=f"Seite {page_nr}/{all_pages_nr}")
+        return embed
+
+    async def on_page_skip(self, button: Button, interaction: MessageInteraction, pages, page_nr, embed_description):
+        if button.custom_id == "jobs:next":
+            page_nr += 1
+        if button.custom_id == "jobs:prev":
+            page_nr -= 1
+        embed = self.get_embed(embed_description, pages[page_nr-1], page_nr, len(pages))
+        view = joboffers_view.JobOffersView(self.on_page_skip, pages, page_nr, embed_description)
+        await interaction.response.edit_message(embed=embed, view=view)
+
+    async def post_new_jobs(self, jobs):
+        fak_text = "aller Fakultäten" if STD_FAK == 'all' else f"der Fakultät {STD_FAK}"
+        joboffers_channel = await self.bot.fetch_channel(self.joboffers_channel_id)
+
+        embed = disnake.Embed(title="Neue Stellenangebote der Uni",
+                              description=f"Ich habe folgende neue Stellenangebote {fak_text} gefunden:")
+        i = 0
+        for job in jobs:
+            i += 1
+            descr = f"{job['info']}\nDeadline: {job['deadline']}\n{job['link']}"
+            embed.add_field(name=job['title'], value=descr, inline=False)
+            if i % 5 == 0:
+                await joboffers_channel.send(embed=embed)
+                embed = disnake.Embed(title="Neue Stellenangebote der Uni ... Fortsetzung")
+        if i % 5 != 0:
+            await joboffers_channel.send(embed=embed)
+
+    async def fetch_joboffers(self):
+        sess = aiohttp.ClientSession()
+        req = await sess.get(JOBS_URL)
+        text = await req.read()
+        await sess.close()
+
+        soup = BeautifulSoup(text, "html.parser")
+        list = soup.findAll("li")
+
+        # alte Liste sichern zum Abgleich
+        old_joboffers = deepcopy(self.joboffers)
+        # Liste leeren um outdated joboffers auszusortieren
+        self.joboffers = {}
+
+        for job in list:
+            detail_string = job.text.strip()
+            if "Studentische Hilfskraft" in detail_string:
+                id = detail_string[detail_string.index('(')+12:detail_string.index(')')]
+                title = detail_string[:detail_string.index(')')+1]
+                info = detail_string[detail_string.index(')')+1:detail_string.index('[')]
+                deadline = detail_string[detail_string.index('[')+1:detail_string.index(']')]
+                link = job.find('a')['href']
+
+                # Sonderzeichen aufräumen
+                to_replace = ["ä", "ü", "²", "„", "“"]
+                replace_with = ["ä", "ü", "²", "\"", "\""]
+                for i in range(len(to_replace)):
+                    info = info.replace(to_replace[i], replace_with[i])
+
+                faks = ["other", "wiwi", "mi", "ksw", "psy", "rewi"]
+
+                fak_id = int(id[0]) # Kennziffer 1=wiwi, 2=mi, 3=ksw, 4=psy, 5=rewi, alle anderen=other
+                if fak_id in range(1,6):
+                    fak = faks[fak_id]
+                else:
+                    fak = faks[0]
+
+                if not self.joboffers.get(fak):
+                    self.joboffers[fak] = {}
+                self.joboffers[fak][id] = {'title': title, 'info': info, 'deadline': deadline, 'link': link}
+        self.save_joboffers()
+        await self.check_for_new_jobs(old_joboffers)
+
+    async def check_for_new_jobs(self, old_joboffers):
+        new_jobs = []
+
+        for fak, fak_offers in self.joboffers.items():
+            if STD_FAK != 'all' and fak != STD_FAK:
+                continue
+
+            if fak_old := old_joboffers.get(fak):
+                for offer_id, offer_data in fak_offers.items():
+                    if old_offer := fak_old.get(offer_id):
+                        if offer_data != old_offer:
+                            new_jobs.append(offer_data)
+                    else:
+                        new_jobs.append(offer_data)
+            else:
+                for offer_id, offer_data in self.joboffers.get(fak).items():
+                    new_jobs.append(offer_data)
+
+        if new_jobs:
+            await self.post_new_jobs(new_jobs)
diff --git a/cogs/learninggroups.py b/cogs/learninggroups.py
index 675db08148ed4c2b1a404a1d1b5e17b408dabdcb..e28e386db9d72113e50f0d0636cf53e2a07fd3b8 100644
--- a/cogs/learninggroups.py
+++ b/cogs/learninggroups.py
@@ -15,15 +15,16 @@ import utils
 from cogs.help import help, handle_error, help_category
 
 """
-  Environment Variablen:
-  DISCORD_LEARNINGGROUPS_OPEN - ID der Kategorie für offene Lerngruppen
-  DISCORD_LEARNINGGROUPS_CLOSE - ID der Kategorie für private Lerngruppen
-  DISCORD_LEARNINGGROUPS_ARCHIVE - ID der Kategorie für archivierte Lerngruppen
-  DISCORD_LEARNINGGROUPS_REQUEST - ID des Channels in welchem Requests vom Bot eingestellt werden
-  DISCORD_LEARNINGGROUPS_INFO - ID des Channels in welchem die Lerngruppen-Informationen gepostet/aktualisert werden
+  Umgebungsvariablen:
+  DISCORD_LEARNINGGROUPS_OPEN - Kategorie-ID der offenen Lerngruppen
+  DISCORD_LEARNINGGROUPS_CLOSE - Kategorie-ID der geschlossenen Lerngruppen
+  DISCORD_LEARNINGGROUPS_PRIVATE - Kategorie-ID der privaten Lerngruppen
+  DISCORD_LEARNINGGROUPS_ARCHIVE - Kategorie-ID der archivierten Lerngruppen
+  DISCORD_LEARNINGGROUPS_REQUEST - ID des Kanals, in dem Anfragen, die über den Bot gestellt wurden, eingetragen werden
+  DISCORD_LEARNINGGROUPS_INFO - ID des Kanals, in dem die Lerngruppen-Informationen gepostet/aktualisert werden
   DISCORD_LEARNINGGROUPS_FILE - Name der Datei mit Verwaltungsdaten der Lerngruppen (minimaler Inhalt: {"requested": {},"groups": {}})
-  DISCORD_LEARNINGGROUPS_COURSE_FILE - Name der Datei welche die Kursnamen für die Lerngruppen-Informationen enthält (minimalter Inhalt: {})
-  DISCORD_MOD_ROLE - ID der Moderator Rolle von der erweiterte Lerngruppen-Actionen ausgeführt werden dürfen
+  DISCORD_LEARNINGGROUPS_COURSE_FILE - Name der Datei welche die Kursnamen für die Lerngruppen-Informationen enthält (minimaler Inhalt: {})
+  DISCORD_MOD_ROLE - ID der Moderations-Rolle, die erweiterte Lerngruppen-Aktionen ausführen darf
 """
 
 LG_OPEN_SYMBOL = f'🌲'
@@ -41,8 +42,8 @@ class GroupState(Enum):
 
 
 @help_category("learninggroups", "Lerngruppen",
-               "Mit dem Lerngruppen-Feature kannst du Lerngruppen-Kanäle beantragen und verwalten.",
-               "Hier kannst du Lerngruppen-Kanäle anlegen, beantragen und verwalten.")
+               "Mit dem Lerngruppen-Feature kannst du Lerngruppenkanäle beantragen und verwalten.",
+               "Hier kannst du Lerngruppenkanäle anlegen, beantragen und verwalten.")
 class LearningGroups(commands.Cog):
     def __init__(self, bot):
         self.bot = bot
@@ -68,9 +69,9 @@ class LearningGroups(commands.Cog):
         self.support_channel = os.getenv('DISCORD_SUPPORT_CHANNEL')
         self.mod_role = os.getenv("DISCORD_MOD_ROLE")
         self.guild_id = os.getenv("DISCORD_GUILD")
-        self.groups = {}  # owner and learninggroup-member ids
+        self.groups = {}  # organizer and learninggroup-member ids
         self.channels = {}  # complete channel configs
-        self.header = {}  # headlines for statusmessage
+        self.header = {}  # headlines for status message
         self.load_groups()
         self.load_header()
 
@@ -132,13 +133,13 @@ class LearningGroups(commands.Cog):
             return GroupState.PRIVATE
         return None
 
-    def is_request_owner(self, request, member):
-        return request["owner_id"] == member.id
+    def is_request_organizer(self, request, member):
+        return request["organizer_id"] == member.id
 
-    def is_group_owner(self, channel, member):
+    def is_group_organizer(self, channel, member):
         channel_config = self.groups["groups"].get(str(channel.id))
         if channel_config:
-            return channel_config["owner_id"] == member.id
+            return channel_config["organizer_id"] == member.id
         return False
 
     def is_mod(self, member):
@@ -177,7 +178,7 @@ class LearningGroups(commands.Cog):
         seconds = channel_config["last_rename"] + self.rename_ratelimit - now
         if seconds > 0:
             channel = await self.bot.fetch_channel(int(channel_config["channel_id"]))
-            await channel.send(f"Discord limitiert die Aufrufe für manche Funktionen, daher kannst du diese Aktion erst wieder in {seconds} Sekunden ausführen.")
+            await channel.send(f"Discord schränkt die Anzahl der Aufrufe für manche Funktionen ein, daher kannst du diese Aktion erst wieder in {seconds} Sekunden ausführen.")
         return seconds > 0
 
     async def category_of_channel(self, state: GroupState):
@@ -233,7 +234,7 @@ class LearningGroups(commands.Cog):
             if lg_channel['is_listed'] and lg_channel['state'] == GroupState.PRIVATE:
                 group_config = self.groups["groups"].get(lg_channel['channel_id'])
                 if group_config:
-                    user = await self.bot.fetch_user(group_config['owner_id'])
+                    user = await self.bot.fetch_user(group_config['organizer_id'])
                     if user:
                         course_msg += f" **@{user.name}#{user.discriminator}**"
                 course_msg +=  f"\n       **↳** `!lg join {groupchannel.id}`"
@@ -244,7 +245,7 @@ class LearningGroups(commands.Cog):
         if len(no_headers) > 0:
             support_channel = await self.bot.fetch_channel(int(self.support_channel))
             if support_channel:
-                await support_channel.send(f"Es fehlen noch Überschriften für folgende Kurse in der Lerngruppenübersicht: **{', '.join(no_headers)}**")
+                await support_channel.send(f"In der Lerngruppenübersicht fehlen noch Überschriften für die folgenden Kurse: **{', '.join(no_headers)}**")
         info_message_ids.append(message.id)
         self.groups["messageids"] = info_message_ids
         await self.save_groups()
@@ -257,8 +258,10 @@ class LearningGroups(commands.Cog):
         category = await self.bot.fetch_channel(self.categories[GroupState.ARCHIVED])
         await self.move_channel(channel, category)
         await channel.edit(name=f"archiv-${channel.name[1:]}")
-        await self.remove_group(channel)
         await self.update_permissions(channel)
+        await self.remove_group(channel)
+        await self.update_statusmessage()
+
 
     async def set_channel_state(self, channel, state: GroupState = None):
         channel_config = self.channels[str(channel.id)]
@@ -268,7 +271,7 @@ class LearningGroups(commands.Cog):
         if state is not None:
             old_state = channel_config["state"]
             if old_state == state:
-                return False  # prevent api requests when nothing changed
+                return False  # prevent api requests when nothing has changed
             channel_config["state"] = state
             await self.alter_channel(channel, channel_config)
             return True
@@ -280,7 +283,7 @@ class LearningGroups(commands.Cog):
         if channel_config["state"] in [GroupState.CLOSED, GroupState.PRIVATE]:
             was_listed = channel_config["is_listed"]
             if was_listed == is_listed:
-                return False  # prevent api requests when nothing changed
+                return False  # prevent api requests when nothing has changed
             channel_config["is_listed"] = is_listed
             await self.alter_channel(channel, channel_config)
             return True
@@ -322,16 +325,16 @@ class LearningGroups(commands.Cog):
         full_channel_name = self.full_channel_name(requested_channel_config)
         channel = await category.create_text_channel(full_channel_name)
         await self.move_channel(channel, category, False)
-        user = await self.bot.fetch_user(requested_channel_config["owner_id"])
+        user = await self.bot.fetch_user(requested_channel_config["organizer_id"])
 
         await channel.send(f":wave: <@!{user.id}>, hier ist deine neue Lerngruppe.\n"
                            "Es gibt offene und private Lerngruppen. Eine offene Lerngruppe ist für jeden sichtbar "
                            "und jeder kann darin schreiben. Eine private Lerngruppe ist unsichtbar und auf eine "
                            "Gruppe an Kommilitoninnen beschränkt."
                            "```"
-                           "Besitzerinfunktionen:\n"
+                           "Funktionen für Lerngruppenorganisatorinnen:\n"
                            "!lg addmember <@newmember>: Fügt ein Mitglied zur Lerngruppe hinzu.\n"                           
-                           "!lg owner <@newowner>: Ändert die Besitzerin der Lerngruppe auf @newowner.\n"
+                           "!lg organizer <@neworganizer>: Ändert die Organisatorin der Lerngruppe auf @neworganizer.\n"
                            "!lg open: Öffnet eine Lerngruppe.\n"
                            "!lg close: Schließt eine Lerngruppe.\n"
                            "!lg private: Stellt die Lerngruppe auf privat.\n"
@@ -341,17 +344,17 @@ class LearningGroups(commands.Cog):
                            "\nKommandos für alle:\n"
                            "!lg id: Zeigt die ID der Lerngruppe an mit der andere Kommilitoninnen beitreten können.\n"
                            "!lg members: Zeigt die Mitglieder der Lerngruppe an.\n"
-                           "!lg owner: Zeigt die Besitzerin der Lerngruppe.\n"
+                           "!lg organizer: Zeigt die Organisatorin der Lerngruppe an.\n"
                            "!lg leave: Du verlässt die Lerngruppe.\n"
-                           "!lg join: Anfrage stellen in die Lerngruppe aufgenommen zu werden.\n"
+                           "!lg join: Anfrage, um der Lerngruppe beizutreten.\n"
                            "\nMit dem nachfolgenden Kommando kann eine Kommilitonin darum "
-                           "bitten in die Lerngruppe aufgenommen zu werden wenn diese bereits privat ist.\n"
+                           "bitten in die Lerngruppe aufgenommen zu werden wenn die Gruppe privat ist.\n"
                            f"!lg join {channel.id}"
-                            "\n(manche Kommandos sind von Discord limitiert und können nur einmal alle 5 Minuten ausgeführt werden)"
+                            "\n(Manche Kommandos werden von Discord eingeschränkt und können nur einmal alle 5 Minuten ausgeführt werden.)"
                            "```"
                            )
         self.groups["groups"][str(channel.id)] = {
-            "owner_id": requested_channel_config["owner_id"],
+            "organizer_id": requested_channel_config["organizer_id"],
             "last_rename": int(time.time())
         }
 
@@ -417,11 +420,14 @@ class LearningGroups(commands.Cog):
             users[mid] = True
             user = await self.bot.fetch_user(mid)
             if user and send_message:
-                await utils.send_dm(user, f"Du wurdest in die Lerngruppe <#{channel.id}> aufgenommen. " 
-                                          "Viel Spass beim gemeinsamen Lernen!\n"
-                                          "Dieser Link führt dich direkt zum Lerngruppen-Channel. " 
-                                          "Diese Nachricht kannst du bei Bedarf in unserer Unterhaltung " 
-                                          "über Rechtsklick anpinnen.")
+                try:
+                    await utils.send_dm(user, f"Du wurdest in die Lerngruppe <#{channel.id}> aufgenommen. " 
+                                              "Viel Spass beim gemeinsamen Lernen!\n"
+                                              "Dieser Link führt dich direkt zum Lerngruppenkanal. " 
+                                              "Diese Nachricht kannst du in unserer Unterhaltung mit Rechtsklick anpinnen, " 
+                                              "wenn du möchtest.")
+                except:
+                    pass
 
         group_config["users"] = users
 
@@ -440,7 +446,7 @@ class LearningGroups(commands.Cog):
         if users.pop(mid, None):
             user = await self.bot.fetch_user(mid)
             if user and send_message:
-                await utils.send_dm(user, f"Du wurdest aus der Lerngruppe {channel.name} entfernt")
+                await utils.send_dm(user, f"Du wurdest aus der Lerngruppe {channel.name} entfernt.")
 
         await self.save_groups()
 
@@ -466,11 +472,11 @@ class LearningGroups(commands.Cog):
         if not group_config:
             return overwrites
 
-        owner = self.bot.get_user(group_config["owner_id"])
-        if not owner:
+        organizer = self.bot.get_user(group_config["organizer_id"])
+        if not organizer:
             return overwrites
 
-        overwrites[owner] = disnake.PermissionOverwrite(read_messages=True)
+        overwrites[organizer] = disnake.PermissionOverwrite(read_messages=True)
         users = group_config.get("users")
         if not users:
             return overwrites
@@ -489,12 +495,12 @@ class LearningGroups(commands.Cog):
     @commands.group(name="lg", aliases=["learninggroup", "lerngruppe"], pass_context=True)
     async def cmd_lg(self, ctx):
         if not ctx.invoked_subcommand:
-            await ctx.channel.send("Gib `!help lg` ein um eine Übersicht über die Lerngruppen-Kommandos zu erhalten.")
+            await ctx.channel.send("Gib `!help lg` ein, um eine Übersicht über die Lerngruppen-Kommandos zu erhalten.")
 
     @help(
         command_group="lg",
         category="learninggroups",
-        brief="Updated die Lerngruppenliste",
+        brief="Aktualisiert die Lerngruppenliste",
         mod=True
     )
     @cmd_lg.command(name="update")
@@ -508,14 +514,14 @@ class LearningGroups(commands.Cog):
         category="learninggroups",
         syntax="!lg header <coursenumber> <name...>",
         brief="Fügt einen Kurs als neue Überschrift in Botys Lerngruppen-Liste (Kanal #lerngruppen) hinzu. "
-              "Darf Leerzeichen enthalten, Anführungszeichen sind nicht erforderlich.",
+              "Der Name darf Leerzeichen enthalten, Anführungszeichen sind nicht erforderlich.",
         example="!lg header 1141 Mathematische Grundlagen",
         parameters={
             "coursenumber": "Nummer des Kurses wie von der Fernuni angegeben (ohne führende Nullen z. B. 1142).",
             "name...": "Ein frei wählbarer Text (darf Leerzeichen enthalten).",
         },
-        description="Kann auch zum Bearbeiten einer Ãœberschrift genutzt werden. Bei bereits existierender "
-                    "Kursnummer wird die Überschrift abgeändert",
+        description="Kann auch zum Bearbeiten einer Ãœberschrift genutzt werden. Existiert die Kursnummer bereits, "
+                    "wird die Überschrift geändert.",
         mod=True
     )
     @cmd_lg.command(name="header")
@@ -535,22 +541,22 @@ class LearningGroups(commands.Cog):
         category="learninggroups",
         syntax="!lg add <coursenumber> <name> <semester> <status> <@usermention>",
         example="!lg add 1142 mathegenies sose22 closed @someuser",
-        brief="Fügt einen Lerngruppen-Kanal hinzu. Der Name darf keine Leerzeichen enthalten.",
+        brief="Fügt einen Lerngruppenkanal hinzu. Der Name darf keine Leerzeichen enthalten.",
         parameters={
             "coursenumber": "Nummer des Kurses wie von der Fernuni angegeben (ohne führende Nullen z. B. 1142).",
             "name": "Ein frei wählbarer Text ohne Leerzeichen. Bindestriche sind zulässig.",
             "semester": ("Das Semester, für welches diese Lerngruppe erstellt werden soll."
                          "sose oder wise gefolgt von der zweistelligen Jahreszahl (z. B. sose22)."),
             "status": "Gibt an ob die Lerngruppe für weitere Lernwillige geöffnet ist (open) oder nicht (closed).",
-            "@usermention": "Die so erwähnte Benutzerin wird als Besitzerin für die Lerngruppe gesetzt."
+            "@usermention": "Die so erwähnte Benutzerin wird als Organisatorin der Lerngruppe eingesetzt."
         },
         mod=True
     )
     @cmd_lg.command(name="add")
     @commands.check(utils.is_mod)
-    async def cmd_add_group(self, ctx, arg_course, arg_name, arg_semester, arg_state, arg_owner: disnake.Member):
+    async def cmd_add_group(self, ctx, arg_course, arg_name, arg_semester, arg_state, arg_organizer: disnake.Member):
         state = self.arg_state_to_group_state(arg_state)
-        channel_config = {"owner_id": arg_owner.id, "course": arg_course, "name": arg_name, "semester": arg_semester,
+        channel_config = {"organizer_id": arg_organizer.id, "course": arg_course, "name": arg_name, "semester": arg_semester,
                           "state": state, "is_listed": False}
 
         if not await self.is_channel_config_valid(ctx, channel_config, ctx.command.name):
@@ -564,30 +570,50 @@ class LearningGroups(commands.Cog):
         command_group="lg",
         category="learninggroups",
         syntax="!lg request <coursenumber> <name> <semester> <status>",
-        brief="Stellt eine Anfrage für einen neuen Lerngruppen-Kanal.",
+        brief="Stellt eine Anfrage für einen neuen Lerngruppenkanal.",
         example="!lg request 1142 mathegenies sose22 closed",
         description=("Moderatorinnen können diese Anfrage bestätigen, dann wird die Gruppe eingerichtet. "
-                     "Die Besitzerin der Gruppe ist die Benutzerin die die Anfrage eingestellt hat."),
+                     "Die Organisatorin der Gruppe ist die Benutzerin, die die Anfrage gestellt hat."),
         parameters={
             "coursenumber": "Nummer des Kurses, wie von der FernUni angegeben (ohne führende Nullen z. B. 1142).",
             "name": "Ein frei wählbarer Text ohne Leerzeichen.",
             "semester": "Das Semester, für welches diese Lerngruppe erstellt werden soll. sose oder wise gefolgt "
             "von der zweistelligen Jahreszahl (z. B. sose22).",
-            "status": "Gibt an ob die Lerngruppe für weitere Lernwillige geöffnet ist (open) oder nicht (closed)."
+            "status": "Gibt an ob die Lerngruppe für weitere Lernwillige geöffnet ist (open) oder nicht (closed) oder ob es sich um eine private Lerngruppe handelt (private)."
         }
     )
     @cmd_lg.command(name="request", aliases=["r", "req"])
     async def cmd_request_group(self, ctx, arg_course, arg_name, arg_semester, arg_state):
+
+        arg_state = re.sub(r"[^a-z0-9]", "", arg_state.lower())
+        arg_semester = re.sub(r"[^a-z0-9]", "", arg_semester.lower())
+
+        if re.match(r"(wise)|(sose)[0-9]+", arg_state) and re.match(r"(open)|(closed*)|(private)", arg_semester):
+            tmp = arg_state
+            arg_state = arg_semester
+            arg_semester = tmp
+
+        arg_semester = re.sub(r"[^wiseo0-9]", "", arg_semester)
+
+        arg_state = re.sub(r"[^a-z]", "", arg_state)
+
         state = self.arg_state_to_group_state(arg_state)
+
+        arg_course = re.sub(r"[^0-9]", "", arg_course)
+        arg_course = re.sub(r"^0+", "", arg_course)
+
         arg_name = re.sub(
             r"[^A-Za-zäöüß0-9-]",
             "",
             arg_name.lower().replace(" ", "-")
         )
-        arg_semester = arg_semester.lower()
+
+
+
+
         if len(arg_semester) == 8:
             arg_semester = f"{arg_semester[0:4]}{arg_semester[-2:]}"
-        channel_config = {"owner_id": ctx.author.id, "course": arg_course, "name": arg_name, "semester": arg_semester,
+        channel_config = {"organizer_id": ctx.author.id, "course": arg_course, "name": arg_name, "semester": arg_semester,
                           "state": state, "is_listed": False}
 
         if not await self.is_channel_config_valid(ctx, channel_config, ctx.command.name):
@@ -610,14 +636,14 @@ class LearningGroups(commands.Cog):
         category="learninggroups",
         syntax="!lg show",
         brief="Zeigt einen privaten Lerngruppenkanal trotzdem in der Liste an.",
-        description=("Muss im betreffenden Lerngruppen-Kanal ausgeführt werden. "
-                     "Die Lerngruppe wird in der Übersicht der Lerngruppen gelistet, so können Kommilitoninnen noch "
-                     "Anfragen stellen, um in die Lerngruppe aufgenommen zu werden."
-                     "Diese Aktion kann nur von der Besitzerin der Lerngruppe ausgeführt werden. ")
+        description=("Muss im betreffenden Lerngruppenkanal ausgeführt werden. "
+                     "Die Lerngruppe wird in der Übersicht der Lerngruppen aufgeführt, so dass Kommilitoninnen noch "
+                     "anfragen können, in die Lerngruppe aufgenommen zu werden."
+                     "Diese Aktion kann nur von der Organisatorin der Lerngruppe ausgeführt werden. ")
     )
     @cmd_lg.command(name="show")
     async def cmd_show(self, ctx):
-        if self.is_group_owner(ctx.channel, ctx.author) or utils.is_mod(ctx):
+        if self.is_group_organizer(ctx.channel, ctx.author) or utils.is_mod(ctx):
             channel_config = self.channels[str(ctx.channel.id)]
             if channel_config:
                 if channel_config.get("state") == GroupState.PRIVATE:
@@ -626,7 +652,7 @@ class LearningGroups(commands.Cog):
                 elif channel_config.get("state") == GroupState.OPEN:
                     await ctx.channel.send("Nichts zu tun. Offene Lerngruppen werden sowieso in der Liste angezeigt.")
                 elif channel_config.get("state") == GroupState.CLOSED:
-                    await ctx.channel.send("Möchtest du die Gruppen öffnen? Versuch‘s mit `!lg open`")
+                    await ctx.channel.send("Möchtest du die Gruppen öffnen? Versuch's mit `!lg open`")
 
 
     @help(
@@ -634,13 +660,13 @@ class LearningGroups(commands.Cog):
         category="learninggroups",
         syntax="!lg hide",
         brief="Versteckt einen privaten Lerngruppenkanal. ",
-        description=("Muss im betreffenden Lerngruppen-Kanal ausgeführt werden. "
-                     "Die Lerngruppe wird nicht mehr in der Liste der Lerngruppen aufgeführt. "
-                     "Diese Aktion kann nur von der Besitzerin der Lerngruppe ausgeführt werden. ")
+        description=("Muss im betreffenden Lerngruppenkanal ausgeführt werden. "
+                     "Die Lerngruppe wird nicht mehr in der Liste der Lerngruppen angezeigt. "
+                     "Diese Aktion kann nur von der Organisatorin der Lerngruppe ausgeführt werden. ")
     )
     @cmd_lg.command(name="hide")
     async def cmd_hide(self, ctx):
-        if self.is_group_owner(ctx.channel, ctx.author) or utils.is_mod(ctx):
+        if self.is_group_organizer(ctx.channel, ctx.author) or utils.is_mod(ctx):
             channel_config = self.channels[str(ctx.channel.id)]
             if channel_config:
                 if channel_config.get("state") == GroupState.PRIVATE:
@@ -650,8 +676,8 @@ class LearningGroups(commands.Cog):
 
                 elif channel_config.get("state") == GroupState.OPEN:
                     await ctx.channel.send("Offene Lerngruppen können nicht aus der Lerngruppenliste entfernt werden. " 
-                                           "Führe `!lg close` aus um die Lerngruppe zu schließen, "
-                                           "oder `!lg private` um diese auf "
+                                           "Führe `!lg close` aus, um die Lerngruppe zu schließen, "
+                                           "oder `!lg private`, um diese auf "
                                            "privat zu schalten.")
                 elif channel_config.get("state") == GroupState.CLOSED:
                     await ctx.channel.send("Wenn diese Gruppe privat werden soll, ist das Kommando das du brauchst: `!lg private`")
@@ -670,44 +696,44 @@ class LearningGroups(commands.Cog):
         command_group="lg",
         category="learninggroups",
         syntax="!lg open",
-        brief="Öffnet den Lerngruppen-Kanal wenn du die Besitzerin bist. ",
-        description=("Muss im betreffenden Lerngruppen-Kanal ausgeführt werden. "
-                     "Verschiebt den Lerngruppen-Kanal in die Kategorie für offene Kanäle und ändert das Icon. "
-                     "Diese Aktion kann nur von der Besitzerin der Lerngruppe ausgeführt werden. ")
+        brief="Öffnet den Lerngruppenkanal, wenn du die Organisatorin bist. ",
+        description=("Muss im betreffenden Lerngruppenkanal ausgeführt werden. "
+                     "Verschiebt den Lerngruppenkanal in die Kategorie für offene Kanäle und ändert das Icon. "
+                     "Diese Aktion kann nur von der Organisatorin der Lerngruppe ausgeführt werden. ")
     )
     @cmd_lg.command(name="open", aliases=["opened", "offen"])
     async def cmd_open(self, ctx):
-        if self.is_group_owner(ctx.channel, ctx.author) or utils.is_mod(ctx):
+        if self.is_group_organizer(ctx.channel, ctx.author) or utils.is_mod(ctx):
             await self.set_channel_state(ctx.channel, state=GroupState.OPEN)
 
     @help(
         command_group="lg",
         category="learninggroups",
         syntax="!lg close",
-        brief="Schließt den Lerngruppen-Kanal wenn du die Besitzerin bist. ",
-        description=("Muss im betreffenden Lerngruppen-Kanal ausgeführt werden. "
+        brief="Schließt den Lerngruppenkanal, wenn du die Organisatorin bist. ",
+        description=("Muss im betreffenden Lerngruppenkanal ausgeführt werden. "
                      "Stellt die Lerngruppe auf geschlossen. Dies ist rein symbolisch und zeigt an, "
                      "dass keine neuen Mitglieder mehr aufgenommen werden. "
-                     "Diese Aktion kann nur von der Besitzerin der Lerngruppe ausgeführt werden. ")
+                     "Diese Aktion kann nur von der Organisatorin der Lerngruppe ausgeführt werden. ")
     )
     @cmd_lg.command(name="close", aliases=["closed", "geschlossen"])
     async def cmd_close(self, ctx):
-        if self.is_group_owner(ctx.channel, ctx.author) or utils.is_mod(ctx):
+        if self.is_group_organizer(ctx.channel, ctx.author) or utils.is_mod(ctx):
             await self.set_channel_state(ctx.channel, state=GroupState.CLOSED)
 
     @help(
         command_group="lg",
         category="learninggroups",
         syntax="!lg private",
-        brief="Macht aus deiner Lerngruppe eine private Lerngruppe wenn du die Besitzerin bist. ",
-        description=("Muss im betreffenden Lerngruppen-Kanal ausgeführt werden. "
+        brief="Macht aus deiner Lerngruppe eine private Lerngruppe, wenn du die Organisatorin bist. ",
+        description=("Muss im betreffenden Lerngruppenkanal ausgeführt werden. "
                      "Stellt die Lerngruppe auf privat. Es haben nur noch Mitglieder "
-                     "der Lerngruppe zugriff auf den Kanal. (siehe `!lg members`)"
-                     "Diese Aktion kann nur von der Besitzerin der Lerngruppe ausgeführt werden. ")
+                     "der Lerngruppe Zugriff auf den Kanal. (siehe `!lg members`)"
+                     "Diese Aktion kann nur von der Organisatorin der Lerngruppe ausgeführt werden. ")
     )
     @cmd_lg.command(name="private", aliases=["privat"])
     async def cmd_private(self, ctx):
-        if self.is_group_owner(ctx.channel, ctx.author) or utils.is_mod(ctx):
+        if self.is_group_organizer(ctx.channel, ctx.author) or utils.is_mod(ctx):
             if await self.set_channel_state(ctx.channel, state=GroupState.PRIVATE):
                 await self.update_permissions(ctx.channel)
 
@@ -717,7 +743,7 @@ class LearningGroups(commands.Cog):
         command_group="lg",
         category="learninggroups",
         syntax="!lg rename <name>",
-        brief="Ändert den Namen des Lerngruppen-Kanals, in dem das Komando ausgeführt wird.",
+        brief="Ändert den Namen des Lerngruppenkanals, in dem das Kommando ausgeführt wird.",
         example="!lg rename matheluschen",
         description="Aus #1142-matheprofis-sose22 wird nach dem Aufruf des Beispiels #1142-matheluschen-sose22.",
         parameters={
@@ -734,8 +760,8 @@ class LearningGroups(commands.Cog):
         command_group="lg",
         syntax="!lg archive",
         category="learninggroups",
-        brief="Archiviert den Lerngruppen-Kanal",
-        description="Verschiebt den Lerngruppen-Kanal, in welchem dieses Kommando ausgeführt wird, ins Archiv.",
+        brief="Archiviert den Lerngruppenkanal.",
+        description="Verschiebt den Lerngruppenkanal, in welchem dieses Kommando ausgeführt wird, ins Archiv.",
         mod=True
     )
     @cmd_lg.command(name="archive", aliases=["archiv"])
@@ -746,42 +772,42 @@ class LearningGroups(commands.Cog):
     @help(
         command_group="lg",
         category="learninggroups",
-        syntax="!lg owner <@usermention>",
-        example="!owner @someuser",
-        brief="Setzt die Besitzerin eines Lerngruppen-Kanals",
-        description="Muss im betreffenden Lerngruppen-Kanal ausgeführt werden. ",
+        syntax="!lg organizer <@usermention>",
+        example="!lg organizer @someuser",
+        brief="Bestimmt die Organisatorin eines Lerngruppenkanals.",
+        description="Muss im betreffenden Lerngruppenkanal ausgeführt werden. ",
         parameters={
-            "@usermention": "Die neue Besitzerin der Lerngruppe."
+            "@usermention": "Die neue Organisatorin der Lerngruppe."
         }
     )
-    @cmd_lg.command(name="owner")
-    async def cmd_owner(self, ctx, new_owner: disnake.Member = None):
+    @cmd_lg.command(name="organizer")
+    async def cmd_organizer(self, ctx, new_organizer: disnake.Member = None):
         group_config = self.groups["groups"].get(str(ctx.channel.id))
 
         if not group_config:
             self.groups["groups"][str(ctx.channel.id)] = {}
             group_config = self.groups["groups"][str(ctx.channel.id)]
 
-        owner_id = group_config.get("owner_id")
+        organizer_id = group_config.get("organizer_id")
 
-        if not owner_id:
+        if not organizer_id:
             return
 
-        if not new_owner:
-                user = await self.bot.fetch_user(owner_id)
-                await ctx.channel.send(f"Besitzerin: @{user.name}#{user.discriminator}")
+        if not new_organizer:
+                user = await self.bot.fetch_user(organizer_id)
+                await ctx.channel.send(f"Organisatorin: @{user.name}#{user.discriminator}")
 
         elif isinstance(group_config, dict):
-            owner = await self.bot.fetch_user(owner_id)
-            if self.is_group_owner(ctx.channel, ctx.author) or utils.is_mod(ctx):
-                group_config["owner_id"] = new_owner.id
-                await self.remove_member_from_group(ctx.channel, new_owner, False)
-                if new_owner != owner:
-                    await self.add_member_to_group(ctx.channel, owner, False)
+            organizer = await self.bot.fetch_user(organizer_id)
+            if self.is_group_organizer(ctx.channel, ctx.author) or utils.is_mod(ctx):
+                group_config["organizer_id"] = new_organizer.id
+                await self.remove_member_from_group(ctx.channel, new_organizer, False)
+                if new_organizer != organizer:
+                    await self.add_member_to_group(ctx.channel, organizer, False)
                 await self.save_groups()
                 await self.update_permissions(ctx.channel)
                 await ctx.channel.send(
-                    f"Glückwunsch {new_owner.mention}! Du bist jetzt die Besitzerin dieser Lerngruppe.")
+                    f"Glückwunsch {new_organizer.mention}! Du bist jetzt die Organisatorin dieser Lerngruppe.")
 
     @help(
         command_group="lg",
@@ -791,7 +817,7 @@ class LearningGroups(commands.Cog):
         brief="Fügt eine Benutzerin zu einer Lerngruppe hinzu.",
         parameters={
             "@usermention": "Die so erwähnte Benutzerin wird zur Lerngruppe hinzugefügt.",
-            "#channel": "(optional) Der Kanal dem die Benutzerin hinzugefügt werden soll."
+            "#channel": "(optional) Der Kanal, zu dem die Benutzerin hinzugefügt werden soll."
         }
     )
     @cmd_lg.command(name="addmember", aliases=["addm", "am"])
@@ -799,10 +825,10 @@ class LearningGroups(commands.Cog):
         if not arg_channel:
             if not self.channels.get(str(ctx.channel.id)):
                 await ctx.channel.send("Wenn das Kommando außerhalb eines Lerngruppenkanals aufgerufen wird, muss der" 
-                                       "Lerngruppenkanal angehängt werden. `!lg addmember <@usermention> <#channel>`")
+                                       "Lerngruppenkanal angefügt werden. `!lg addmember <@usermention> <#channel>`")
                 return
             arg_channel = ctx.channel
-        if self.is_group_owner(arg_channel, ctx.author) or utils.is_mod(ctx):
+        if self.is_group_organizer(arg_channel, ctx.author) or utils.is_mod(ctx):
             await self.add_member_to_group(arg_channel, arg_member)
             await self.update_permissions(arg_channel)
 
@@ -813,7 +839,7 @@ class LearningGroups(commands.Cog):
         example="!lg removemember @someuser #1141-mathegl-lerngruppe-sose21",
         brief="Entfernt eine Benutzerin aus einer Lerngruppe.",
         parameters={
-            "#channel": "Der Kanal aus dem die Benutzerin gelöscht werden soll.",
+            "#channel": "Der Kanal, aus dem die Benutzerin gelöscht werden soll.",
             "@usermention": "Die so erwähnte Benutzerin wird aus der Lerngruppe entfernt."
         },
         mod=True
@@ -828,7 +854,7 @@ class LearningGroups(commands.Cog):
         command_group="lg",
         category="learninggroups",
         syntax="!lg members",
-        brief="Listet die Mitglieder der Lerngruppe auf.",
+        brief="Zählt die Mitglieder der Lerngruppe auf.",
     )
     @cmd_lg.command(name="members")
     async def cmd_members(self, ctx):
@@ -836,14 +862,14 @@ class LearningGroups(commands.Cog):
         if not group_config:
             await ctx.channel.send("Das ist kein Lerngruppenkanal.")
             return
-        owner_id = group_config.get("owner_id")
+        organizer_id = group_config.get("organizer_id")
 
-        if not owner_id:
+        if not organizer_id:
             return
 
-        owner = await self.bot.fetch_user(owner_id)
+        organizer = await self.bot.fetch_user(organizer_id)
         users = group_config.get("users", {})
-        if not users and not owner:
+        if not users and not organizer:
             await ctx.channel.send("Keine Lerngruppenmitglieder vorhanden.")
             return
 
@@ -853,7 +879,7 @@ class LearningGroups(commands.Cog):
             user = await self.bot.fetch_user(user_id)
             names.append("@" + user.name + "#" + user.discriminator)
 
-        await ctx.channel.send(f"Besitzerin: **@{owner.name}#{owner.discriminator}**\nMitglieder: " +
+        await ctx.channel.send(f"Organisatorin: **@{organizer.name}#{organizer.discriminator}**\nMitglieder: " +
                                (f"{', '.join(names)}" if len(names) > 0 else "Keine"))
 
     @help(
@@ -864,7 +890,7 @@ class LearningGroups(commands.Cog):
     )
     @cmd_lg.command(name="id")
     async def cmd_id(self, ctx):
-        if self.is_group_owner(ctx.channel, ctx.author) or utils.is_mod(ctx):
+        if self.is_group_organizer(ctx.channel, ctx.author) or utils.is_mod(ctx):
             group_config = self.groups["groups"].get(str(ctx.channel.id))
             if not group_config:
                 await ctx.channel.send("Das ist kein Lerngruppenkanal.")
@@ -876,9 +902,9 @@ class LearningGroups(commands.Cog):
         command_group="lg",
         category="learninggroups",
         syntax="!lg join <lg-id>",
-        brief="Fragt bei der Besitzerin einer Lerngruppe um Aufnahme.",
+        brief="Fragt bei der Organisatorin einer Lerngruppe um Aufnahme an.",
         parameters={
-            "id": "Die ID zur Lerngruppe."
+            "id": "Die ID der Lerngruppe."
         }
     )
     @cmd_lg.command(name="join")
@@ -900,12 +926,12 @@ class LearningGroups(commands.Cog):
             channel=channel,
             title="Jemand möchte deiner Lerngruppe beitreten!",
             description=f"<@!{ctx.author.id}> möchte gerne der Lerngruppe **#{channel.name}** beitreten.",
-            message=f"Anfrage von <@!{ctx.author.id}>",
+            message=f"<@!{group_config['organizer_id']}>, du wirst gebraucht. Anfrage von <@!{ctx.author.id}>:",
             custom_prefix="learninggroups:join"
         )
         await utils.send_dm(ctx.author, f"Deine Anfrage wurde an **#{channel.name}** gesendet. "
-                                        "Sobald die Besitzerin der Lerngruppe darüber "
-                                        "entschieden hat bekommst du Bescheid.")
+                                        "Sobald die Organisatorin der Lerngruppe darüber "
+                                        "entschieden hat, bekommst du Bescheid.")
 
     @help(
         command_group="lg",
@@ -915,7 +941,7 @@ class LearningGroups(commands.Cog):
     )
     @cmd_lg.command(name="kick")
     async def cmd_kick(self, ctx, arg_member: disnake.Member):
-        if self.is_group_owner(ctx.channel, ctx.author) or utils.is_mod(ctx):
+        if self.is_group_organizer(ctx.channel, ctx.author) or utils.is_mod(ctx):
             group_config = self.groups["groups"].get(str(ctx.channel.id))
             if not group_config:
                 await ctx.channel.send("Das ist keine gültiger Lerngruppenkanal.")
@@ -937,8 +963,8 @@ class LearningGroups(commands.Cog):
             await ctx.channel.send("Das ist keine gültiger Lerngruppenkanal.")
             return
 
-        if group_config["owner_id"] == ctx.author.id:
-            await ctx.channel.send("Du kannst nicht aus deiner eigenen Lerngruppe flüchten. Übertrage erst den Besitz.")
+        if group_config["organizer_id"] == ctx.author.id:
+            await ctx.channel.send("Du kannst nicht aus deiner eigenen Lerngruppe flüchten. Gib erst die Verantwortung ab.")
             return
 
         await self.remove_member_from_group(ctx.channel, ctx.author)
@@ -954,9 +980,9 @@ class LearningGroups(commands.Cog):
             if confirmed and self.is_mod(member):
                 await self.add_requested_group_channel(message, direct=False)
 
-            elif not confirmed and (self.is_request_owner(request, member) or self.is_mod(member)):
+            elif not confirmed and (self.is_request_organizer(request, member) or self.is_mod(member)):
                 if self.is_mod(member):
-                    user = await self.bot.fetch_user(request["owner_id"] )
+                    user = await self.bot.fetch_user(request["organizer_id"] )
                     if user:
                         await utils.send_dm(user, f"Deine Lerngruppenanfrage für #{self.full_channel_name(request)} wurde abgelehnt.")
                 await self.remove_group_request(message)
@@ -972,10 +998,10 @@ class LearningGroups(commands.Cog):
         if not group_config:
             return
 
-        if self.is_group_owner(channel, member) or self.is_mod(member):
+        if self.is_group_organizer(channel, member) or self.is_mod(member):
             if confirmed:
-                if message.mentions and len(message.mentions) == 1:
-                    await self.add_member_to_group(channel, message.mentions[0])
+                if message.mentions and len(message.mentions) == 2:
+                    await self.add_member_to_group(channel, message.mentions[1])
                     await self.update_permissions(channel)
 
                 else:
diff --git a/cogs/roles.py b/cogs/roles.py
index fa3a4d4d1112fe7f8808f727359426b0e03e7e0e..f3be0d5a8d3f1c1c2008dfe11e4a8ad84a710b3b 100644
--- a/cogs/roles.py
+++ b/cogs/roles.py
@@ -2,24 +2,18 @@ import json
 import os
 
 import disnake
+import emoji
 from disnake.ext import commands
 
-import utils
-from cogs.help import help, handle_error, help_category
 
-
-@help_category("updater", "Updater", "Diese Kommandos werden zum Updaten von Nachrichten benutzt, die Boty automatisch erzeugt.")
-@help_category("info", "Informationen", "Kleine Helferlein, um schnell an Informationen zu kommen.")
 class Roles(commands.Cog):
     def __init__(self, bot):
         self.bot = bot
         self.roles_file = os.getenv("DISCORD_ROLES_FILE")
         self.channel_id = int(os.getenv("DISCORD_ROLLEN_CHANNEL", "0"))
-        self.degree_program_message_id = int(os.getenv("DISCORD_DEGREE_PROGRAM_MSG", "0"))
-        self.color_message_id = int(os.getenv("DISCORD_COLOR_MSG", "0"))
-        self.special_message_id = int(os.getenv("DISCORD_SPECIAL_MSG", "0"))
         self.assignable_roles = {}
         self.load_roles()
+        self.register_views()
 
     def load_roles(self):
         """ Loads all assignable roles from ROLES_FILE """
@@ -27,202 +21,102 @@ class Roles(commands.Cog):
         roles_file = open(self.roles_file, mode='r')
         self.assignable_roles = json.load(roles_file)
 
-    def get_degree_program_emojis(self):
-        """ Creates a dict for degree program role emojis """
-
-        tmp_emojis = {}
-        emojis = {}
-        degree_program_assignable = self.assignable_roles[0]
-
-        # start with getting all emojis that are used in those roles as a dict
-        for emoji in self.bot.emojis:
-            if emoji.name in degree_program_assignable:
-                tmp_emojis[emoji.name] = emoji
-
-        # bring them in desired order
-        for key in degree_program_assignable.keys():
-            emojis[key] = tmp_emojis.get(key)
-
-        return emojis
-
-    def get_color_emojis(self):
-        """ Creates a dict for color role emojis """
-
-        emojis = {}
-        color_assignable = self.assignable_roles[1]
+    def register_views(self):
+        """ Register view for each category at view manager """
 
-        # start with getting all emojis that are used in those roles as a dict
-        for emoji in self.bot.emojis:
-            if emoji.name in color_assignable:
-                emojis[emoji.name] = emoji
+        for role_category, roles in self.assignable_roles.items():
+            prefix = f"assign_{role_category}"
+            self.bot.view_manager.register(prefix, self.on_button_clicked)
 
-        return emojis
+    def get_stat_roles(self):
+        """ Get all roles that should be part of the stats Command """
 
-    def get_special_emojis(self):
-        """ Creates a dict for special role emojis """
+        stat_roles = []
+        for category in self.assignable_roles.values():
+            if category["in_stats"]:
+                for role in category["roles"].values():
+                    stat_roles.append(role["name"])
 
-        return self.assignable_roles[2]
+        return stat_roles
 
-    def get_key(self, role):
-        """ Get the key for a given role. This role is used for adding or removing a role from a user. """
+    async def on_button_clicked(self, button: disnake.ui.Button, interaction: disnake.MessageInteraction, value=None):
+        """
+        Add or Remove Roles, when Button is clicked. Role gets added, if the user clicking the button doesn't have
+        the role already assigned, and removed, if the role is already assigned
+        """
 
-        for key, role_name in self.assignable_roles[0].items():
-            if role_name == role.name:
-                return key
+        guild_roles = {str(role.id): role for role in interaction.guild.roles}
+        role = guild_roles.get(value)
 
-    @help(
-        category="info",
-        brief="Gibt die Mitgliederstatistik aus."
-    )
-    @commands.command(name="stats")
-    async def cmd_stats(self, ctx):
-        """ Sends stats in Chat. """
-
-        guild = ctx.guild
+        if role in interaction.author.roles:
+            await interaction.author.remove_roles(role)
+            await interaction.send(f"Rolle \"{role.name}\" erfolgreich entfernt", ephemeral=True)
+        else:
+            await interaction.author.add_roles(role)
+            await interaction.send(f"Rolle \"{role.name}\" erfolgreich hinzugefügt", ephemeral=True)
+
+    @commands.slash_command(name="update-roles", description="Update Self-Assignable Roles")
+    @commands.default_member_permissions(moderate_members=True)
+    async def cmd_update_roles(self, interaction: disnake.ApplicationCommandInteraction):
+        """ Update all role assignment messages in role assignment channel """
+        await interaction.response.defer(ephemeral=True)
+
+        channel = await interaction.guild.fetch_channel(self.channel_id)
+        await channel.purge()
+        for role_category, roles in self.assignable_roles.items():
+            prefix = f"assign_{role_category}"
+            fields = []
+            buttons = []
+            value = f""
+            guild_roles = {role.name: role for role in interaction.guild.roles}
+
+            for key, role in roles.get("roles").items():
+                role_emoji = role.get('emoji') if role.get(
+                    'emoji') in emoji.UNICODE_EMOJI_ALIAS_ENGLISH else f"<{role.get('emoji')}>"
+                value += f"{role_emoji} : {role.get('name')}\n"
+                buttons.append({"emoji": role_emoji, "custom_id": f"{prefix}_{key}",
+                                "value": f"{str(guild_roles.get(role.get('name')).id)}"})
+
+            if roles.get("list_roles"):
+                fields.append({"name": "Rollen", "value": value, "inline": False})
+
+            await self.bot.view_manager.dialog(
+                channel=channel,
+                title=f"Vergabe von {roles.get('name')}",
+                description="Durch klicken auf den entsprechenden Button kannst du dir die damit "
+                            "assoziierte Rolle zuweisen, bzw. entfernen.",
+                message="",
+                fields=fields,
+                callback_key=prefix,
+                buttons=buttons
+            )
+
+        await interaction.edit_original_message("Rollen erfolgreich aktualisiert.")
+
+    @commands.slash_command(name="stats", description="Rollen Statistik abrufen")
+    async def cmd_stats(self, interaction: disnake.ApplicationCommandInteraction, show: bool = False):
+        """
+        Send role statistics into chat, by default as ephemeral
+
+        Parameters
+        ----------
+        show: Sichtbar für alle?
+        """
+
+        guild = interaction.guild
         members = await guild.fetch_members().flatten()
-        answer = f''
+        guild_roles = {role.name: role for role in interaction.guild.roles}
+        stat_roles = self.get_stat_roles()
         embed = disnake.Embed(title="Statistiken",
-                              description=f'Wir haben aktuell {len(members)} Mitglieder auf diesem Server, verteilt auf folgende Rollen:')
+                              description=f'Wir haben aktuell {len(members)} Mitglieder auf diesem Server, '
+                                          f'verteilt auf folgende Rollen:')
 
-        for role in guild.roles:
-            if not self.get_key(role):
-                continue
+        for role_name in stat_roles:
+            role = guild_roles[role_name]
             role_members = role.members
-            if len(role_members) > 0 and not role.name.startswith("Farbe"):
-                embed.add_field(name=role.name, value=f'{len(role_members)} Mitglieder', inline=False)
-
-        no_role = 0
-        for member in members:
-            # ToDo Search for study roles only!
-            if len(member.roles) == 1:
-                no_role += 1
-
-        embed.add_field(name="\u200B", value="\u200b", inline=False)
-        embed.add_field(name="Mitglieder ohne Rolle", value=str(no_role), inline=False)
-
-        await ctx.channel.send(answer, embed=embed)
-
-    @help(
-        category="updater",
-        brief="Aktualisiert die Vergabe-Nachricht von Studiengangs-Rollen.",
-        mod=True
-    )
-    @commands.command("update-degree-program")
-    @commands.check(utils.is_mod)
-    async def cmd_update_degree_program(self, ctx):
-        channel = await self.bot.fetch_channel(self.channel_id)
-        message = await channel.fetch_message(self.degree_program_message_id)
-        degree_program_emojis = self.get_degree_program_emojis()
-
-        embed = disnake.Embed(title="Vergabe von Studiengangs-Rollen",
-                              description="Durch klicken auf die entsprechende Reaktion kannst du dir die damit assoziierte Rolle zuweisen, oder entfernen. Dies funktioniert so, dass ein Klick auf die Reaktion die aktuelle Zuordnung dieser Rolle ändert. Das bedeutet, wenn du die Rolle, die mit <:St:763126549327118366> assoziiert ist, schon hast, aber die Reaktion noch nicht ausgewählt hast, dann wird dir bei einem Klick auf die Reaktion diese Rolle wieder weggenommen. ")
-
-        value = f""
-        for key, emoji in degree_program_emojis.items():
-            if emoji:
-                value += f"<:{key}:{emoji.id}> : {self.assignable_roles[0].get(key)}\n"
-
-        embed.add_field(name="Rollen",
-                        value=value,
-                        inline=False)
-
-        await message.edit(content="", embed=embed)
-        await message.clear_reactions()
-
-        for emoji in degree_program_emojis.values():
-            if emoji:
-                await message.add_reaction(emoji)
-
-    @help(
-        category="updater",
-        brief="Aktualisiert die Vergabe-Nachricht von Farb-Rollen.",
-        mod=True
-    )
-    @commands.command("update-color")
-    @commands.check(utils.is_mod)
-    async def cmd_update_color(self, ctx):
-        channel = await self.bot.fetch_channel(self.channel_id)
-        message = await channel.fetch_message(self.color_message_id)
-        color_emojis = self.get_color_emojis()
-
-        embed = disnake.Embed(title="Vergabe von Farb-Rollen",
-                              description="Durch klicken auf die entsprechende Reaktion kannst du dir die damit assoziierte Rolle zuweisen, oder entfernen. Dies funktioniert so, dass ein Klick auf die Reaktion die aktuelle Zuordnung dieser Rolle ändert. Das bedeutet, wenn du die Rolle, die mit <:FarbeGruen:771451407916204052> assoziiert ist, schon hast, aber die Reaktion noch nicht ausgewählt hast, dann wird dir bei einem Klick auf die Reaktion diese Rolle wieder weggenommen. ")
-
-        await message.edit(content="", embed=embed)
-        await message.clear_reactions()
-
-        for emoji in color_emojis.values():
-            if emoji:
-                await message.add_reaction(emoji)
-
-    @help(
-        category="updater",
-        brief="Aktualisiert die Vergabe-Nachricht von Spezial-Rollen.",
-        mod=True
-    )
-    @commands.command("update-special")
-    @commands.check(utils.is_mod)
-    async def cmd_update_special(self, ctx):
-        channel = await self.bot.fetch_channel(self.channel_id)
-        message = await channel.fetch_message(self.special_message_id)
-        special_emojis = self.get_special_emojis()
-
-        embed = disnake.Embed(title="Vergabe von Spezial-Rollen",
-                              description="Durch klicken auf die entsprechende Reaktion kannst du dir die damit assoziierte Rolle zuweisen, oder entfernen. Dies funktioniert so, dass ein Klick auf die Reaktion die aktuelle Zuordnung dieser Rolle ändert. Das bedeutet, wenn du die Rolle, die mit :exclamation: assoziiert ist, schon hast, aber die Reaktion noch nicht ausgewählt hast, dann wird dir bei einem Klick auf die Reaktion diese Rolle wieder weggenommen. ")
-
-        value = f""
-        for emoji, role in special_emojis.items():
-            value += f"{emoji} : {role}\n"
-
-        embed.add_field(name="Rollen",
-                        value=value,
-                        inline=False)
-
-        await message.edit(content="", embed=embed)
-        await message.clear_reactions()
-
-        for emoji in special_emojis.keys():
-            await message.add_reaction(emoji)
-
-    @commands.Cog.listener()
-    async def on_raw_reaction_add(self, payload):
-        if payload.user_id == self.bot.user.id or payload.message_id not in [self.degree_program_message_id,
-                                                                             self.color_message_id,
-                                                                             self.special_message_id]:
-            return
-
-        if payload.emoji.name not in self.assignable_roles[0] and payload.emoji.name not in self.assignable_roles[
-            1] and payload.emoji.name not in self.assignable_roles[2]:
-            return
-
-        role_name = ""
-        guild = await self.bot.fetch_guild(payload.guild_id)
-        member = await guild.fetch_member(payload.user_id)
-        channel = await self.bot.fetch_channel(payload.channel_id)
-        message = await channel.fetch_message(payload.message_id)
-        roles = member.roles
-
-        await message.remove_reaction(payload.emoji, member)
-
-        if payload.emoji.name in self.assignable_roles[0]:
-            role_name = self.assignable_roles[0].get(payload.emoji.name)
-        elif payload.emoji.name in self.assignable_roles[1]:
-            role_name = self.assignable_roles[1].get(payload.emoji.name)
-        else:
-            role_name = self.assignable_roles[2].get(payload.emoji.name)
-
-        for role in roles:
-            if role.name == role_name:
-                await member.remove_roles(role)
-                await utils.send_dm(member, f"Rolle \"{role.name}\" erfolgreich entfernt")
-                break
-        else:
-            guild_roles = guild.roles
-
-            for role in guild_roles:
-                if role.name == role_name:
-                    await member.add_roles(role)
-                    await utils.send_dm(member, f"Rolle \"{role.name}\" erfolgreich hinzugefügt")
+            num_members = len(role_members)
+            if num_members > 0:
+                embed.add_field(name=role.name,
+                                value=f'{num_members} {"Mitglieder" if num_members > 1 else "Mitglied"}', inline=False)
 
-    async def cog_command_error(self, ctx, error):
-        await handle_error(ctx, error)
+        await interaction.send(embed=embed, ephemeral=not show)
diff --git a/fernuni_bot.py b/fernuni_bot.py
index 9c9e334e8ebd7cbdda0e696c39e02b673b4a4ba0..638601830786bda80c30f3ae1863ac6cc975832a 100644
--- a/fernuni_bot.py
+++ b/fernuni_bot.py
@@ -56,6 +56,7 @@ class Boty(commands.Bot):
         self.add_cog(calmdown.Calmdown(self))
         self.add_cog(github.Github(self))
         self.add_cog(timer.Timer(self))
+        # self.add_cog(job_offers.Joboffers(self))
 
 
 bot = Boty()
diff --git a/requirements.txt b/requirements.txt
index 7213ab12887f08b1cf6f64776273fd4bfe3e119f..06585bd5955a3a246f7de4d1aef4cecf64fc1401 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,21 +1,21 @@
-aiohttp==3.7.4
-async-timeout==3.0.1
-attrs==20.3.0
-beautifulsoup4==4.9.3
-certifi==2020.12.5
-cffi==1.14.5
-chardet==3.0.4
-disnake==2.2.2
-emoji==1.2.0
-idna==2.10
-multidict==5.1.0
-pycparser==2.20
-PyNaCl==1.4.0
-python-dotenv==0.17.0
-requests==2.25.1
-six==1.16.0
-soupsieve==2.2.1
-tinydb==4.4.0
-typing-extensions==3.7.4.3
-urllib3==1.26.5
-yarl==1.6.3
+aiohttp==3.7.4
+async-timeout==3.0.1
+attrs==20.3.0
+beautifulsoup4==4.9.3
+certifi==2020.12.5
+cffi==1.14.5
+chardet==3.0.4
+disnake==2.5.2
+emoji==1.2.0
+idna==2.10
+multidict==5.1.0
+pycparser==2.20
+PyNaCl==1.4.0
+python-dotenv==0.20.0
+requests==2.25.1
+six==1.16.0
+soupsieve==2.2.1
+tinydb==4.4.0
+typing-extensions==3.7.4.3
+urllib3==1.26.5
+yarl==1.6.3
diff --git a/utils.py b/utils.py
index 0959473e7c6bd4bb32d05e686e04912e572cd2a9..84906098d2d61f501ac5b464681b704a975e67ad 100644
--- a/utils.py
+++ b/utils.py
@@ -15,11 +15,14 @@ DATE_TIME_FMT = os.getenv("DISCORD_DATE_TIME_FORMAT")
 async def send_dm(user, message, embed=None):
     """ Send DM to a user/member """
 
-    if type(user) is disnake.User or type(user) is disnake.Member:
-        if user.dm_channel is None:
-            await user.create_dm()
-
-        return await user.dm_channel.send(message, embed=embed)
+    try:
+        if type(user) is disnake.User or type(user) is disnake.Member:
+            if user.dm_channel is None:
+                await user.create_dm()
+
+            return await user.dm_channel.send(message, embed=embed)
+    except:
+        print(f"Cannot send DM to {user} with text: {message}")
 
 
 def is_mod(ctx):
diff --git a/views/joboffers_view.py b/views/joboffers_view.py
new file mode 100644
index 0000000000000000000000000000000000000000..588abbafbaca92818274f2447d009895cd38d79f
--- /dev/null
+++ b/views/joboffers_view.py
@@ -0,0 +1,35 @@
+import disnake
+from disnake import MessageInteraction, ButtonStyle
+from disnake.ui import Button, View
+
+NEXT = "jobs:next"
+PREV = "jobs:prev"
+
+
+class JobOffersView(View):
+    def __init__(self, callback, list_of_pages, actual_page_nr, embed_description):
+        super().__init__(timeout=None)
+        self.callback = callback
+        self.list_of_pages = list_of_pages
+        self.actual_page_nr = actual_page_nr
+        self.embed_description = embed_description
+        if actual_page_nr == 1:
+            self.disable_prev()
+        if actual_page_nr == len(self.list_of_pages):
+            self.disable_next()
+
+    @disnake.ui.button(emoji="⬅", custom_id=PREV)
+    async def btn_prev(self, button: Button, interaction: MessageInteraction):
+        await self.callback(button, interaction, self.list_of_pages, self.actual_page_nr, self.embed_description)
+
+    @disnake.ui.button(emoji="âž¡", custom_id=NEXT)
+    async def btn_next(self, button: Button, interaction: MessageInteraction):
+        await self.callback(button, interaction, self.list_of_pages, self.actual_page_nr, self.embed_description)
+
+    def disable_prev(self):
+        prev_button = self.children[0]
+        prev_button.disabled = True
+
+    def disable_next(self):
+        next_button = self.children[1]
+        next_button.disabled = True
\ No newline at end of file