Refactor Webhook to use alert_configurations and Add Signal API endpoint field
- This field will be used to specify the API endpoint for Signal notifications. - This change aligns the frontend with the backend's data structure for webhooks.
This commit is contained in:
+46
-59
@@ -9,7 +9,6 @@ import {
|
|||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import { AlertConfiguration, alertConfigService } from "@/services/alertConfigService";
|
import { AlertConfiguration, alertConfigService } from "@/services/alertConfigService";
|
||||||
import { WebhookConfiguration, webhookService } from "@/services/webhookService";
|
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
@@ -62,6 +61,7 @@ const slackSchema = baseSchema.extend({
|
|||||||
const signalSchema = baseSchema.extend({
|
const signalSchema = baseSchema.extend({
|
||||||
notification_type: z.literal("signal"),
|
notification_type: z.literal("signal"),
|
||||||
signal_number: z.string().min(1, "Signal number is required"),
|
signal_number: z.string().min(1, "Signal number is required"),
|
||||||
|
signal_api_endpoint: z.string().url("Must be a valid API endpoint URL"),
|
||||||
});
|
});
|
||||||
|
|
||||||
const googleChatSchema = baseSchema.extend({
|
const googleChatSchema = baseSchema.extend({
|
||||||
@@ -107,19 +107,19 @@ const notificationTypeOptions = [
|
|||||||
value: "discord",
|
value: "discord",
|
||||||
label: "Discord",
|
label: "Discord",
|
||||||
description: "Send notifications to Discord webhook",
|
description: "Send notifications to Discord webhook",
|
||||||
icon: "/upload/notification/discord.png"
|
icon: "/upload/notification/discord.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "slack",
|
value: "slack",
|
||||||
label: "Slack",
|
label: "Slack",
|
||||||
description: "Send notifications to Slack webhook",
|
description: "Send notifications to Slack webhook",
|
||||||
icon: "/upload/notification/slack.png"
|
icon: "/upload/notification/slack.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "signal",
|
value: "signal",
|
||||||
label: "Signal",
|
label: "Signal",
|
||||||
description: "Send notifications via Signal",
|
description: "Send notifications via Signal",
|
||||||
icon: "/upload/notification/signal.png"
|
icon: "/upload/notification/signal.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "google_chat",
|
value: "google_chat",
|
||||||
@@ -234,14 +234,6 @@ export const NotificationChannelDialog = ({
|
|||||||
onClose(false);
|
onClose(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const copyToClipboard = (text: string) => {
|
|
||||||
navigator.clipboard.writeText(text);
|
|
||||||
toast({
|
|
||||||
title: "Copied",
|
|
||||||
description: "Template copied to clipboard",
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const insertTemplate = (template: string) => {
|
const insertTemplate = (template: string) => {
|
||||||
setValue("webhook_payload_template", template);
|
setValue("webhook_payload_template", template);
|
||||||
};
|
};
|
||||||
@@ -249,39 +241,16 @@ export const NotificationChannelDialog = ({
|
|||||||
const onSubmit = async (values: FormValues) => {
|
const onSubmit = async (values: FormValues) => {
|
||||||
setIsSubmitting(true);
|
setIsSubmitting(true);
|
||||||
try {
|
try {
|
||||||
if (values.notification_type === "webhook") {
|
// Handle all notification types including webhook through alert_configurations
|
||||||
// Handle webhook creation/update with simplified fields
|
const configData = {
|
||||||
const webhookData: Omit<WebhookConfiguration, 'id' | 'collectionId' | 'collectionName' | 'created' | 'updated'> = {
|
...values,
|
||||||
name: values.notify_name,
|
service_id: values.service_id || "global",
|
||||||
url: values.webhook_url,
|
};
|
||||||
enabled: values.enabled ? "on" : "off",
|
|
||||||
method: "POST",
|
|
||||||
secret: "",
|
|
||||||
headers: "",
|
|
||||||
description: "",
|
|
||||||
payload_template: values.webhook_payload_template || defaultPayloadTemplate,
|
|
||||||
retry_count: "3",
|
|
||||||
trigger_events: "all",
|
|
||||||
user_id: "global",
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isEditing && editingConfig?.id) {
|
if (isEditing && editingConfig?.id) {
|
||||||
await webhookService.updateWebhook(editingConfig.id, webhookData);
|
await alertConfigService.updateAlertConfiguration(editingConfig.id, configData);
|
||||||
} else {
|
|
||||||
await webhookService.createWebhook(webhookData);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Handle all other notification types including Google Chat and Email
|
await alertConfigService.createAlertConfiguration(configData as any);
|
||||||
const configData = {
|
|
||||||
...values,
|
|
||||||
service_id: values.service_id || "global",
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isEditing && editingConfig?.id) {
|
|
||||||
await alertConfigService.updateAlertConfiguration(editingConfig.id, configData);
|
|
||||||
} else {
|
|
||||||
await alertConfigService.createAlertConfiguration(configData as any);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onClose(true); // Close with refresh
|
onClose(true); // Close with refresh
|
||||||
@@ -435,22 +404,40 @@ export const NotificationChannelDialog = ({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{notificationType === "signal" && (
|
{notificationType === "signal" && (
|
||||||
<FormField
|
<>
|
||||||
control={form.control}
|
<FormField
|
||||||
name="signal_number"
|
control={form.control}
|
||||||
render={({ field }) => (
|
name="signal_number"
|
||||||
<FormItem>
|
render={({ field }) => (
|
||||||
<FormLabel>Signal Number</FormLabel>
|
<FormItem>
|
||||||
<FormControl>
|
<FormLabel>Signal Number</FormLabel>
|
||||||
<Input placeholder="+1234567890" {...field} />
|
<FormControl>
|
||||||
</FormControl>
|
<Input placeholder="+1234567890" {...field} />
|
||||||
<FormDescription>
|
</FormControl>
|
||||||
Signal phone number to send notifications to
|
<FormDescription>
|
||||||
</FormDescription>
|
Signal phone number to send notifications to
|
||||||
<FormMessage />
|
</FormDescription>
|
||||||
</FormItem>
|
<FormMessage />
|
||||||
)}
|
</FormItem>
|
||||||
/>
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="signal_api_endpoint"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Signal API Endpoint</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input placeholder="https://your-signal-api.com/v2/send" {...field} />
|
||||||
|
</FormControl>
|
||||||
|
<FormDescription>
|
||||||
|
The Rest API endpoint for your Signal service
|
||||||
|
</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{notificationType === "google_chat" && (
|
{notificationType === "google_chat" && (
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export interface AlertConfiguration {
|
|||||||
telegram_chat_id?: string;
|
telegram_chat_id?: string;
|
||||||
discord_webhook_url?: string;
|
discord_webhook_url?: string;
|
||||||
signal_number?: string;
|
signal_number?: string;
|
||||||
|
signal_api_endpoint?: string;
|
||||||
notify_name: string;
|
notify_name: string;
|
||||||
bot_token?: string;
|
bot_token?: string;
|
||||||
template_id?: string;
|
template_id?: string;
|
||||||
@@ -27,10 +28,14 @@ export interface AlertConfiguration {
|
|||||||
smtp_password?: string;
|
smtp_password?: string;
|
||||||
webhook_id?: string;
|
webhook_id?: string;
|
||||||
channel_id?: string;
|
channel_id?: string;
|
||||||
|
// Webhook fields for alert_configurations
|
||||||
|
webhook_url?: string;
|
||||||
|
webhook_payload_template?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const alertConfigService = {
|
export const alertConfigService = {
|
||||||
async getAlertConfigurations(): Promise<AlertConfiguration[]> {
|
async getAlertConfigurations(): Promise<AlertConfiguration[]> {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await pb.collection('alert_configurations').getList(1, 50);
|
const response = await pb.collection('alert_configurations').getList(1, 50);
|
||||||
return response.items as AlertConfiguration[];
|
return response.items as AlertConfiguration[];
|
||||||
@@ -66,15 +71,23 @@ export const alertConfigService = {
|
|||||||
cleanConfig.slack_webhook_url = config.slack_webhook_url || "";
|
cleanConfig.slack_webhook_url = config.slack_webhook_url || "";
|
||||||
} else if (config.notification_type === "signal") {
|
} else if (config.notification_type === "signal") {
|
||||||
cleanConfig.signal_number = config.signal_number || "";
|
cleanConfig.signal_number = config.signal_number || "";
|
||||||
|
cleanConfig.signal_api_endpoint = config.signal_api_endpoint || "";
|
||||||
} else if (config.notification_type === "google_chat") {
|
} else if (config.notification_type === "google_chat") {
|
||||||
cleanConfig.google_chat_webhook_url = config.google_chat_webhook_url || "";
|
cleanConfig.google_chat_webhook_url = config.google_chat_webhook_url || "";
|
||||||
|
|
||||||
} else if (config.notification_type === "email") {
|
} else if (config.notification_type === "email") {
|
||||||
|
|
||||||
cleanConfig.email_address = config.email_address || "";
|
cleanConfig.email_address = config.email_address || "";
|
||||||
cleanConfig.email_sender_name = config.email_sender_name || "";
|
cleanConfig.email_sender_name = config.email_sender_name || "";
|
||||||
cleanConfig.smtp_server = config.smtp_server || "";
|
cleanConfig.smtp_server = config.smtp_server || "";
|
||||||
cleanConfig.smtp_port = config.smtp_port || "";
|
cleanConfig.smtp_port = config.smtp_port || "";
|
||||||
cleanConfig.smtp_password = config.smtp_password || "";
|
cleanConfig.smtp_password = config.smtp_password || "";
|
||||||
|
|
||||||
|
} else if (config.notification_type === "webhook") {
|
||||||
|
|
||||||
|
cleanConfig.webhook_url = config.webhook_url || "";
|
||||||
|
cleanConfig.webhook_payload_template = config.webhook_payload_template || "";
|
||||||
|
|
||||||
}
|
}
|
||||||
const result = await pb.collection('alert_configurations').create(cleanConfig);
|
const result = await pb.collection('alert_configurations').create(cleanConfig);
|
||||||
|
|
||||||
@@ -84,6 +97,7 @@ export const alertConfigService = {
|
|||||||
});
|
});
|
||||||
return result as AlertConfiguration;
|
return result as AlertConfiguration;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
// Try to get more details from the error
|
// Try to get more details from the error
|
||||||
if (error && typeof error === 'object') {
|
if (error && typeof error === 'object') {
|
||||||
}
|
}
|
||||||
@@ -99,7 +113,17 @@ export const alertConfigService = {
|
|||||||
|
|
||||||
async updateAlertConfiguration(id: string, config: Partial<AlertConfiguration>): Promise<AlertConfiguration | null> {
|
async updateAlertConfiguration(id: string, config: Partial<AlertConfiguration>): Promise<AlertConfiguration | null> {
|
||||||
try {
|
try {
|
||||||
const result = await pb.collection('alert_configurations').update(id, config);
|
// Build the update config with proper field mapping
|
||||||
|
const updateConfig: any = {};
|
||||||
|
|
||||||
|
// Copy all provided fields
|
||||||
|
Object.keys(config).forEach(key => {
|
||||||
|
if (config[key as keyof AlertConfiguration] !== undefined) {
|
||||||
|
updateConfig[key] = config[key as keyof AlertConfiguration];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await pb.collection('alert_configurations').update(id, updateConfig);
|
||||||
toast({
|
toast({
|
||||||
title: "Success",
|
title: "Success",
|
||||||
description: "Notification channel updated successfully",
|
description: "Notification channel updated successfully",
|
||||||
|
|||||||
Reference in New Issue
Block a user