mirror of
https://github.com/nicotsx/ironmount.git
synced 2025-12-10 12:10:51 +01:00
telegram notification
This commit is contained in:
@@ -1990,6 +1990,10 @@ export type GetScheduleNotificationsResponses = {
|
|||||||
} | {
|
} | {
|
||||||
shoutrrrUrl: string;
|
shoutrrrUrl: string;
|
||||||
type: 'custom';
|
type: 'custom';
|
||||||
|
} | {
|
||||||
|
type: 'telegram';
|
||||||
|
botToken: string;
|
||||||
|
chatId: string;
|
||||||
} | {
|
} | {
|
||||||
type: 'discord';
|
type: 'discord';
|
||||||
webhookUrl: string;
|
webhookUrl: string;
|
||||||
@@ -2007,7 +2011,7 @@ export type GetScheduleNotificationsResponses = {
|
|||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
type: 'custom' | 'discord' | 'email' | 'gotify' | 'ntfy' | 'pushover' | 'slack';
|
type: 'custom' | 'discord' | 'email' | 'gotify' | 'ntfy' | 'pushover' | 'slack' | 'telegram';
|
||||||
updatedAt: number;
|
updatedAt: number;
|
||||||
};
|
};
|
||||||
destinationId: number;
|
destinationId: number;
|
||||||
@@ -2074,6 +2078,10 @@ export type UpdateScheduleNotificationsResponses = {
|
|||||||
} | {
|
} | {
|
||||||
shoutrrrUrl: string;
|
shoutrrrUrl: string;
|
||||||
type: 'custom';
|
type: 'custom';
|
||||||
|
} | {
|
||||||
|
type: 'telegram';
|
||||||
|
botToken: string;
|
||||||
|
chatId: string;
|
||||||
} | {
|
} | {
|
||||||
type: 'discord';
|
type: 'discord';
|
||||||
webhookUrl: string;
|
webhookUrl: string;
|
||||||
@@ -2091,7 +2099,7 @@ export type UpdateScheduleNotificationsResponses = {
|
|||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
type: 'custom' | 'discord' | 'email' | 'gotify' | 'ntfy' | 'pushover' | 'slack';
|
type: 'custom' | 'discord' | 'email' | 'gotify' | 'ntfy' | 'pushover' | 'slack' | 'telegram';
|
||||||
updatedAt: number;
|
updatedAt: number;
|
||||||
};
|
};
|
||||||
destinationId: number;
|
destinationId: number;
|
||||||
@@ -2147,6 +2155,10 @@ export type ListNotificationDestinationsResponses = {
|
|||||||
} | {
|
} | {
|
||||||
shoutrrrUrl: string;
|
shoutrrrUrl: string;
|
||||||
type: 'custom';
|
type: 'custom';
|
||||||
|
} | {
|
||||||
|
type: 'telegram';
|
||||||
|
botToken: string;
|
||||||
|
chatId: string;
|
||||||
} | {
|
} | {
|
||||||
type: 'discord';
|
type: 'discord';
|
||||||
webhookUrl: string;
|
webhookUrl: string;
|
||||||
@@ -2164,7 +2176,7 @@ export type ListNotificationDestinationsResponses = {
|
|||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
type: 'custom' | 'discord' | 'email' | 'gotify' | 'ntfy' | 'pushover' | 'slack';
|
type: 'custom' | 'discord' | 'email' | 'gotify' | 'ntfy' | 'pushover' | 'slack' | 'telegram';
|
||||||
updatedAt: number;
|
updatedAt: number;
|
||||||
}>;
|
}>;
|
||||||
};
|
};
|
||||||
@@ -2204,6 +2216,10 @@ export type CreateNotificationDestinationData = {
|
|||||||
} | {
|
} | {
|
||||||
shoutrrrUrl: string;
|
shoutrrrUrl: string;
|
||||||
type: 'custom';
|
type: 'custom';
|
||||||
|
} | {
|
||||||
|
type: 'telegram';
|
||||||
|
botToken: string;
|
||||||
|
chatId: string;
|
||||||
} | {
|
} | {
|
||||||
type: 'discord';
|
type: 'discord';
|
||||||
webhookUrl: string;
|
webhookUrl: string;
|
||||||
@@ -2260,6 +2276,10 @@ export type CreateNotificationDestinationResponses = {
|
|||||||
} | {
|
} | {
|
||||||
shoutrrrUrl: string;
|
shoutrrrUrl: string;
|
||||||
type: 'custom';
|
type: 'custom';
|
||||||
|
} | {
|
||||||
|
type: 'telegram';
|
||||||
|
botToken: string;
|
||||||
|
chatId: string;
|
||||||
} | {
|
} | {
|
||||||
type: 'discord';
|
type: 'discord';
|
||||||
webhookUrl: string;
|
webhookUrl: string;
|
||||||
@@ -2277,7 +2297,7 @@ export type CreateNotificationDestinationResponses = {
|
|||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
type: 'custom' | 'discord' | 'email' | 'gotify' | 'ntfy' | 'pushover' | 'slack';
|
type: 'custom' | 'discord' | 'email' | 'gotify' | 'ntfy' | 'pushover' | 'slack' | 'telegram';
|
||||||
updatedAt: number;
|
updatedAt: number;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -2363,6 +2383,10 @@ export type GetNotificationDestinationResponses = {
|
|||||||
} | {
|
} | {
|
||||||
shoutrrrUrl: string;
|
shoutrrrUrl: string;
|
||||||
type: 'custom';
|
type: 'custom';
|
||||||
|
} | {
|
||||||
|
type: 'telegram';
|
||||||
|
botToken: string;
|
||||||
|
chatId: string;
|
||||||
} | {
|
} | {
|
||||||
type: 'discord';
|
type: 'discord';
|
||||||
webhookUrl: string;
|
webhookUrl: string;
|
||||||
@@ -2380,7 +2404,7 @@ export type GetNotificationDestinationResponses = {
|
|||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
type: 'custom' | 'discord' | 'email' | 'gotify' | 'ntfy' | 'pushover' | 'slack';
|
type: 'custom' | 'discord' | 'email' | 'gotify' | 'ntfy' | 'pushover' | 'slack' | 'telegram';
|
||||||
updatedAt: number;
|
updatedAt: number;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -2420,6 +2444,10 @@ export type UpdateNotificationDestinationData = {
|
|||||||
} | {
|
} | {
|
||||||
shoutrrrUrl: string;
|
shoutrrrUrl: string;
|
||||||
type: 'custom';
|
type: 'custom';
|
||||||
|
} | {
|
||||||
|
type: 'telegram';
|
||||||
|
botToken: string;
|
||||||
|
chatId: string;
|
||||||
} | {
|
} | {
|
||||||
type: 'discord';
|
type: 'discord';
|
||||||
webhookUrl: string;
|
webhookUrl: string;
|
||||||
@@ -2486,6 +2514,10 @@ export type UpdateNotificationDestinationResponses = {
|
|||||||
} | {
|
} | {
|
||||||
shoutrrrUrl: string;
|
shoutrrrUrl: string;
|
||||||
type: 'custom';
|
type: 'custom';
|
||||||
|
} | {
|
||||||
|
type: 'telegram';
|
||||||
|
botToken: string;
|
||||||
|
chatId: string;
|
||||||
} | {
|
} | {
|
||||||
type: 'discord';
|
type: 'discord';
|
||||||
webhookUrl: string;
|
webhookUrl: string;
|
||||||
@@ -2503,7 +2535,7 @@ export type UpdateNotificationDestinationResponses = {
|
|||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
type: 'custom' | 'discord' | 'email' | 'gotify' | 'ntfy' | 'pushover' | 'slack';
|
type: 'custom' | 'discord' | 'email' | 'gotify' | 'ntfy' | 'pushover' | 'slack' | 'telegram';
|
||||||
updatedAt: number;
|
updatedAt: number;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -70,6 +70,11 @@ const defaultValuesForType = {
|
|||||||
apiToken: "",
|
apiToken: "",
|
||||||
priority: 0 as const,
|
priority: 0 as const,
|
||||||
},
|
},
|
||||||
|
telegram: {
|
||||||
|
type: "telegram" as const,
|
||||||
|
botToken: "",
|
||||||
|
chatId: ""
|
||||||
|
},
|
||||||
custom: {
|
custom: {
|
||||||
type: "custom" as const,
|
type: "custom" as const,
|
||||||
shoutrrrUrl: "",
|
shoutrrrUrl: "",
|
||||||
@@ -146,6 +151,7 @@ export const CreateNotificationForm = ({ onSubmit, mode = "create", initialValue
|
|||||||
<SelectItem value="gotify">Gotify</SelectItem>
|
<SelectItem value="gotify">Gotify</SelectItem>
|
||||||
<SelectItem value="ntfy">Ntfy</SelectItem>
|
<SelectItem value="ntfy">Ntfy</SelectItem>
|
||||||
<SelectItem value="pushover">Pushover</SelectItem>
|
<SelectItem value="pushover">Pushover</SelectItem>
|
||||||
|
<SelectItem value="telegram">Telegram</SelectItem>
|
||||||
<SelectItem value="custom">Custom (Shoutrrr URL)</SelectItem>
|
<SelectItem value="custom">Custom (Shoutrrr URL)</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
@@ -613,6 +619,43 @@ export const CreateNotificationForm = ({ onSubmit, mode = "create", initialValue
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{watchedType === "telegram" && (
|
||||||
|
<>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="botToken"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Bot Token</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input {...field} type="password" placeholder="123456789:ABC-DEF1234ghIkl-zyx57W2v1u123ew11" />
|
||||||
|
</FormControl>
|
||||||
|
<FormDescription>
|
||||||
|
Telegram bot token. Get this from BotFather when you create your bot.
|
||||||
|
</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="chatId"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Chat ID</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input {...field} placeholder="-1231234567890" />
|
||||||
|
</FormControl>
|
||||||
|
<FormDescription>
|
||||||
|
Telegram chat ID to send notifications to.
|
||||||
|
</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
{watchedType === "custom" && (
|
{watchedType === "custom" && (
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ export default function Notifications({ loaderData }: Route.ComponentProps) {
|
|||||||
<SelectItem value="gotify">Gotify</SelectItem>
|
<SelectItem value="gotify">Gotify</SelectItem>
|
||||||
<SelectItem value="ntfy">Ntfy</SelectItem>
|
<SelectItem value="ntfy">Ntfy</SelectItem>
|
||||||
<SelectItem value="pushover">Pushover</SelectItem>
|
<SelectItem value="pushover">Pushover</SelectItem>
|
||||||
|
<SelectItem value="telegram">Telegram</SelectItem>
|
||||||
<SelectItem value="custom">Custom</SelectItem>
|
<SelectItem value="custom">Custom</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export const NOTIFICATION_TYPES = {
|
|||||||
gotify: "gotify",
|
gotify: "gotify",
|
||||||
ntfy: "ntfy",
|
ntfy: "ntfy",
|
||||||
pushover: "pushover",
|
pushover: "pushover",
|
||||||
|
telegram: "telegram",
|
||||||
custom: "custom",
|
custom: "custom",
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
@@ -64,6 +65,12 @@ export const pushoverNotificationConfigSchema = type({
|
|||||||
priority: "-1 | 0 | 1",
|
priority: "-1 | 0 | 1",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const telegramNotificationConfigSchema = type({
|
||||||
|
type: "'telegram'",
|
||||||
|
botToken: "string",
|
||||||
|
chatId: "string",
|
||||||
|
});
|
||||||
|
|
||||||
export const customNotificationConfigSchema = type({
|
export const customNotificationConfigSchema = type({
|
||||||
type: "'custom'",
|
type: "'custom'",
|
||||||
shoutrrrUrl: "string",
|
shoutrrrUrl: "string",
|
||||||
@@ -75,6 +82,7 @@ export const notificationConfigSchema = emailNotificationConfigSchema
|
|||||||
.or(gotifyNotificationConfigSchema)
|
.or(gotifyNotificationConfigSchema)
|
||||||
.or(ntfyNotificationConfigSchema)
|
.or(ntfyNotificationConfigSchema)
|
||||||
.or(pushoverNotificationConfigSchema)
|
.or(pushoverNotificationConfigSchema)
|
||||||
|
.or(telegramNotificationConfigSchema)
|
||||||
.or(customNotificationConfigSchema);
|
.or(customNotificationConfigSchema);
|
||||||
|
|
||||||
export type NotificationConfig = typeof notificationConfigSchema.infer;
|
export type NotificationConfig = typeof notificationConfigSchema.infer;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { buildDiscordShoutrrrUrl } from "./discord";
|
|||||||
import { buildGotifyShoutrrrUrl } from "./gotify";
|
import { buildGotifyShoutrrrUrl } from "./gotify";
|
||||||
import { buildNtfyShoutrrrUrl } from "./ntfy";
|
import { buildNtfyShoutrrrUrl } from "./ntfy";
|
||||||
import { buildPushoverShoutrrrUrl } from "./pushover";
|
import { buildPushoverShoutrrrUrl } from "./pushover";
|
||||||
|
import { buildTelegramShoutrrrUrl } from "./telegram";
|
||||||
import { buildCustomShoutrrrUrl } from "./custom";
|
import { buildCustomShoutrrrUrl } from "./custom";
|
||||||
|
|
||||||
export function buildShoutrrrUrl(config: NotificationConfig): string {
|
export function buildShoutrrrUrl(config: NotificationConfig): string {
|
||||||
@@ -21,6 +22,8 @@ export function buildShoutrrrUrl(config: NotificationConfig): string {
|
|||||||
return buildNtfyShoutrrrUrl(config);
|
return buildNtfyShoutrrrUrl(config);
|
||||||
case "pushover":
|
case "pushover":
|
||||||
return buildPushoverShoutrrrUrl(config);
|
return buildPushoverShoutrrrUrl(config);
|
||||||
|
case "telegram":
|
||||||
|
return buildTelegramShoutrrrUrl(config);
|
||||||
case "custom":
|
case "custom":
|
||||||
return buildCustomShoutrrrUrl(config);
|
return buildCustomShoutrrrUrl(config);
|
||||||
default: {
|
default: {
|
||||||
|
|||||||
8
app/server/modules/notifications/builders/telegram.ts
Normal file
8
app/server/modules/notifications/builders/telegram.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import type { NotificationConfig } from "~/schemas/notifications";
|
||||||
|
|
||||||
|
export function buildTelegramShoutrrrUrl(config: Extract<NotificationConfig, { type: "telegram" }>): string {
|
||||||
|
// Shoutrrr format: telegram://bottoken@telegram?channels=chatid1,chatid2
|
||||||
|
// config: { type: 'telegram', botToken: string, chatId: string }
|
||||||
|
// Do NOT encode botToken or chatId; Shoutrrr expects raw values (colon, dash, etc.)
|
||||||
|
return `telegram://${config.botToken}@telegram?channels=${config.chatId}`;
|
||||||
|
}
|
||||||
@@ -65,6 +65,11 @@ async function encryptSensitiveFields(config: NotificationConfig): Promise<Notif
|
|||||||
...config,
|
...config,
|
||||||
apiToken: await cryptoUtils.encrypt(config.apiToken),
|
apiToken: await cryptoUtils.encrypt(config.apiToken),
|
||||||
};
|
};
|
||||||
|
case "telegram":
|
||||||
|
return {
|
||||||
|
...config,
|
||||||
|
botToken: await cryptoUtils.encrypt(config.botToken),
|
||||||
|
};
|
||||||
case "custom":
|
case "custom":
|
||||||
return {
|
return {
|
||||||
...config,
|
...config,
|
||||||
@@ -107,6 +112,11 @@ async function decryptSensitiveFields(config: NotificationConfig): Promise<Notif
|
|||||||
...config,
|
...config,
|
||||||
apiToken: await cryptoUtils.decrypt(config.apiToken),
|
apiToken: await cryptoUtils.decrypt(config.apiToken),
|
||||||
};
|
};
|
||||||
|
case "telegram":
|
||||||
|
return {
|
||||||
|
...config,
|
||||||
|
botToken: await cryptoUtils.decrypt(config.botToken),
|
||||||
|
};
|
||||||
case "custom":
|
case "custom":
|
||||||
return {
|
return {
|
||||||
...config,
|
...config,
|
||||||
|
|||||||
Reference in New Issue
Block a user