Merge reminder & backend features

This commit is contained in:
2025-01-17 15:37:14 +01:00
parent 67db439f84
commit f3b68dca33
5 changed files with 73 additions and 38 deletions

View File

@@ -1,9 +1,28 @@
import { BackendConfig } from "../types/config";
import { BackendSettings, Config } from "../types/config";
import { Notification } from "../types/notification";
export abstract class Backend {
constructor(config: BackendConfig) {
export abstract class Backend<C extends BackendSettings> {
public abstract readonly name: string;
protected abstract requiredFields: readonly (keyof C)[];
protected abstract notify(config: C, notification: Notification): void;
#validate(config: Partial<C>): C {
for (const field of this.requiredFields) {
if (config[field] === undefined) {
throw new Error(`The '${String(field)}' configuration field of'${this.name}' consumer is required`)
}
}
return config as C;
}
abstract notify(notification: Notification): void;
public remind(config: Config, notification: Notification) {
const cfg = config.backend[this.name] as Partial<C>;
if (cfg.enable !== true) {
return
}
this.notify(this.#validate(cfg), notification);
}
}

View File

@@ -1,3 +1,31 @@
import dayjs from "dayjs";
import { NotificationDatabase } from "../types/notification";
import { Config } from "../types/config";
import { NtfySH } from "./ntfy-sh";
export { Backend } from "./base";
export { NtfySH } from "./ntfy-sh";
const backends = [
new NtfySH()
];
/**
* Iterates through all the database notifications for current time
* and triggers the notification using specified backends in the config.
*/
export async function remind(config: Config, db: NotificationDatabase) {
const now = dayjs().format("HH:mm");
const notifications = db[now] ?? [];
for (const notification of notifications) {
for (const backend of backends) {
backend.remind(config, notification);
await snooze(1500);
}
}
}
function snooze(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}

View File

@@ -1,27 +1,25 @@
import { BackendSettings } from "../types/config";
import { Notification } from "../types/notification";
import { Backend } from "./base";
type Config = {
url: string;
token: string;
topic: string;
}
topic?: string;
} & BackendSettings;
export class NtfySH extends Backend {
#config: Config;
export class NtfySH extends Backend<Config> {
public name = "ntfy.sh";
constructor(config: Config) {
super(config);
this.#config = config;
}
notify(notification: Notification): void {
fetch(`https://${this.#config.url}/${this.#config.topic}`, {
protected requiredFields = ['url', 'token'] as const;
protected notify(config: Config, notification: Notification): void {
fetch(`https://${config.url}/${config.topic || 'obsidian'}`, {
method: 'POST',
body: notification.text,
headers: {
'Title': notification.title,
'Authorization': `Bearer ${this.#config.token}`
'Authorization': `Bearer ${config.token}`
}
})
}

View File

@@ -1,21 +0,0 @@
import dayjs from "dayjs";
import { NotificationDatabase } from "../types/notification";
import { Backend } from "../backend";
/**
* Iterates through all the database notifications for current time
* and triggers the notification using specified backend.
*/
export async function remind(db: NotificationDatabase, backend: Backend) {
const now = dayjs().format("HH:mm");
const notifications = db[now] ?? [];
for (const notification of notifications) {
backend.notify(notification);
await snooze(1500);
}
}
function snooze(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}

View File

@@ -1 +1,12 @@
export type BackendConfig = Record<string, unknown>;
export type BackendSettings = {
enable?: boolean;
};
export type SupportedBackends = 'ntfy.sh';
export type BackendConfig = {
backend: SupportedBackends;
settings: BackendSettings;
}
export type Config = {
backend: Record<string, unknown>;
};