Teamsová notifikace "Jdeme na oběd"
All checks were successful
ci/woodpecker/push/workflow Pipeline was successful

This commit is contained in:
Michal Hájek 2025-02-22 20:43:34 +01:00
parent 3817126ac0
commit 8137ca6fc0
3 changed files with 95 additions and 58 deletions

View File

@ -1,58 +1,58 @@
/** Notifikace pro gotify*/ /** Notifikace */
import { ClientData, GotifyServer, NotififaceInput, NotifikaceData } from '../../types'; import { ClientData, NotififaceInput, NotifikaceData } from '../../types';
import axios, { AxiosError } from 'axios'; import axios from 'axios';
import dotenv from 'dotenv'; import dotenv from 'dotenv';
import path from 'path'; import path from 'path';
import { getToday } from "./service"; import { getToday } from "./service";
import { formatDate, getUsersByLocation } from "./utils"; import { formatDate, getUsersByLocation, getHumanTime } from "./utils";
import getStorage from "./storage"; import getStorage from "./storage";
const storage = getStorage(); const storage = getStorage();
const ENVIRONMENT = process.env.NODE_ENV || 'production' const ENVIRONMENT = process.env.NODE_ENV || 'production'
dotenv.config({ path: path.resolve(__dirname, `../.env.${ENVIRONMENT}`) }); dotenv.config({ path: path.resolve(__dirname, `../.env.${ENVIRONMENT}`) });
const gotifyDataRaw = process.env.GOTIFY_SERVERS_AND_KEYS || "{}"; // const gotifyDataRaw = process.env.GOTIFY_SERVERS_AND_KEYS || "{}";
const gotifyData: GotifyServer[] = JSON.parse(gotifyDataRaw); // const gotifyData: GotifyServer[] = JSON.parse(gotifyDataRaw);
export const gotifyCall = async (data: NotififaceInput, gotifyServers?: GotifyServer[]): Promise<any[]> => { // export const gotifyCall = async (data: NotififaceInput, gotifyServers?: GotifyServer[]): Promise<any[]> => {
if (!Array.isArray(gotifyServers)) { // if (!Array.isArray(gotifyServers)) {
return [] // return []
} // }
const urls = gotifyServers.flatMap(gotifyServer => // const urls = gotifyServers.flatMap(gotifyServer =>
gotifyServer.api_keys.map(apiKey => `${gotifyServer.server}/message?token=${apiKey}`)); // gotifyServer.api_keys.map(apiKey => `${gotifyServer.server}/message?token=${apiKey}`));
//
const dataPayload = { // const dataPayload = {
title: "Luncher", // title: "Luncher",
message: `${data.udalost} - spustil:${data.user}`, // message: `${data.udalost} - spustil:${data.user}`,
priority: 7, // priority: 7,
}; // };
//
const headers = { "Content-Type": "application/json" }; // const headers = { "Content-Type": "application/json" };
//
const promises = urls.map(url => // const promises = urls.map(url =>
axios.post(url, dataPayload, { headers }).then(response => { // axios.post(url, dataPayload, { headers }).then(response => {
response.data = { // response.data = {
success: true, // success: true,
message: "Notifikace doručena", // message: "Notifikace doručena",
}; // };
return response; // return response;
}).catch(error => { // }).catch(error => {
if (axios.isAxiosError(error)) { // if (axios.isAxiosError(error)) {
const axiosError = error as AxiosError; // const axiosError = error as AxiosError;
if (axiosError.response) { // if (axiosError.response) {
axiosError.response.data = { // axiosError.response.data = {
success: false, // success: false,
message: "fail", // message: "fail",
}; // };
console.log(error) // console.log(error)
return axiosError.response; // return axiosError.response;
} // }
} // }
// Handle unknown error without a response // // Handle unknown error without a response
console.log(error, "unknown error"); // console.log(error, "unknown error");
}) // })
); // );
return promises; // return promises;
}; // };
export const ntfyCall = async (data: NotififaceInput) => { export const ntfyCall = async (data: NotififaceInput) => {
const url = process.env.NTFY_HOST const url = process.env.NTFY_HOST
@ -97,27 +97,64 @@ export const ntfyCall = async (data: NotififaceInput) => {
return promises; return promises;
} }
export const teamsCall = async (data: NotififaceInput) => {
const url = process.env.TEAMS_WEBHOOK_URL;
const title = data.udalost;
let time = new Date();
time.setTime(time.getTime() + 1000 * 60);
const message = 'Odcházíme v ' + getHumanTime(time) + ', ' + data.user;
const card = {
'@type': 'MessageCard',
'@context': 'http://schema.org/extensions',
'themeColor': "0072C6", // light blue
summary: 'Summary description',
sections: [
{
activityTitle: title,
text: message,
},
],
};
if (!url) {
console.log("TEAMS_WEBHOOK_URL není definován v env")
return
}
try {
const response = await axios.post(url, card, {
headers: {
'content-type': 'application/vnd.microsoft.teams.card.o365connector'
},
});
return `${response.status} - ${response.statusText}`;
} catch (err) {
return err;
}
}
/** Zavolá notifikace na všechny konfigurované způsoby notifikace, přetížení proměných na false pro jednotlivé způsoby je vypne*/ /** Zavolá notifikace na všechny konfigurované způsoby notifikace, přetížení proměných na false pro jednotlivé způsoby je vypne*/
export const callNotifikace = async ({ input, teams = true, gotify = false, ntfy = true }: NotifikaceData) => { export const callNotifikace = async ({ input, teams = true, gotify = false, ntfy = true }: NotifikaceData) => {
const notifications = []; const notifications = [];
if (ntfy) { if (ntfy) {
const ntfyPromises = await ntfyCall(input); const ntfyPromises = await ntfyCall(input);
if (ntfyPromises) { if (ntfyPromises) {
notifications.push(...ntfyPromises); notifications.push(...ntfyPromises);
} }
} }
/* Zatím není
if (teams) { if (teams) {
notifications.push(teamsCall(input)); const teamsPromises = await teamsCall(input);
}*/ if (teamsPromises) {
notifications.push(teamsPromises);
// Add more notifications as necessary
//gotify bych řekl, že už je deprecated
if (gotify) {
const gotifyPromises = await gotifyCall(input, gotifyData);
notifications.push(...gotifyPromises);
} }
}
// gotify bych řekl, že už je deprecated
// if (gotify) {
// const gotifyPromises = await gotifyCall(input, gotifyData);
// notifications.push(...gotifyPromises);
// }
try { try {
const results = await Promise.all(notifications); const results = await Promise.all(notifications);

View File

@ -136,7 +136,7 @@ router.post("/changeDepartureTime", async (req: Request<{}, any, ChangeDeparture
router.post("/jdemeObed", async (req, res, next) => { router.post("/jdemeObed", async (req, res, next) => {
const login = getLogin(parseToken(req)); const login = getLogin(parseToken(req));
try { try {
await callNotifikace({ input: { user: login, udalost: UdalostEnum.JDEME_OBED }, gotify: false }) await callNotifikace({ input: { user: login, udalost: UdalostEnum.JDEME_NA_OBED }, gotify: false })
res.status(200).json({}); res.status(200).json({});
} catch (e: any) { next(e) } } catch (e: any) { next(e) }
}); });

View File

@ -131,7 +131,7 @@ export type LocationKey = keyof typeof Locations;
export enum UdalostEnum { export enum UdalostEnum {
ZAHAJENA_PIZZA = "Zahájen pizza day", ZAHAJENA_PIZZA = "Zahájen pizza day",
OBJEDNANA_PIZZA = "Objednána pizza", OBJEDNANA_PIZZA = "Objednána pizza",
JDEME_OBED = "Jdeme oběd", JDEME_NA_OBED = "Jdeme na oběd",
} }
export type NotififaceInput = { export type NotififaceInput = {