feat: add Matrix chat notification support (#211)
Implements native Matrix notification channel support, allowing users to receive service alerts in any Matrix room via the Client-Server API. Changes: - server/service-operation/notification/matrix.go: new Matrix service implementing the NotificationService interface (PUT /_matrix/client/v3/...) - server/service-operation/notification/types.go: add MatrixHomeserver, MatrixRoomID, MatrixAccessToken fields to AlertConfiguration - server/service-operation/notification/manager.go: register MatrixService - server/pb_migrations/1772200000_updated_alert_configurations_matrix.js: PocketBase migration adding matrix fields and notification_type value - application: Matrix option in channel dialog with homeserver/room/token fields, tab filter, list display, type definitions and translations (en, km) - application/public/upload/notification/matrix.png: Matrix channel icon
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 250 B |
+71
-4
@@ -38,7 +38,7 @@ interface NotificationChannelDialogProps {
|
||||
|
||||
const baseSchema = z.object({
|
||||
notify_name: z.string().min(1, "Name is required"),
|
||||
notification_type: z.enum(["telegram", "discord", "slack", "signal", "google_chat", "email", "ntfy", "pushover", "notifiarr", "gotify", "webhook"]),
|
||||
notification_type: z.enum(["telegram", "discord", "slack", "signal", "google_chat", "email", "ntfy", "pushover", "notifiarr", "gotify", "webhook", "matrix"]),
|
||||
enabled: z.boolean().default(true),
|
||||
service_id: z.string().default("global"),
|
||||
template_id: z.string().optional(),
|
||||
@@ -110,6 +110,13 @@ const gotifySchema = baseSchema.extend({
|
||||
server_url: z.string().url("Must be a valid server URL"),
|
||||
});
|
||||
|
||||
const matrixSchema = baseSchema.extend({
|
||||
notification_type: z.literal("matrix"),
|
||||
matrix_homeserver: z.string().url("Must be a valid homeserver URL"),
|
||||
matrix_room_id: z.string().min(1, "Room ID is required"),
|
||||
matrix_access_token: z.string().min(1, "Access token is required"),
|
||||
});
|
||||
|
||||
const formSchema = z.discriminatedUnion("notification_type", [
|
||||
telegramSchema,
|
||||
discordSchema,
|
||||
@@ -122,6 +129,7 @@ const formSchema = z.discriminatedUnion("notification_type", [
|
||||
notifiarrSchema,
|
||||
gotifySchema,
|
||||
webhookSchema,
|
||||
matrixSchema,
|
||||
]);
|
||||
|
||||
type FormValues = z.infer<typeof formSchema>;
|
||||
@@ -188,12 +196,18 @@ const notificationTypeOptions = [
|
||||
description: "Send push notifications via Gotify",
|
||||
icon: "/upload/notification/gotify.png"
|
||||
},
|
||||
{
|
||||
value: "webhook",
|
||||
label: "Webhook",
|
||||
{
|
||||
value: "webhook",
|
||||
label: "Webhook",
|
||||
description: "Send notifications to custom webhook",
|
||||
icon: "/upload/notification/webhook.png"
|
||||
},
|
||||
{
|
||||
value: "matrix",
|
||||
label: "Matrix",
|
||||
description: "Send notifications to a Matrix chat room",
|
||||
icon: "/upload/notification/matrix.png"
|
||||
},
|
||||
];
|
||||
|
||||
const webhookPayloadTemplates = {
|
||||
@@ -832,6 +846,59 @@ export const NotificationChannelDialog = ({
|
||||
</>
|
||||
)}
|
||||
|
||||
{notificationType === "matrix" && (
|
||||
<>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="matrix_homeserver"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t("matrixHomeserver")}</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder={t("matrixHomeserverPlaceholder")} {...field} />
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
{t("matrixHomeserverDesc")}
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="matrix_room_id"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t("matrixRoomId")}</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder={t("matrixRoomIdPlaceholder")} {...field} />
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
{t("matrixRoomIdDesc")}
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="matrix_access_token"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t("matrixAccessToken")}</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder={t("matrixAccessTokenPlaceholder")} {...field} type="password" />
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
{t("matrixAccessTokenDesc")}
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="enabled"
|
||||
|
||||
@@ -82,6 +82,7 @@ export const NotificationChannelList = ({
|
||||
case "pushover": return "Pushover";
|
||||
case "notifiarr": return "Notifiarr";
|
||||
case "webhook": return "Webhook";
|
||||
case "matrix": return "Matrix";
|
||||
default: return type || "Unknown";
|
||||
}
|
||||
};
|
||||
@@ -102,6 +103,8 @@ export const NotificationChannelList = ({
|
||||
return config.signal_number || '';
|
||||
case "email":
|
||||
return config.email_address || '';
|
||||
case "matrix":
|
||||
return config.matrix_room_id || '';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -154,6 +154,7 @@ const NotificationSettings = () => {
|
||||
<TabsTrigger value="google_chat">{t("googleChat")}</TabsTrigger>
|
||||
<TabsTrigger value="email">{t("email")}</TabsTrigger>
|
||||
<TabsTrigger value="webhook">{t("webhook")}</TabsTrigger>
|
||||
<TabsTrigger value="matrix">{t("matrix")}</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value={currentTab} className="mt-0">
|
||||
|
||||
@@ -7,7 +7,7 @@ export interface AlertConfiguration {
|
||||
collectionId?: string;
|
||||
collectionName?: string;
|
||||
service_id: string;
|
||||
notification_type: "telegram" | "discord" | "slack" | "signal" | "google_chat" | "email" | "ntfy" | "pushover" | "notifiarr" | "gotify" | "webhook";
|
||||
notification_type: "telegram" | "discord" | "slack" | "signal" | "google_chat" | "email" | "ntfy" | "pushover" | "notifiarr" | "gotify" | "webhook" | "matrix";
|
||||
telegram_chat_id?: string;
|
||||
discord_webhook_url?: string;
|
||||
signal_number?: string;
|
||||
@@ -34,6 +34,9 @@ export interface AlertConfiguration {
|
||||
server_url?: string;
|
||||
webhook_url?: string;
|
||||
webhook_payload_template?: string;
|
||||
matrix_homeserver?: string;
|
||||
matrix_room_id?: string;
|
||||
matrix_access_token?: string;
|
||||
}
|
||||
|
||||
export const alertConfigService = {
|
||||
@@ -105,8 +108,13 @@ export const alertConfigService = {
|
||||
} else if (config.notification_type === "webhook") {
|
||||
cleanConfig.webhook_url = config.webhook_url || "";
|
||||
cleanConfig.webhook_payload_template = config.webhook_payload_template || "";
|
||||
|
||||
}
|
||||
|
||||
} else if (config.notification_type === "matrix") {
|
||||
cleanConfig.matrix_homeserver = config.matrix_homeserver || "";
|
||||
cleanConfig.matrix_room_id = config.matrix_room_id || "";
|
||||
cleanConfig.matrix_access_token = config.matrix_access_token || "";
|
||||
|
||||
}
|
||||
const result = await pb.collection('alert_configurations').create(cleanConfig);
|
||||
|
||||
toast({
|
||||
|
||||
@@ -73,6 +73,7 @@ export const settingsTranslations: SettingsTranslations = {
|
||||
googleChat: "Google Chat",
|
||||
email: "Email",
|
||||
webhook: "Webhook",
|
||||
matrix: "Matrix",
|
||||
|
||||
// NotificationChannelDialog.tsx
|
||||
editChannel: "Edit Notification Channel",
|
||||
@@ -129,6 +130,12 @@ export const settingsTranslations: SettingsTranslations = {
|
||||
notifiarrChannelIdDesc: "The Discord channel ID where notifications will be sent",
|
||||
gotifyServerUrl: "Server URL",
|
||||
gotifyServerUrlDesc: "The URL of your Gotify server",
|
||||
matrixHomeserver: "Homeserver URL",
|
||||
matrixHomeserverDesc: "The URL of your Matrix homeserver (e.g. https://matrix.org)",
|
||||
matrixRoomId: "Room ID",
|
||||
matrixRoomIdDesc: "The Matrix room ID to send notifications to (e.g. !abc123:matrix.org)",
|
||||
matrixAccessToken: "Access Token",
|
||||
matrixAccessTokenDesc: "The access token of your Matrix bot account",
|
||||
errorSaveChannel: "Failed to save notification channel",
|
||||
|
||||
channelNamePlaceholder: "My Notification Channel",
|
||||
@@ -150,6 +157,9 @@ export const settingsTranslations: SettingsTranslations = {
|
||||
notifiarrChannelIdPlaceholder: "Discord Channel ID",
|
||||
gotifyServerUrlPlaceholder: "https://your-gotify-server.com",
|
||||
webhookUrlPlaceholder: "https://api.example.com/webhook",
|
||||
matrixHomeserverPlaceholder: "https://matrix.org",
|
||||
matrixRoomIdPlaceholder: "!roomid:matrix.org",
|
||||
matrixAccessTokenPlaceholder: "syt_...",
|
||||
|
||||
// DataRetentionSettings.tsx
|
||||
// permissionNotice: "Permission Notice:",
|
||||
|
||||
@@ -73,6 +73,7 @@ descriptionChannelsServices: "កំណត់រចនាសម្ព័ន្
|
||||
googleChat: "Google Chat",
|
||||
email: "អ៊ីមែល",
|
||||
webhook: "Webhook",
|
||||
matrix: "Matrix",
|
||||
|
||||
// NotificationChannelDialog.tsx
|
||||
editChannel: "កែសម្រួលបណ្តាញជូនដំណឹង",
|
||||
@@ -129,6 +130,12 @@ descriptionChannelsServices: "កំណត់រចនាសម្ព័ន្
|
||||
notifiarrChannelIdDesc: "លេខសម្គាល់បណ្តាញ Discord ដែលការជូនដំណឹងនឹងត្រូវបានផ្ញើទៅ",
|
||||
gotifyServerUrl: "URL នៃម៉ាស៊ីនបម្រើ",
|
||||
gotifyServerUrlDesc: "URL នៃម៉ាស៊ីនបម្រើ Gotify របស់អ្នក",
|
||||
matrixHomeserver: "Homeserver URL",
|
||||
matrixHomeserverDesc: "URL នៃ Matrix homeserver របស់អ្នក (ឧ. https://matrix.org)",
|
||||
matrixRoomId: "Room ID",
|
||||
matrixRoomIdDesc: "Matrix room ID ដែលការជូនដំណឹងនឹងត្រូវបានផ្ញើទៅ (ឧ. !abc123:matrix.org)",
|
||||
matrixAccessToken: "Access Token",
|
||||
matrixAccessTokenDesc: "Access token នៃ Matrix bot account របស់អ្នក",
|
||||
errorSaveChannel: "បរាជ័យក្នុងការរក្សាទុកបណ្តាញជូនដំណឹង",
|
||||
|
||||
channelNamePlaceholder: "ប៉ុស្តិ៍ផ្ទាល់សារជូនដំណឹងរបស់ខ្ញុំ",
|
||||
@@ -150,6 +157,9 @@ descriptionChannelsServices: "កំណត់រចនាសម្ព័ន្
|
||||
notifiarrChannelIdPlaceholder: "ID ប៉ុស្តិ៍ផ្ទាល់សារ Discord",
|
||||
gotifyServerUrlPlaceholder: "https://your-gotify-server.com",
|
||||
webhookUrlPlaceholder: "https://api.example.com/webhook",
|
||||
matrixHomeserverPlaceholder: "https://matrix.org",
|
||||
matrixRoomIdPlaceholder: "!roomid:matrix.org",
|
||||
matrixAccessTokenPlaceholder: "syt_...",
|
||||
|
||||
// DataRetentionSettings.tsx
|
||||
permissionNoticeDataRetention: "ជាអ្នកប្រើប្រាស់អ្នកគ្រប់គ្រង អ្នកមិនមានសិទ្ធចូលដំណើរការការកំណត់រក្សាទុកទិន្នន័យទេ។ ការកំណត់ទាំងនេះអាចត្រូវបានចូលដំណើរការនិងកែប្រែដោយតែអ្នកគ្រប់គ្រងដ៏ខ្ពស់ប៉ុណ្ណោះ។",
|
||||
|
||||
@@ -71,6 +71,7 @@ export interface SettingsTranslations {
|
||||
googleChat: string;
|
||||
email: string;
|
||||
webhook: string;
|
||||
matrix: string;
|
||||
|
||||
// NotificationChannelDialog.tsx
|
||||
editChannel: string;
|
||||
@@ -127,6 +128,12 @@ export interface SettingsTranslations {
|
||||
notifiarrChannelIdDesc: string;
|
||||
gotifyServerUrl: string;
|
||||
gotifyServerUrlDesc: string;
|
||||
matrixHomeserver: string;
|
||||
matrixHomeserverDesc: string;
|
||||
matrixRoomId: string;
|
||||
matrixRoomIdDesc: string;
|
||||
matrixAccessToken: string;
|
||||
matrixAccessTokenDesc: string;
|
||||
errorSaveChannel: string;
|
||||
|
||||
channelNamePlaceholder: string;
|
||||
@@ -148,6 +155,9 @@ export interface SettingsTranslations {
|
||||
notifiarrChannelIdPlaceholder: string;
|
||||
gotifyServerUrlPlaceholder: string;
|
||||
webhookUrlPlaceholder: string;
|
||||
matrixHomeserverPlaceholder: string;
|
||||
matrixRoomIdPlaceholder: string;
|
||||
matrixAccessTokenPlaceholder: string;
|
||||
|
||||
// DataRetentionSettings.tsx
|
||||
// permissionNotice: string;
|
||||
|
||||
Reference in New Issue
Block a user