diff --git a/LICENSE.md b/LICENSE.md
index 4dc11eca968a0b1931fd904c53f9184876cf683d..4c1034a1f7f175e619d83b56eec67a85461fc228 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,7 +1,7 @@
 
 The MIT License (MIT)
 
-Copyright (c) 2018-2019 Benedikt Magnus
+Copyright (c) 2018-2021 Benedikt Magnus
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/locale/de-DE.commands.json b/locale/de-DE.commands.json
index 6f4baec22bda0900f1e41ac110001dbef15f7d23..46f6fe31fc35e4445e6267091ca9498ac38f8d2c 100644
--- a/locale/de-DE.commands.json
+++ b/locale/de-DE.commands.json
@@ -36,6 +36,12 @@
             "Tag"
         ]
     },
+    "goodEvening": {
+        "commands": [
+            "guten Abend",
+            "Abend"
+        ]
+    },
     "goodMorning": {
         "commands": [
             "guten Morgen",
@@ -86,6 +92,14 @@
     "maybe": {
         "commands": ["vielleicht", "vllt", "eventuell", "evtl"]
     },
+    "moddingStatus":
+    {
+        "commands": [
+            "Wichtelstatus",
+            "Status"
+        ],
+        "info": "Gibt Informationen zum aktuellen Status des Wichtelns aus."
+    },
     "no": {
         "commands": ["nein", "ne", "nö", "ausgeschlossen", "auf keinen Fall"]
     },
@@ -96,7 +110,26 @@
     "sternenrose": {
         "commands": ["sternenrose"]
     },
+    "thankYou": {
+        "commands": [
+            "Danke",
+            "Dankeschön",
+            "Dankesehr",
+            "Danke dir",
+            "Vielen Dank",
+            "Großen Dank"
+        ]
+    },
     "yes": {
         "commands": ["ja", "jap", "jawohl", "okay", "ok", "meinetwegen"]
+    },
+    "yourAreWelcome": {
+        "commands": [
+            "Bitte",
+            "Bittesehr",
+            "Bitte sehr",
+            "Bitteschön",
+            "Bitte schön"
+        ]
     }
 }
diff --git a/locale/de-DE.texts.json b/locale/de-DE.texts.json
index 446d00c505d8ffa2dfb726ac3bd564b8ab79d72f..0401117030d05a5ec3bfacb84b6f0e8012e0ab10 100644
--- a/locale/de-DE.texts.json
+++ b/locale/de-DE.texts.json
@@ -14,6 +14,7 @@
     "deregistration": "Schade, {contact.nickname}! Ich hab dich vom Wichteln abgemeldet. Wenn du wieder mitmachen möchtest, schreibe „registrieren“.",
     "deregistrationCancelled": "Puh, nochmal Glück gehabt! Schön, dass du dabei bleibst!",
     "goodAfternoon": "Guten Tag, {contact.nickname}!",
+    "goodEvening": "Guten Abend, {contact.nickname}!",
     "goodMorning": "Guten Morgen, {contact.nickname}!",
     "goodNight": "Schlaf schön, {contact.nickname}!",
     "hello": "Hallööö, {contact.nickname}!",
@@ -35,6 +36,9 @@
     "notUnderstood": "Häää? Probiers nochmal.",
     "oldInformation": "Dies findet sich aktuell dazu in meiner Datenbank:\n>>> {var.informationValue}",
     "moderationNeedHelp": "<@&{var.moderationRoleId}> Der Wichtel {contact.nickname} ({contact.tag}) bittet um Hilfe.",
+    "moderationStatus": "**Status des Wichtelns {var.currentEventName}**\nAktuelle Phase: {var.eventPhaseString}\n\nAnzahl Teilnehmer: {var.contactCount}\nDavon vollständig registriert: {var.waitingMemberCount}\n\nBewichtelungsarten:\nAls Wichtelpate: {var.analogueGiverCount} mal analog, {var.digitalGiverCount} mal digital, {var.allGiverCount} mal beides\nAls Wichtelkind: {var.analogueTakerCount} mal analog, {var.digitalTakerCount} mal digital, {var.allTakerCount} mal beides\n\nPakete: {var.parcelSentCount} versendet, {var.parcelReceivedCount} erhalten",
+    "moderationStatusEventPhase": "{var.currentEventPhase}",
+    "moderationStatusEventPhaseWithNextPhase": "{var.currentEventPhase} ({var.nextEventPhase} startet am {date.day}.{date.month}.{date.year} um {date.hour}:{date.minute} Uhr)",
     "modsCalled": "Keine Sorge! Hilfe ist unterwegs! (So schnell sie kann...)",
     "profileName": "Name",
     "profileGiftType": "Bewichtelungsart",
@@ -49,5 +53,7 @@
     "registrationCancelled": "Schade! Wenn du es dir anders überlegen solltest, schreibe einfach „registrieren“, um den Anmeldevorgang erneut zu starten.",
     "registrationProfileOverview": "Hier noch einen Überblick über deinen aktuellen Steckbrief:",
     "sentComponentText": "Klicken! Du sollst klicken!",
-    "sternenrose": "Vielen Dank, Sterni! :)"
+    "sternenrose": "Vielen Dank, Sterni! :)",
+    "thankYouResponse": "Bitte!",
+    "yourAreWelcomeRespone": "🙂"
 }
diff --git a/locale/de-DE.values.json b/locale/de-DE.values.json
index c8ec56629af88bbd90ed91eaa6f63269b90182f5..c0aa406b6c6672027c5015161dbabebbed36a296 100644
--- a/locale/de-DE.values.json
+++ b/locale/de-DE.values.json
@@ -4,5 +4,9 @@
     "giftTypeAll": "beides",
     "giftTypeNothing": "nichts",
     "no": "nein",
-    "yes": "ja"
-}
\ No newline at end of file
+    "yes": "ja",
+    "wichtelEventPhaseEnded": "Postwichteln",
+    "wichtelEventPhaseRegistration": "Registrierung",
+    "wichtelEventPhaseWaiting": "Präwichteln",
+    "wichtelEventPhaseWichteln": "Wichteln"
+}
diff --git a/scripts/utility/localisation.ts b/scripts/utility/localisation.ts
index a7eacd6d590fb692f9fac8a4d2f78197305b61d8..6a5c812e0442ca062b82e58d27bce9064ad1f662 100644
--- a/scripts/utility/localisation.ts
+++ b/scripts/utility/localisation.ts
@@ -3,6 +3,7 @@ import * as fs from 'fs';
 import Config from './config';
 import GiftType from '../wichtelbot/types/giftType';
 import TokenString from './tokenString';
+import WichtelEventPhase from './wichtelEvent';
 
 export interface CommandInfo
 {
@@ -17,6 +18,7 @@ interface Commands
     contacting: CommandInfo;
     deregistration: CommandInfo;
     goodAfternoon: CommandInfo;
+    goodEvening: CommandInfo;
     goodMorning: CommandInfo;
     goodNight: CommandInfo;
     hello: CommandInfo;
@@ -25,10 +27,13 @@ interface Commands
     informationBothAnalogueAndDigital: CommandInfo;
     informationDigital: CommandInfo;
     maybe: CommandInfo;
+    moddingStatus: CommandInfo;
     no: CommandInfo;
     registration: CommandInfo;
     sternenrose: CommandInfo;
+    thankYou: CommandInfo;
     yes: CommandInfo;
+    yourAreWelcome: CommandInfo;
 }
 
 // TODO: Documentation
@@ -49,6 +54,7 @@ interface Texts
     deregistration: TokenString;
     deregistrationCancelled: TokenString;
     goodAfternoon: TokenString;
+    goodEvening: TokenString;
     goodMorning: TokenString;
     goodNight: TokenString;
     hello: TokenString;
@@ -70,6 +76,9 @@ interface Texts
     notUnderstood: TokenString;
     oldInformation: TokenString;
     moderationNeedHelp: TokenString; // TODO: This includes a Discord specific mention which is not portable to other implementations.
+    moderationStatus: TokenString;
+    moderationStatusEventPhase: TokenString;
+    moderationStatusEventPhaseWithNextPhase: TokenString;
     modsCalled: TokenString;
     profileName: TokenString;
     profileGiftType: TokenString;
@@ -85,6 +94,8 @@ interface Texts
     registrationProfileOverview: TokenString;
     sentComponentText: TokenString;
     sternenrose: TokenString;
+    thankYouResponse: TokenString;
+    yourAreWelcomeRespone: TokenString;
 }
 
 interface Values
@@ -95,6 +106,10 @@ interface Values
     giftTypeNothing: string;
     no: string;
     yes: string;
+    wichtelEventPhaseEnded: string,
+    wichtelEventPhaseRegistration: string,
+    wichtelEventPhaseWaiting: string,
+    wichtelEventPhaseWichteln: string,
 }
 
 export default abstract class Localisation
@@ -148,27 +163,19 @@ export default abstract class Localisation
 
     public static translateGiftType (giftType: GiftType): string
     {
-        let result = '';
-
         switch (giftType)
         {
             case GiftType.Analogue:
-                result = Localisation._values.giftTypeAnalogue;
-                break;
+                return Localisation._values.giftTypeAnalogue;
             case GiftType.Digital:
-                result = Localisation._values.giftTypeDigital;
-                break;
+                return Localisation._values.giftTypeDigital;
             case GiftType.All:
-                result = Localisation._values.giftTypeAll;
-                break;
+                return Localisation._values.giftTypeAll;
             case GiftType.Nothing:
-                result = Localisation._values.giftTypeNothing;
-                break;
+                return Localisation._values.giftTypeNothing;
             default:
                 throw TypeError('Invalid gift type to translate.');
         }
-
-        return result;
     }
 
     public static translateCountry (country: string): string
@@ -180,4 +187,21 @@ export default abstract class Localisation
 
         return localisedCountry;
     }
+
+    public static translateWichtelEventPhase (eventPhase: WichtelEventPhase): string
+    {
+        switch (eventPhase)
+        {
+            case WichtelEventPhase.Waiting:
+                return Localisation._values.wichtelEventPhaseWaiting;
+            case WichtelEventPhase.Registration:
+                return Localisation._values.wichtelEventPhaseRegistration;
+            case WichtelEventPhase.Wichteln:
+                return Localisation._values.wichtelEventPhaseWichteln;
+            case WichtelEventPhase.Ended:
+                return Localisation._values.wichtelEventPhaseEnded;
+            default:
+                throw TypeError('Invalid event phase to translate.');
+        }
+    }
 }
diff --git a/scripts/utility/utils.ts b/scripts/utility/utils.ts
index 9a94e34a5fcfbd25ce51238f416d8ea6b26229ee..097217b0186c566d2c5f75108d2dbe5937bdce5c 100644
--- a/scripts/utility/utils.ts
+++ b/scripts/utility/utils.ts
@@ -1,3 +1,12 @@
+interface DateStrings
+{
+    year: string;
+    month: string;
+    day: string;
+    hour: string;
+    minute: string;
+}
+
 export default abstract class Utils
 {
     private static readonly defaultMaxWordLength = 100;
@@ -7,6 +16,17 @@ export default abstract class Utils
         return Math.floor(new Date().getTime() / 1000);
     }
 
+    public static dateToDateStrings (unixTime: Date): DateStrings
+    {
+        return {
+            'year': unixTime.getFullYear().toString(),
+            'month': (unixTime.getMonth() + 1).toString(),
+            'day': unixTime.getDate().toString(),
+            'hour': unixTime.getHours().toString(),
+            'minute': unixTime.getMinutes().toString().padStart(2, '0'),
+        };
+    }
+
     /**
      * Split text naturally between words if possible and removing unnecessary whitespaces at the break points.
      * @param text The text to split.
diff --git a/scripts/wichtelbot/database/database.ts b/scripts/wichtelbot/database/database.ts
index c417075cfb113b3d68b3f6a6785b8f073e139eb8..e69178b90ee37670f6e743727f998008e9460568 100644
--- a/scripts/wichtelbot/database/database.ts
+++ b/scripts/wichtelbot/database/database.ts
@@ -4,8 +4,12 @@ import { Exclusion, ExclusionData } from '../classes/exclusion';
 import { Relationship, RelationshipData } from '../classes/relationship';
 import Config from '../../utility/config';
 import ContactType from '../types/contactType';
+import GiftType from '../types/giftType';
+import { GiftTypeStatistics } from './giftTypeStatistics';
 import { InformationData } from '../classes/information';
 import Member from '../classes/member';
+import { ParcelStatistics } from './parcelStatistics';
+import { State } from '../endpoint/definitions';
 import Utils from '../../utility/utils';
 import Sqlite = require('better-sqlite3');
 
@@ -167,6 +171,18 @@ export default class Database
         return result;
     }
 
+    /**
+     * Runs the given statement with the given parameters and returns the result as a number.
+     */
+    private getCount (statement: Sqlite.Statement, parameters: unknown): number
+    {
+        statement.pluck(true);
+
+        const count = statement.get(parameters) as number;
+
+        return count;
+    }
+
     public hasContact (contactId: string): boolean
     {
         const statement = this.mainDatabase.prepare(
@@ -249,6 +265,15 @@ export default class Database
         );
     }
 
+    public getContactCount (): number
+    {
+        const statement = this.mainDatabase.prepare(
+            'SELECT COUNT(*) FROM contact WHERE contact.state != ?'
+        );
+
+        return this.getCount(statement, State.Nothing); // All contacts in this event phase have a state not equal to "Nothing".
+    }
+
     /**
      * Will check if there is information in the database.
      * @param contactId The ID of the contact the information must be linked to.
@@ -270,9 +295,7 @@ export default class Database
         // this makes it much easier:
         statement.pluck(true);
 
-        let result = !!statement.get(contactId);
-
-        result = !!result; // Makes sure the value is definitely a boolean.
+        const result = !!statement.get(contactId); // Make sure the value is definitely a boolean.
 
         return result;
     }
@@ -403,6 +426,15 @@ export default class Database
         runTransaction();
     }
 
+    public getWaitingMemberCount (): number
+    {
+        const statement = this.mainDatabase.prepare(
+            'SELECT COUNT(*) FROM contact WHERE contact.state = ?'
+        );
+
+        return this.getCount(statement, State.Waiting);
+    }
+
     /**
      * Will return the type of contact that can be found for this ID. \
      * If no contact is found, the given contactCoreData will be returned instead.
@@ -546,6 +578,55 @@ export default class Database
             statement.run(parameters);
         }
     }
+
+    public getGiftTypeStatistics (): GiftTypeStatistics
+    {
+        const statement = this.mainDatabase.prepare(
+            `SELECT
+                COUNT(CASE WHEN information.giftTypeAsGiver = :analogueGiftType THEN 1 END) AS analogueGiverCount,
+                COUNT(CASE WHEN information.giftTypeAsGiver = :digitalGiftType THEN 1 END) AS digitalGiverCount,
+                COUNT(CASE WHEN information.giftTypeAsGiver = :allGiftType THEN 1 END) AS allGiverCount,
+                COUNT(CASE WHEN information.giftTypeAsTaker = :analogueGiftType THEN 1 END) AS analogueTakerCount,
+                COUNT(CASE WHEN information.giftTypeAsTaker = :digitalGiftType THEN 1 END) AS digitalTakerCount,
+                COUNT(CASE WHEN information.giftTypeAsTaker = :allGiftType THEN 1 END) AS allTakerCount
+            FROM
+                information
+            LEFT JOIN
+                contact ON information.contactId = contact.id
+            WHERE
+                information.lastUpdateTime >= :currentEventRegistrationTime
+                AND contact.state = :waitingState`
+        );
+
+        const result = statement.get(
+            {
+                analogueGiftType: GiftType.Analogue,
+                digitalGiftType: GiftType.Digital,
+                allGiftType: GiftType.All,
+                currentEventRegistrationTime: Config.main.currentEvent.registration,
+                waitingState: State.Waiting,
+            }
+        ) as GiftTypeStatistics;
+
+        return result;
+    }
+
+    public getParcelStatistics (): ParcelStatistics
+    {
+        const statement = this.mainDatabase.prepare(
+            `SELECT
+                COUNT(CASE WHEN shippingDate != '' THEN 1 END) AS sentCount,
+                COUNT(CASE WHEN receivingDate != '' THEN 1 END) AS receivedCount
+            FROM
+                parcel
+            WHERE
+                wichtelEvent = ?`
+        );
+
+        const result = statement.get(Config.main.currentEvent.name) as ParcelStatistics;
+
+        return result;
+    }
 }
 
 /*
diff --git a/scripts/wichtelbot/database/giftTypeStatistics.ts b/scripts/wichtelbot/database/giftTypeStatistics.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c1a3f0e0e209ba0f0f1a456d4efc4edc4972dac6
--- /dev/null
+++ b/scripts/wichtelbot/database/giftTypeStatistics.ts
@@ -0,0 +1,9 @@
+export interface GiftTypeStatistics
+{
+    analogueGiverCount: number;
+    digitalGiverCount: number;
+    allGiverCount: number;
+    analogueTakerCount: number;
+    digitalTakerCount: number;
+    allTakerCount: number;
+}
diff --git a/scripts/wichtelbot/database/parcelStatistics.ts b/scripts/wichtelbot/database/parcelStatistics.ts
new file mode 100644
index 0000000000000000000000000000000000000000..52c3fa98700ed96cf27a0245fcf81622942c2101
--- /dev/null
+++ b/scripts/wichtelbot/database/parcelStatistics.ts
@@ -0,0 +1,5 @@
+export interface ParcelStatistics
+{
+    sentCount: number;
+    receivedCount: number;
+}
diff --git a/scripts/wichtelbot/endpoint/definitions/state.ts b/scripts/wichtelbot/endpoint/definitions/state.ts
index a03d151561390eef6323c8e395b1188c34bebd9c..9f4db0ab08504923b9f24415fbbad6c7f9a6cbf6 100644
--- a/scripts/wichtelbot/endpoint/definitions/state.ts
+++ b/scripts/wichtelbot/endpoint/definitions/state.ts
@@ -1,7 +1,7 @@
 enum State
 {
     // As contact:
-    Nothing = '', // Is allowed to do nothing but stateless commands.
+    Nothing = 'nothing', // Is allowed to do nothing but stateless commands.
     New = 'new',
     Registration = 'registration',
     // As contact/member:
diff --git a/scripts/wichtelbot/message/handlingDefinition.ts b/scripts/wichtelbot/message/handlingDefinition.ts
index fef9e9347e368950b42330c3acd7be7b54be41df..76b857e67bdbc3b743be6f9b5f5a2ae372aab509 100644
--- a/scripts/wichtelbot/message/handlingDefinition.ts
+++ b/scripts/wichtelbot/message/handlingDefinition.ts
@@ -6,6 +6,7 @@ import GeneralModule from './modules/generalModule';
 import GiftType from '../types/giftType';
 import InformationModule from './modules/informationModule';
 import Message from '../endpoint/definitions/message';
+import { ModerationModule } from './modules/moderationModule';
 import State from "../endpoint/definitions/state";
 import TokenString from '../../utility/tokenString';
 
@@ -49,16 +50,18 @@ export default class HandlingDefinition
 {
     protected generalModule: GeneralModule;
     protected informationModule: InformationModule;
+    protected moderationModule: ModerationModule;
 
     private get maxShortMessageLength (): number
     {
         return Math.floor(Config.main.maxMessageLength / 2);
     }
 
-    constructor (generalModule: GeneralModule, informationModule: InformationModule)
+    constructor (generalModule: GeneralModule, informationModule: InformationModule, moderationModule: ModerationModule)
     {
         this.generalModule = generalModule;
         this.informationModule = informationModule;
+        this.moderationModule = moderationModule;
     }
 
     public stateCommands: StateCommandDefinition[] = [
@@ -72,13 +75,21 @@ export default class HandlingDefinition
                     result: Localisation.texts.modsCalled,
                 },
                 {
-                    command: Localisation.commands.goodAfternoon,
-                    result: Localisation.texts.goodAfternoon,
+                    command: Localisation.commands.sternenrose,
+                    result: Localisation.texts.sternenrose,
                 },
                 {
                     command: Localisation.commands.goodMorning,
                     result: Localisation.texts.goodMorning,
                 },
+                {
+                    command: Localisation.commands.goodAfternoon,
+                    result: Localisation.texts.goodAfternoon,
+                },
+                {
+                    command: Localisation.commands.goodEvening,
+                    result: Localisation.texts.goodEvening,
+                },
                 {
                     command: Localisation.commands.goodNight,
                     result: Localisation.texts.goodNight,
@@ -92,10 +103,13 @@ export default class HandlingDefinition
                     result: Localisation.texts.maybeResponse,
                 },
                 {
-                    command: Localisation.commands.sternenrose,
-                    result: Localisation.texts.sternenrose,
+                    command: Localisation.commands.thankYou,
+                    result: Localisation.texts.thankYouResponse,
+                },
+                {
+                    command: Localisation.commands.yourAreWelcome,
+                    result: Localisation.texts.yourAreWelcomeRespone,
                 }
-                // TODO: Response to "thank you".
             ],
             handlerFunction: async (message: Message, result: TokenString): Promise<void> =>
             {
@@ -476,6 +490,9 @@ export default class HandlingDefinition
     ];
 
     public moderatorCommands: CommandDefinition[] = [
-
+        {
+            commandInfo: Localisation.commands.moddingStatus,
+            handlerFunction: async (message: Message): Promise<void> => this.moderationModule.sendStatus(message)
+        }
     ];
 }
diff --git a/scripts/wichtelbot/message/messageHandler.ts b/scripts/wichtelbot/message/messageHandler.ts
index 0cd6a9c539c2a2af3cde50c669f14daed0a1f6f0..41574479aa0e1a2ee0e4f9c95ed048d99c96c38f 100644
--- a/scripts/wichtelbot/message/messageHandler.ts
+++ b/scripts/wichtelbot/message/messageHandler.ts
@@ -6,6 +6,7 @@ import Database from '../database/database';
 import GeneralModule from './modules/generalModule';
 import HandlingDefinition from './handlingDefinition';
 import InformationModule from './modules/informationModule';
+import { ModerationModule } from './modules/moderationModule';
 import StateCommand from './handlingTools/stateCommand';
 import StateCommandMap from './handlingTools/stateCommandMap';
 
@@ -29,6 +30,7 @@ export default class MessageHandler
 
     protected generalModule: GeneralModule;
     protected informationModule: InformationModule;
+    protected moderationModule: ModerationModule;
 
     // In private messages:
     protected stateCommands = new StateCommandMap();
@@ -56,8 +58,9 @@ export default class MessageHandler
 
         this.generalModule = new GeneralModule(database);
         this.informationModule = new InformationModule(database);
+        this.moderationModule = new ModerationModule(database);
 
-        this.handlingDefinition = new HandlingDefinition(this.generalModule, this.informationModule);
+        this.handlingDefinition = new HandlingDefinition(this.generalModule, this.informationModule, this.moderationModule);
 
         this.applyHandlingDefinition();
     }
diff --git a/scripts/wichtelbot/message/modules/generalModule.ts b/scripts/wichtelbot/message/modules/generalModule.ts
index a28942dfd4c27e64ed2ed62c43d13d5a7c632d07..f851f05e22173ad7fc27c661e7e0e3bc2f564afc 100644
--- a/scripts/wichtelbot/message/modules/generalModule.ts
+++ b/scripts/wichtelbot/message/modules/generalModule.ts
@@ -9,6 +9,7 @@ import Member from '../../classes/member';
 import Message from '../../endpoint/definitions/message';
 import State from '../../endpoint/definitions/state';
 import TokenString from '../../../utility/tokenString';
+import Utils from '../../../utility/utils';
 import WichtelEventPhase from '../../../utility/wichtelEvent';
 
 /**
@@ -69,12 +70,14 @@ export default class GeneralModule
 
             const registrationPhaseTime = new Date(nowInMs + randomAdditionInMs);
 
+            const registrationDateStrings = Utils.dateToDateStrings(registrationPhaseTime);
+
             const parameters = new KeyValuePairList();
-            parameters.addPair('year', registrationPhaseTime.getFullYear().toString());
-            parameters.addPair('month', (registrationPhaseTime.getMonth() + 1).toString());
-            parameters.addPair('day', registrationPhaseTime.getDate().toString());
-            parameters.addPair('hour', registrationPhaseTime.getHours().toString());
-            parameters.addPair('minute', registrationPhaseTime.getMinutes().toString().padStart(2, '0'));
+            parameters.addPair('year', registrationDateStrings.year);
+            parameters.addPair('month', registrationDateStrings.month);
+            parameters.addPair('day', registrationDateStrings.day);
+            parameters.addPair('hour', registrationDateStrings.hour);
+            parameters.addPair('minute', registrationDateStrings.minute);
 
             answer = Localisation.texts.contactingTooEarly.process(message.author, parameters);
         }
diff --git a/scripts/wichtelbot/message/modules/moderationModule.ts b/scripts/wichtelbot/message/modules/moderationModule.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bd0367f1a19c9a898dfc0b556f11e2ecd0612dc1
--- /dev/null
+++ b/scripts/wichtelbot/message/modules/moderationModule.ts
@@ -0,0 +1,93 @@
+import Config from "../../../utility/config";
+import Database from "../../database/database";
+import { KeyValuePairList } from "../../../utility/keyValuePair";
+import Localisation from "../../../utility/localisation";
+import { Message } from "../../endpoint/definitions";
+import Utils from "../../../utility/utils";
+import WichtelEventPhase from "../../../utility/wichtelEvent";
+
+export class ModerationModule
+{
+    protected database: Database;
+
+    constructor (database: Database)
+    {
+        this.database = database;
+    }
+
+    public async sendStatus (message: Message): Promise<void>
+    {
+        // TODO: This could be improved with visualisations.
+
+        const currentEventPhase = Localisation.translateWichtelEventPhase(Config.currentEventPhase);
+
+        let nextEventPhase: WichtelEventPhase|null = null;
+        let nextEventPhaseUnixTime: number|null = null;
+
+        switch (Config.currentEventPhase)
+        {
+            case WichtelEventPhase.Waiting:
+                nextEventPhase = WichtelEventPhase.Registration;
+                nextEventPhaseUnixTime = Config.main.currentEvent.registration;
+                break;
+            case WichtelEventPhase.Registration:
+                nextEventPhase = WichtelEventPhase.Wichteln;
+                nextEventPhaseUnixTime = Config.main.currentEvent.assignment;
+                break;
+            case WichtelEventPhase.Wichteln:
+                nextEventPhase = WichtelEventPhase.Ended;
+                nextEventPhaseUnixTime = Config.main.currentEvent.end;
+                break;
+            case WichtelEventPhase.Ended:
+                // No next phase
+                break;
+        }
+
+        let eventPhaseString: string;
+
+        if ((nextEventPhase === null) || (nextEventPhaseUnixTime === null))
+        {
+            const parameters = new KeyValuePairList('currentEventPhase', currentEventPhase);
+
+            eventPhaseString = Localisation.texts.moderationStatusEventPhase.process(message.author, parameters);
+        }
+        else
+        {
+            const parameters = new KeyValuePairList();
+            parameters.addPair('currentEventPhase', currentEventPhase);
+            parameters.addPair('nextEventPhase', Localisation.translateWichtelEventPhase(nextEventPhase));
+
+            const registrationDateStrings = Utils.dateToDateStrings(new Date(nextEventPhaseUnixTime * 1000));
+            parameters.addPair('year', registrationDateStrings.year);
+            parameters.addPair('month', registrationDateStrings.month);
+            parameters.addPair('day', registrationDateStrings.day);
+            parameters.addPair('hour', registrationDateStrings.hour);
+            parameters.addPair('minute', registrationDateStrings.minute);
+
+            eventPhaseString = Localisation.texts.moderationStatusEventPhaseWithNextPhase.process(message.author, parameters);
+        }
+
+        const contactCount = this.database.getContactCount();
+        const waitingMemberCount = this.database.getWaitingMemberCount();
+        const giftTypeStatistics = this.database.getGiftTypeStatistics();
+        const parcelStatistics = this.database.getParcelStatistics();
+
+        const parameters = new KeyValuePairList();
+        parameters.addPair('currentEventName', Config.main.currentEvent.name);
+        parameters.addPair('eventPhaseString', eventPhaseString);
+        parameters.addPair('contactCount', `${contactCount}`);
+        parameters.addPair('waitingMemberCount', `${waitingMemberCount}`);
+        parameters.addPair('analogueGiverCount', `${giftTypeStatistics.analogueGiverCount}`);
+        parameters.addPair('digitalGiverCount', `${giftTypeStatistics.digitalGiverCount}`);
+        parameters.addPair('allGiverCount', `${giftTypeStatistics.allGiverCount}`);
+        parameters.addPair('analogueTakerCount', `${giftTypeStatistics.analogueTakerCount}`);
+        parameters.addPair('digitalTakerCount', `${giftTypeStatistics.digitalTakerCount}`);
+        parameters.addPair('allTakerCount', `${giftTypeStatistics.allTakerCount}`);
+        parameters.addPair('parcelSentCount', `${parcelStatistics.sentCount}`);
+        parameters.addPair('parcelReceivedCount', `${parcelStatistics.receivedCount}`);
+
+        const answer = Localisation.texts.moderationStatus.process(message.author, parameters);
+
+        await message.reply(answer);
+    }
+}
diff --git a/tests/tests/utility.tokenString.ts b/tests/tests/utility.tokenString.ts
index 52286738ce0b6ea86f2a32aa794648d7ce9bd594..c31918639ca5ade831f795e6bd7dd7b9e600985e 100644
--- a/tests/tests/utility.tokenString.ts
+++ b/tests/tests/utility.tokenString.ts
@@ -1,11 +1,10 @@
 import 'mocha';
 import { assert } from 'chai';
-
+import Config from '../../scripts/utility/config';
 import ContactTestUtility from '../utility/contact';
 import { KeyValuePairList } from '../../scripts/utility/keyValuePair';
 import Localisation from '../../scripts/utility/localisation';
 import TokenString from '../../scripts/utility/tokenString';
-import Config from '../../scripts/utility/config';
 
 describe('tokenString',
     function ()
diff --git a/tests/tests/wichtelbot.endpoint.implementations.discord.ts b/tests/tests/wichtelbot.endpoint.implementations.discord.ts
index dff140404bec90693cbcf8a81abe9f5488a54a88..220e61da07c25125bde816e5db52b05355f14b89 100644
--- a/tests/tests/wichtelbot.endpoint.implementations.discord.ts
+++ b/tests/tests/wichtelbot.endpoint.implementations.discord.ts
@@ -4,7 +4,6 @@ import * as DiscordEndpoint from '../../scripts/wichtelbot/endpoint/implementati
 import * as mockito from 'ts-mockito';
 import { assert } from 'chai';
 import { ChannelType } from '../../scripts/wichtelbot/endpoint/definitions';
-import GeneralTestUtility from '../utility/general';
 
 describe('discord client',
     function ()
diff --git a/tests/utility/message.ts b/tests/utility/message.ts
index bcd44b1e384239fbb487107f9b36c0d28e8d78fb..38cec7817db37481f413da101a84fa4bff373399 100644
--- a/tests/utility/message.ts
+++ b/tests/utility/message.ts
@@ -1,4 +1,3 @@
-
 import { Channel, ChannelType, Client, Component, Message, State, User } from '../../scripts/wichtelbot/endpoint/definitions';
 import Contact from '../../scripts/wichtelbot/classes/contact';
 import Database from '../../scripts/wichtelbot/database/database';