| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- import axios, { AxiosResponse, AxiosError } from 'axios';
- import dotenv from 'dotenv';
- import express, { NextFunction, Request, Response } from 'express';
- import firebaseAdmin from 'firebase-admin';
- import fsp from 'fs/promises';
- import path from 'path';
- dotenv.config();
- const STATIC_WEB_DIR = 'public';
- (async () => {
- try {
- const gcmSettings = JSON.parse(
- await fsp.readFile(process.env.GOOGLE_GLOUD_MESSAGING_CREDENTIALS ?? 'google-cloud/gcm-api.json', { encoding: 'utf-8' })
- );
- const server = express();
- const firebase = firebaseAdmin.initializeApp();
- server.get('/topics/:regToken', async (req, res, next) => {
- try {
- const regToken = req.params.regToken;
- const { apiToken } = gcmSettings;
- const response = await axios.get<any, AxiosResponse<any>>(`https://iid.googleapis.com/iid/info/${regToken}?details=true`, {
- headers: {
- Authorization: `key=${apiToken}`
- }
- });
- res.send(response.data);
- } catch (err) {
- next(err);
- }
- });
- server.put('/topics/:topic/:regToken', async (req, res, next) => {
- try {
- const topic = req.params.topic;
- const regToken = req.params.regToken;
- const response = await firebase.messaging().subscribeToTopic(regToken, topic);
- if (!response.failureCount) return res.send({ ok: true });
- throw response.errors;
- } catch (err) {
- next(err);
- }
- });
- server.delete('/topics/:topic/:regToken', async (req, res, next) => {
- try {
- const topic = req.params.topic;
- const regToken = req.params.regToken;
- const response = await firebase.messaging().unsubscribeFromTopic(regToken, topic);
- if (!response.failureCount) return res.send({ ok: true });
- throw response.errors;
- } catch (err) {
- next(err);
- }
- });
- server.get('/logo.png', async (req, res, next) => {
- try {
- const files = await fsp.readdir(STATIC_WEB_DIR, { encoding: 'utf-8' });
- const logo = files.find(file => file.includes('logo') && file.endsWith('.png'));
- if (!logo) {
- throw { type: 'http', message: 'File not found', status: 404 };
- }
- res.sendFile(path.resolve(STATIC_WEB_DIR, logo));
- } catch (err) {
- next(err);
- }
- });
- server.use('/', express.static(STATIC_WEB_DIR));
- server.use('**', express.static(path.join(STATIC_WEB_DIR, 'index.html')));
- server.use((err: any, req: Request, res: Response, next: NextFunction) => {
- let log = false;
- if (err instanceof AxiosError) {
- log = true;
- res.status(err.status ?? err.response?.status ?? 500).send(err.message);
- } else {
- const keys = Object.keys(err);
- if (keys.includes('type') && err.type === 'http') {
- res.status(err.status).send(err.message);
- } else {
- log = true;
- res.status(500).send(JSON.stringify(err));
- }
- }
- if (log) console.error('[ERROR] Webservice ErrorHandler caught:', err);
- });
- const port = Number(process.env.WEB_PORT ?? '80');
- server.listen(port, () => console.log('[FCM BACKEND] Webserver running at', `http://localhost:${port}`));
- } catch (err) {
- console.error(err);
- process.exit(1);
- }
- })();
|