All files / src/modules/notifiers gotify.ts

4% Statements 1/25
0% Branches 0/10
0% Functions 0/6
4.16% Lines 1/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74          1x                                                                                                                                        
import pino from "pino"
 
import { env } from "../../config"
import { AbstractNotifier } from "./notifier"
 
const logger = pino()
 
interface GetMessage {
  messages: {
    id: number
  }[]
}
 
export class GotifyNotifier extends AbstractNotifier {
  constructor() {
    super()
  }
 
  override async sendMessage(title: string, message: string): Promise<string> {
    const result = await fetch(`${env.gotifyUrl}/message`, {
      method: "POST",
      headers: { "Content-Type": "application/json", "X-Gotify-Key": env.gotifyToken },
      body: JSON.stringify({ title, message, extras: { "client::display": { contentType: "text/markdown" } } }),
    })
    if (!result.ok) {
      throw new Error(`Failed to send message to Gotify: ${result.status} ${result.statusText}`)
    }
    const data = await result.json()
    return `${data.id}`
  }
 
  override async deleteMessage(id: string): Promise<void> {
    if (await this.hasMessageId(id)) {
      const result = await fetch(`${env.gotifyUrl}/message/${id}?token=${env.gotifyUserToken}`, {
        method: "DELETE",
        headers: { "X-Gotify-Key": env.gotifyToken },
      })
      if (!result.ok) {
        throw new Error(`Failed to delete message with ID ${id} from Gotify: ${result.status} ${result.statusText}`)
      }
    } else {
      logger.debug({ id }, "Message ID does not exist, skipping deletion")
    }
  }
 
  override async deleteAllMessages(): Promise<void> {
    const result = await fetch(`${env.gotifyUrl}/application/${env.gotifyApplicationId}/message?token=${env.gotifyUserToken}`, {
      method: "DELETE",
      headers: { "X-Gotify-Key": env.gotifyToken },
    })
    if (!result.ok) {
      throw new Error(`Failed to delete all messages from Gotify: ${result.status} ${result.statusText}`)
    }
  }
 
  override async hasMessageId(messageId: string): Promise<boolean> {
    try {
      const result = await fetch(`${env.gotifyUrl}/application/${env.gotifyApplicationId}/message?token=${env.gotifyUserToken}`, {
        method: "GET",
        headers: { "X-Gotify-Key": env.gotifyToken },
      })
      if (!result.ok) {
        throw new Error(`Failed to fetch messages from Gotify: ${result.status} ${result.statusText}`)
      }
      const messages = (await result.json()) as GetMessage
      const ids = messages.messages.map((msg) => msg.id.toString())
      return ids.includes(messageId)
    } catch (error) {
      logger.error({ err: error }, "Error checking for message ID %s in Gotify:", messageId)
      return false
    }
  }
}