diff --git a/src/lib/notifications/notificationTypes.ts b/src/lib/notifications/notificationTypes.ts
index 56d95d95fc9ac8acea0cf938c7753998a7be799e..4e5dad176731a8599938f4047f353aa98cfe30da 100644
--- a/src/lib/notifications/notificationTypes.ts
+++ b/src/lib/notifications/notificationTypes.ts
@@ -8,4 +8,5 @@ export const NotificationType = {
 	USE_VOUCHER: {key: 1<<4, name: "use-voucher"} as Type<"use-voucher">,
 	SEND_TRANSFER: {key: 1<<5, name: "send-transfer"} as Type<"send-transfer">,
 	RECEIVE_TRANSFER: {key: 1<<6, name: "receive-transfer"} as Type<"receive-transfer">,
+	NEWS: {key: 1<<7, name: "news"} as Type<"news">,
 };
diff --git a/src/lib/notifications/types.ts b/src/lib/notifications/types.ts
index 9fb6607ad6ede62ed4ad6c8e29bfdc3f5e9bdbc7..66c31aaff19c5a27d3891193b92230aa91d740e1 100644
--- a/src/lib/notifications/types.ts
+++ b/src/lib/notifications/types.ts
@@ -1,4 +1,4 @@
-export type PossibleNotificationType = "buy" | "refund" | "deposit" | "withdraw" | "use-voucher" | "send-transfer" | "receive-transfer";
+export type PossibleNotificationType = "buy" | "refund" | "deposit" | "withdraw" | "use-voucher" | "send-transfer" | "receive-transfer" | "news";
 
 export type Item = {name: string, code: string, price: number, premium: number|undefined};
 export type User = {name: string, id: number}
@@ -11,6 +11,7 @@ export type WithdrawNotificationData = {amount: number, balanceBefore: number, b
 export type UseVoucherNotificationData = {voucher: {code: string, value: number}, balanceBefore: number, balanceAfter: number};
 export type SendTransferNotificationData = {amount: number, receiver: User, balanceBefore: number, balanceAfter: number};
 export type ReceiveTransferNotificationData = {amount: number, sender: User, balanceBefore: number, balanceAfter: number};
+export type NewsNotificationData = {title: string, textVersion: string, htmlVersion: string};
 export type NotificationData<T extends PossibleNotificationType> =
     T extends "buy" ? BuyNotificationData :
     T extends "refund" ? RefundNotificationData :
@@ -19,6 +20,7 @@ export type NotificationData<T extends PossibleNotificationType> =
     T extends "use-voucher" ? UseVoucherNotificationData :
     T extends "send-transfer" ? SendTransferNotificationData :
     T extends "receive-transfer" ? ReceiveTransferNotificationData :
+    T extends "news" ? NewsNotificationData :
     never;
 
 export type HandlerReturnSuccess = {status: "success"};
diff --git a/src/lib/server/notifications/formatter.ts b/src/lib/server/notifications/formatter.ts
index 24fbfc974c245a956be24f33cac0d017649b2a7c..f001541779231fbfc521a5bd9c1c1f24b4b2fb35 100644
--- a/src/lib/server/notifications/formatter.ts
+++ b/src/lib/server/notifications/formatter.ts
@@ -23,6 +23,9 @@ export function getMessageTitle<T extends PossibleNotificationType>(type: Notifi
 		case "receive-transfer": {
 			return "Überweisung erhalten";
 		}
+		case "news": {
+			return "Neu bei der Getränkekasse";
+		}
 		default: {
 			console.error(`Unknown notification type`, type);
 			return `Unknown notification type ${type}`;
@@ -70,6 +73,9 @@ Dein neuer Kontostand beträgt ${(balanceAfter/100).toFixed(2)}€.`;
 			return `Du hast ${(amount/100).toFixed(2)}€ von ${sender.name} erhalten.
 Dein neuer Kontostand beträgt ${(balanceAfter/100).toFixed(2)}€.`;
 		}
+		case "news": {
+			return (data as NotificationData<"news">).textVersion;
+		}
 		default: {
 			console.error(`Unknown notification type`, type);
 			return `Unknown notification type ${type}`;
@@ -118,6 +124,9 @@ export function formatMessageToHtml<T extends PossibleNotificationType>(type: No
 			return `<p>Du hast ${(amount / 100).toFixed(2)}€ von ${escapeHtml(sender.name)} erhalten.</p>
 <p>Dein neuer Kontostand beträgt ${(balanceAfter / 100).toFixed(2)}€.</p>`;
 		}
+		case "news": {
+			return (data as NotificationData<"news">).htmlVersion;
+		}
 		default: {
 			console.error(`Unknown notification type`, type);
 			return `Unknown notification type ${escapeHtml(JSON.stringify(type))}`;
diff --git a/src/lib/server/notifications/handler.ts b/src/lib/server/notifications/handler.ts
index 830b6c6e53adc6555b6d1f4da6514946b911e8b5..bbdfd4773223c4c6bb7a3ebff8f761da37828d7e 100644
--- a/src/lib/server/notifications/handler.ts
+++ b/src/lib/server/notifications/handler.ts
@@ -2,17 +2,21 @@ import { db } from "$lib/server/database";
 import { ChannelType } from "./channelTypes";
 import type { HandlerReturnError, HandlerReturnIgnored, HandlerReturnType, NotificationChannel, NotificationData, NotificationType, PossibleNotificationType } from "../../notifications/types";
 
-export async function sendNotification<T extends PossibleNotificationType>(user: { id: number, notificationChannels: NotificationChannel[] | undefined } | number, type: NotificationType<T>, data: NotificationData<T>): Promise<HandlerReturnType[]>{
+export async function sendNotification<T extends PossibleNotificationType>(user: { id: number, notificationChannels: NotificationChannel[] | undefined } | number | null, type: NotificationType<T>, data: NotificationData<T>): Promise<HandlerReturnType[]>{
 	let notificationChannels: NotificationChannel[];
-	let userId: number;
-	if(typeof user === "number"){
-		userId = user;
+	if(user === null){
+		notificationChannels = await getNotificationChannels(type.key);
 	}else{
-		userId = user.id;
-		notificationChannels = user.notificationChannels?.filter(channel => channel.notificationTypes & type.key);
-	}
-	if(!notificationChannels){
-		notificationChannels = await getNotificationChannels(userId, type.key);
+		let userId: number;
+		if(typeof user === "number"){
+			userId = user;
+		}else{
+			userId = user.id;
+			notificationChannels = user.notificationChannels?.filter(channel => channel.notificationTypes & type.key);
+		}
+		if(!notificationChannels){
+			notificationChannels = await getNotificationChannels(userId, type.key);
+		}
 	}
 	return Promise.all(notificationChannels.map(channel => {
 		const channelType = Object.values(ChannelType).find(type => type.key === channel.channelType);
@@ -34,9 +38,17 @@ export async function sendNotification<T extends PossibleNotificationType>(user:
 	}));
 };
 
-async function getNotificationChannels(userId: number, notificationType: number): Promise<NotificationChannel[]> {
-	const allChannels = await db.notificationChannel.findMany({
-		where: { userId }
-	});
+function getNotificationChannels(userId: number, notificationType: number): Promise<NotificationChannel[]>;
+function getNotificationChannels(notificationType: number): Promise<NotificationChannel[]>
+async function getNotificationChannels(userId: number, notificationType?: number): Promise<NotificationChannel[]> {
+	let allChannels;
+	if(notificationType === undefined){
+		notificationType = userId;
+		allChannels = await db.notificationChannel.findMany();
+	}else{
+		allChannels = await db.notificationChannel.findMany({
+			where: { userId }
+		});
+	}
 	return allChannels.filter(channel => channel.notificationTypes & notificationType);
 }
diff --git a/src/routes/admin/mail/+page.server.ts b/src/routes/admin/mail/+page.server.ts
index bce0dc30c818ae0e808467bad44f549815f2ac01..0fa2364fe63ae6a9d6fe81092205f1efdf855854 100644
--- a/src/routes/admin/mail/+page.server.ts
+++ b/src/routes/admin/mail/+page.server.ts
@@ -2,6 +2,8 @@ import { error, type Actions } from "@sveltejs/kit";
 import { getUsers } from "../api/users";
 import { sendMail } from "$lib/server/mail";
 import { format } from "./formatter";
+import { sendNotification } from "$lib/server/notifications/handler";
+import { NotificationType } from "$lib/notifications/notificationTypes";
 
 export async function load(){
 	const users = await getUsers();
@@ -13,24 +15,34 @@ export const actions: Actions = {
 		const data = await event.request.formData();
 		const subject = data.get("subject");
 		const message = data.get("content");
-		const users = data.get("users");
-		if(typeof subject !== "string" || typeof message !== "string" || typeof users !== "string") throw error(400, "Invalid request");
-		const userIDs = users.split(",").map(id => parseInt(id));
-		const usersToSend = await getUsers(userIDs);
-		const result: {accepted: number[], rejected: number[], error: {userId: number, error: any}[]} = { accepted: [], rejected: [], error: [] };
-		for(const user of usersToSend){
-			const mail = format(subject, message, user);
-			try{
-				const r = await sendMail(mail);
-				if(r.accepted.length > 0) result.accepted.push(user.id);
-				else if(r.rejected.length > 0) result.rejected.push(user.id);
-			}catch(err){
-				result.error.push({
-					userId: user.id,
-					error: err
-				});
+		const type = data.get("type");
+		if(type === "mail"){
+			const users = data.get("users");
+			if(typeof subject !== "string" || typeof message !== "string" || typeof users !== "string") throw error(400, "Invalid request");
+			const userIDs = users.split(",").map(id => parseInt(id));
+			const usersToSend = await getUsers(userIDs);
+			const result: {accepted: number[], rejected: number[], error: {userId: number, error: any}[]} = { accepted: [], rejected: [], error: [] };
+			for(const user of usersToSend){
+				const mail = format(subject, message, user);
+				try{
+					const r = await sendMail(mail);
+					if(r.accepted.length > 0) result.accepted.push(user.id);
+					else if(r.rejected.length > 0) result.rejected.push(user.id);
+				}catch(err){
+					result.error.push({
+						userId: user.id,
+						error: err
+					});
+				}
 			}
+			return result;
+		}else if(type === "notification"){
+			if(typeof subject !== "string" || typeof message !== "string") throw error(400, "Invalid request");
+			const notification = format(subject, message);
+			sendNotification(null, NotificationType.NEWS, notification);
+			return { status: "success" };
+		}else{
+			throw error(400, "Invalid request");
 		}
-		return result;
 	}
 };
diff --git a/src/routes/admin/mail/+page.svelte b/src/routes/admin/mail/+page.svelte
index b1ea9f4c41049a14d21e33992b8c282ec4770706..a61f15280c82d875f23a9a2e386cd3dde543a169 100644
--- a/src/routes/admin/mail/+page.svelte
+++ b/src/routes/admin/mail/+page.svelte
@@ -7,15 +7,17 @@
 	export let data: {users: User[]};
 	
 	let subject = "", content = "";
+	let type: "mail"|"notification" = "mail";
 	let minBalance, maxBalance;
 	$: filter = (user: User) => {
+		if(type === "notification") return false;
 		if(minBalance != null && user.balance < minBalance) return false;
 		if(maxBalance != null && user.balance > maxBalance) return false;
 		return true;
 	};
 	$: matchedUsers = data.users.filter(filter);
 	$: exampleUser = matchedUsers[Math.floor(Math.random()*matchedUsers.length)];
-	$: preview = exampleUser ? format(subject, content, exampleUser) : null;
+	$: preview = format(subject, content, exampleUser);
 </script>
 
 <style>
@@ -32,43 +34,67 @@
 
 <a href="/admin">Zurück</a>
 
+<h2>Typ</h2>
+<select bind:value={type}>
+	<option value="mail">Mail</option>
+	<option value="notification">Benachrichtigung</option>
+</select>
+
+{#if type === "mail"}
 <h2>Empfänger</h2>
 <label>Minimales Guthaben: <input type="number" bind:value={minBalance} /></label><br>
 <label>Maximales Guthaben: <input type="number" bind:value={maxBalance} /></label><br>
+{/if}
 
 <h2>Mail</h2>
-<form method="post" action="?/send" use:enhance={({form, data, cancel})=>{
-	return async ({result})=>{
-		if(result.type === "success"){
-			const { rejected, accepted, error } = result.data;
-			if(error.length){
-				console.error("Error sending mails", error);
-				addMessage(MessageType.ERROR, "Fehler beim Senden der Mails an: " + error.map(e=>e.userId).join(", "));
-			}
-			if(rejected.length){
-				addMessage(MessageType.ERROR, "Mails konnten nicht an: " + rejected.map(e=>e.userId).join(", ") + " gesendet werden");
+<form method="post" action="?/send" use:enhance={({formElement, formData, cancel})=>{
+	if(type === "mail"){
+		return async ({result})=>{
+			if(result.type === "success"){
+				const { rejected, accepted, error } = result.data;
+				if(error.length){
+					console.error("Error sending mails", error);
+					addMessage(MessageType.ERROR, "Fehler beim Senden der Mails an: " + error.map(e=>e.userId).join(", "));
+				}
+				if(rejected.length){
+					addMessage(MessageType.ERROR, "Mails konnten nicht an: " + rejected.map(e=>e.userId).join(", ") + " gesendet werden");
+				}
+				if(accepted.length){
+					addMessage(MessageType.SUCCESS, "Mails erfolgreich an " + accepted.length + " Nutzer gesendet");
+				}
 			}
-			if(accepted.length){
-				addMessage(MessageType.SUCCESS, "Mails erfolgreich an " + accepted.length + " Nutzer gesendet");
+		};
+	}else{
+		return async ({result})=>{
+			if(result.type === "success"){
+				addMessage(MessageType.SUCCESS, "Benachrichtigung erfolgreich versendet");
+			}else{
+				addMessage(MessageType.ERROR, "Benachrichtigung konnte nicht versendet werden");
+				console.error(result);
 			}
-		}
-	};
+		};
+	}
 }}>
 	<input type="text" name="subject" placeholder="Betreff" bind:value={subject} required /><br>
 	<textarea name="content" placeholder="Inhalt" bind:value={content} required></textarea><br>
+	<input type="hidden" name="type" value={type} />
+	{#if type === "mail"}
 	<input type="hidden" name="users" value={matchedUsers.map(u=>u.id).join(",")} />
+	{/if}
 	<button type="submit">Senden</button>
 </form>
 
 <h2>Vorschau</h2>
-{#if preview}
+{#if type==="mail" && !matchedUsers.length}
+<p class="preview">Die Mail wird an keinen Nutzer gesendet</p>
+{:else}
 <div class="preview">
+	{#if type === "mail"}
 	<p><b>An: </b>{matchedUsers.map(u=>u.email).join(", ")}</p>
-	<h3>{preview.subject}</h3>
+	{/if}
+	<h3>{type === "mail" ? preview.subject : preview.title}</h3>
 	<div>
-		{@html preview.html}
+		{@html type === "mail" ? preview.html : preview.htmlVersion}
 	</div>
 </div>
-{:else}
-<p class="preview">Die Mail wird an keinen Nutzer gesendet</p>
 {/if}
diff --git a/src/routes/admin/mail/formatter.ts b/src/routes/admin/mail/formatter.ts
index 45b15c5d13a86a6c7686c292cfa8402cd43d618b..6605af5b3cbee224c4cc2e4a93eef5e85e78a642 100644
--- a/src/routes/admin/mail/formatter.ts
+++ b/src/routes/admin/mail/formatter.ts
@@ -3,6 +3,7 @@ import MarkdownItHighlight from "markdown-it-highlightjs";
 import hljs from "highlight.js";
 import hljsCSS from "highlight.js/styles/github.css?inline";
 import type { User } from "@prisma/client";
+import type { NewsNotificationData } from "$lib/notifications/types";
 
 const md = new MarkdownIt({
 	breaks: true,
@@ -16,6 +17,7 @@ const md = new MarkdownIt({
 	hljs
 });
 md.core.ruler.push("replacePlaceholders", state=>{
+	if(!state.env.user) return;
 	for(const token of state.tokens){
 		handleToken(token, state.env.user);
 	}
@@ -40,15 +42,27 @@ type Mail = {
 	html: string
 };
 
-export function format(subject: string, content: string, user: User): Mail {
-	const html = md.render(content, {user});
-	const css = html.includes("hljs") ? `<style>${hljsCSS}</style>` : "";
-	return {
-		to: { name: user.name, address: user.email },
-		subject: replacePlaceholders(subject, user),
-		text: replacePlaceholders(content, user),
-		html: css + html
-	};
+export function format(subject: string, content: string, user: User): Mail;
+export function format(subject: string, content: string): NewsNotificationData;
+export function format(subject: string, content: string, user?: User) {
+	if(user){
+		const html = md.render(content, {user});
+		const css = html.includes("hljs") ? `<style>${hljsCSS}</style>` : "";
+		return {
+			to: { name: user.name, address: user.email },
+			subject: replacePlaceholders(subject, user),
+			text: replacePlaceholders(content, user),
+			html: css + html
+		};
+	}else{
+		const html = md.render(content);
+		const css = html.includes("hljs") ? `<style>${hljsCSS}</style>` : "";
+		return {
+			title: subject,
+			textVersion: content,
+			htmlVersion: css + html
+		};
+	}
 }
 
 function replacePlaceholders(content: string, user: User): string {