Merge reminder & backend features
This commit is contained in:
@@ -1,9 +1,28 @@
|
|||||||
import { BackendConfig } from "../types/config";
|
import { BackendSettings, Config } from "../types/config";
|
||||||
import { Notification } from "../types/notification";
|
import { Notification } from "../types/notification";
|
||||||
|
|
||||||
export abstract class Backend {
|
export abstract class Backend<C extends BackendSettings> {
|
||||||
constructor(config: BackendConfig) {
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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 { Backend } from "./base";
|
||||||
export { NtfySH } from "./ntfy-sh";
|
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));
|
||||||
|
}
|
||||||
@@ -1,27 +1,25 @@
|
|||||||
|
import { BackendSettings } from "../types/config";
|
||||||
import { Notification } from "../types/notification";
|
import { Notification } from "../types/notification";
|
||||||
import { Backend } from "./base";
|
import { Backend } from "./base";
|
||||||
|
|
||||||
type Config = {
|
type Config = {
|
||||||
url: string;
|
url: string;
|
||||||
token: string;
|
token: string;
|
||||||
topic: string;
|
topic?: string;
|
||||||
}
|
} & BackendSettings;
|
||||||
|
|
||||||
export class NtfySH extends Backend {
|
export class NtfySH extends Backend<Config> {
|
||||||
#config: Config;
|
public name = "ntfy.sh";
|
||||||
|
|
||||||
constructor(config: Config) {
|
protected requiredFields = ['url', 'token'] as const;
|
||||||
super(config);
|
|
||||||
this.#config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
notify(notification: Notification): void {
|
protected notify(config: Config, notification: Notification): void {
|
||||||
fetch(`https://${this.#config.url}/${this.#config.topic}`, {
|
fetch(`https://${config.url}/${config.topic || 'obsidian'}`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: notification.text,
|
body: notification.text,
|
||||||
headers: {
|
headers: {
|
||||||
'Title': notification.title,
|
'Title': notification.title,
|
||||||
'Authorization': `Bearer ${this.#config.token}`
|
'Authorization': `Bearer ${config.token}`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
|
||||||
}
|
|
||||||
@@ -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>;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user