UNPKG

@cityssm/ntfy-publish

Version:

A Node package to publish notifications to an ntfy server.

131 lines (102 loc) 3.18 kB
import fs from 'node:fs/promises' import { ntfyMessagePriorityDefault } from './priorities.js' import type { FetchHeaders, NtfyMessageOptions } from './types.js' /** * The default ntfy server to use. */ export const DEFAULT_NTFY_SERVER = 'https://ntfy.sh' /** * @deprecated Use `DEFAULT_NTFY_SERVER` instead. */ export const DEFAULT_SERVER = DEFAULT_NTFY_SERVER /** * The default priority to use when sending a message. */ export const DEFAULT_NTFY_PRIORITY = ntfyMessagePriorityDefault /** * @deprecated Use `DEFAULT_NTFY_PRIORITY` instead. */ export const DEFAULT_PRIORITY = DEFAULT_NTFY_PRIORITY /** * Send a message through an ntfy server. * @param ntfyMessage The message to post. * @returns `true` if the message was posted. */ export default async function publish( ntfyMessage: NtfyMessageOptions ): Promise<boolean> { /* * Set Server */ let server = ntfyMessage.server ?? DEFAULT_NTFY_SERVER if (!server.endsWith('/')) { server += '/' } /* * Build Headers */ const messageHeaders: FetchHeaders = { Priority: ntfyMessage.priority ?? DEFAULT_NTFY_PRIORITY } if (ntfyMessage.title !== undefined) { messageHeaders.Title = ntfyMessage.title } if (ntfyMessage.tags !== undefined) { messageHeaders.Tags = ntfyMessage.tags.join(',') } if (ntfyMessage.clickURL !== undefined) { messageHeaders.Click = ntfyMessage.clickURL } if (ntfyMessage.iconURL !== undefined) { messageHeaders.Icon = ntfyMessage.iconURL } // Attachments let hasLocalAttachment = false if (ntfyMessage.fileAttachmentURL !== undefined) { hasLocalAttachment = !( ntfyMessage.fileAttachmentURL.toLowerCase().startsWith('http://') || ntfyMessage.fileAttachmentURL.toLowerCase().startsWith('https://') ) if (!hasLocalAttachment) { messageHeaders.Attach = ntfyMessage.fileAttachmentURL } } const fileData = hasLocalAttachment ? // eslint-disable-next-line security/detect-non-literal-fs-filename await fs.readFile(ntfyMessage.fileAttachmentURL as string) : undefined if (ntfyMessage.fileName !== undefined) { messageHeaders.Filename = ntfyMessage.fileName } // Cache if (Object.hasOwn(ntfyMessage, 'cache') && !(ntfyMessage.cache ?? true)) { messageHeaders.Cache = 'no' } /* * Send Message */ const response = await fetch(server + ntfyMessage.topic, { method: 'POST', body: hasLocalAttachment ? fileData : ntfyMessage.message ?? '', headers: messageHeaders as Record<string, string> }) return response.ok } export { ntfyMessagePrioritiesDefault, ntfyMessagePrioritiesHigh, ntfyMessagePrioritiesLow, ntfyMessagePrioritiesMax, ntfyMessagePrioritiesMin, ntfyMessagePriorityDefault, ntfyMessagePriorityHigh, ntfyMessagePriorityLow, ntfyMessagePriorityMax, ntfyMessagePriorityMin } from './priorities.js' export type { FetchHeaders, NtfyMessageOptions, NtfyMessagePriority } from './types.js' export { ntfyTagEmojis, isSupportedTagEmoji } from './emoji.js'