feat: add pushover integration
This commit is contained in:
1 parent
dd2eb3aa66
commit
5ec38d6136
10 files changed
+115
-1
No files matched your search
@@ -182,6 +182,7 @@ export type HomarrDocumentationPath =
|
||||
| "/docs/integrations/glances"
|
||||
| "/docs/integrations/gluetun"
|
||||
| "/docs/integrations/gotify"
|
||||
| "/docs/integrations/pushover"
|
||||
| "/docs/integrations/home-assistant"
|
||||
| "/docs/integrations/ical"
|
||||
| "/docs/integrations/immich"
|
||||
@@ -326,6 +327,7 @@ export type HomarrDocumentationPath =
|
||||
| "/docs/integrations/quay"
|
||||
| "/docs/integrations/ntfy"
|
||||
| "/docs/integrations/gotify"
|
||||
| "/docs/integrations/pushover"
|
||||
| "/docs/integrations/ical"
|
||||
| "/docs/integrations/anchor"
|
||||
| "/docs/integrations/truenas"
|
||||
|
||||
@@ -41,6 +41,7 @@ export const integrationDocSlugs: Record<IntegrationKind, string | null> = {
|
||||
quay: "quay",
|
||||
ntfy: "ntfy",
|
||||
gotify: "gotify",
|
||||
pushover: "pushover",
|
||||
ical: "ical",
|
||||
anchor: "anchor",
|
||||
truenas: "truenas",
|
||||
|
||||
@@ -18,6 +18,7 @@ export const integrationSecretKindObject = {
|
||||
githubAppId: { isPublic: true, multiline: false },
|
||||
githubInstallationId: { isPublic: true, multiline: false },
|
||||
slug: { isPublic: true, multiline: false },
|
||||
userKey: { isPublic: false, multiline: false },
|
||||
} satisfies Record<string, { isPublic: boolean; multiline: boolean }>;
|
||||
|
||||
export const integrationSecretKinds = objectKeys(integrationSecretKindObject);
|
||||
@@ -362,6 +363,14 @@ export const integrationDefs = {
|
||||
category: ["notifications"],
|
||||
documentationUrl: createDocumentationLink("/docs/integrations/gotify"),
|
||||
},
|
||||
pushover: {
|
||||
name: "Pushover",
|
||||
secretKinds: [["apiKey", "userKey"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/pushover.svg",
|
||||
category: ["notifications"],
|
||||
defaultUrl: "https://api.pushover.net",
|
||||
documentationUrl: createDocumentationLink("/docs/integrations/pushover"),
|
||||
},
|
||||
ical: {
|
||||
name: "iCal",
|
||||
secretKinds: [["url"]],
|
||||
|
||||
@@ -39,6 +39,7 @@ import { NextcloudIntegration } from "../nextcloud/nextcloud.integration";
|
||||
import { NPMIntegration } from "../npm/npm-integration";
|
||||
import { GotifyIntegration } from "../gotify/gotify-integration";
|
||||
import { NTFYIntegration } from "../ntfy/ntfy-integration";
|
||||
import { PushoverIntegration } from "../pushover/pushover-integration";
|
||||
import { OpenMediaVaultIntegration } from "../openmediavault/openmediavault-integration";
|
||||
import { OPNsenseIntegration } from "../opnsense/opnsense-integration";
|
||||
import { OverseerrIntegration } from "../overseerr/overseerr-integration";
|
||||
@@ -125,6 +126,7 @@ export const integrationCreators = {
|
||||
quay: QuayIntegration,
|
||||
ntfy: NTFYIntegration,
|
||||
gotify: GotifyIntegration,
|
||||
pushover: PushoverIntegration,
|
||||
mock: MockIntegration,
|
||||
truenas: TrueNasIntegration,
|
||||
unraid: UnraidIntegration,
|
||||
|
||||
@@ -19,6 +19,7 @@ export { ReadarrIntegration } from "./media-organizer/readarr/readarr-integratio
|
||||
export { SonarrIntegration } from "./media-organizer/sonarr/sonarr-integration";
|
||||
export { NextcloudIntegration } from "./nextcloud/nextcloud.integration";
|
||||
export { GotifyIntegration } from "./gotify/gotify-integration";
|
||||
export { PushoverIntegration } from "./pushover/pushover-integration";
|
||||
export { NTFYIntegration } from "./ntfy/ntfy-integration";
|
||||
export { OpenMediaVaultIntegration } from "./openmediavault/openmediavault-integration";
|
||||
export { GlancesIntegration } from "./glances/glances-integration";
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { ResponseError } from "@homarr/common/server";
|
||||
import { fetchWithTrustedCertificatesAsync } from "@homarr/core/infrastructure/http";
|
||||
|
||||
import { Integration } from "../base/integration";
|
||||
import type { IntegrationTestingInput } from "../base/integration";
|
||||
import type { TestingResult } from "../base/test-connection/test-connection-service";
|
||||
import type { Notification } from "../interfaces/notifications/notification-types";
|
||||
import type { INotificationsIntegration } from "../interfaces/notifications/notifications-integration";
|
||||
import { pushoverLimitsResponseSchema } from "./pushover-schema";
|
||||
|
||||
export class PushoverIntegration extends Integration implements INotificationsIntegration {
|
||||
public async testingAsync(input: IntegrationTestingInput): Promise<TestingResult> {
|
||||
const token = this.getSecretValue("apiKey");
|
||||
const url = this.url("/1/apps/limits.json", { token });
|
||||
const response = await input.fetchAsync(url);
|
||||
|
||||
if (!response.ok) throw new ResponseError(response);
|
||||
|
||||
const result = await pushoverLimitsResponseSchema.safeParseAsync(await response.json());
|
||||
if (!result.success) throw new Error(`Failed to parse Pushover response: ${result.error.message}`);
|
||||
if (result.data.status !== 1) throw new Error("Pushover API returned non-success status");
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
public async getNotificationsAsync(): Promise<Notification[]> {
|
||||
const token = this.getSecretValue("apiKey");
|
||||
const url = this.url("/1/apps/limits.json", { token });
|
||||
const response = await fetchWithTrustedCertificatesAsync(url);
|
||||
|
||||
if (!response.ok) throw new ResponseError(response);
|
||||
|
||||
const result = await pushoverLimitsResponseSchema.safeParseAsync(await response.json());
|
||||
if (!result.success) throw new Error(`Failed to parse Pushover response: ${result.error.message}`);
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { z } from "zod/v4";
|
||||
|
||||
export const pushoverLimitsResponseSchema = z.object({
|
||||
status: z.number(),
|
||||
request: z.string(),
|
||||
limit: z.number().optional(),
|
||||
remaining: z.number().optional(),
|
||||
reset: z.number().optional(),
|
||||
});
|
||||
Reference in new issue
Block a user