diff --git a/controllers/url_token.controller.js b/controllers/url_token.controller.js new file mode 100644 index 0000000..30a1b4a --- /dev/null +++ b/controllers/url_token.controller.js @@ -0,0 +1,23 @@ +const { getTokenByUidDb } = require("../db/url_token.db"); + +class urlTokenController { + static async getUrlToken(req, res) { + try { + const { uid } = req.params; + + const data = await getTokenByUidDb(uid); + + if (!data) { + return res.status(404).send("Link tidak valid."); + } + + const targetUrl = `${process.env.BASE_URL_FRONTEND}/auth/redirect?token=${data.token}`; + + return res.redirect(targetUrl); + } catch (err) { + return err + } + } +} + +module.exports = urlTokenController; \ No newline at end of file diff --git a/db/url_token.db.js b/db/url_token.db.js new file mode 100644 index 0000000..b907410 --- /dev/null +++ b/db/url_token.db.js @@ -0,0 +1,29 @@ +const pool = require("../config"); + +const insertUrlTokenDb = async (data) => { + try { + const queryText = ` + INSERT INTO url_token (url_token_id, url_token) + VALUES ($1, $2) + `; + + const queryParams = [data.url_token_id, data.url_token]; + + const result = await pool.query(queryText, queryParams); + + return result; + } catch (err) { + return err; + } +}; + +const getTokenByUidDb = async (url_token_id) => { + const queryText = `SELECT * FROM url_token WHERE url_token_id = $1 AND deleted_at IS NULL`; + const result = await pool.query(queryText, [url_token_id]); + return result.recordset[0]; +}; + +module.exports = { + getTokenByUidDb, + insertUrlTokenDb, // Export fungsi baru +}; \ No newline at end of file diff --git a/package.json b/package.json index ee2d46c..3bc2bdb 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "nodemailer": "^6.8.0", "pg": "^8.8.0", "pino": "^6.11.3", + "pm2": "^6.0.14", "stripe": "^8.138.0", "svg-captcha": "^1.4.0", "swagger-ui-express": "^4.6.0", diff --git a/routes/index.js b/routes/index.js index fabe125..c6c6732 100644 --- a/routes/index.js +++ b/routes/index.js @@ -19,7 +19,8 @@ const notificationErrorSparepart = require("./notification_error_sparepart.route const sparepart = require("./sparepart.route") const notificationErrorLog = require("./notification_error_log.route") const notificationErrorUser = require("./notification_error_user.route") -const errorCode = require("./error_code.route") +const errorCode = require("./error_code.route"); +const notifikasiWA = require("./notifikasi-wa.route"); router.use("/auth", auth); router.use("/user", users); @@ -42,5 +43,6 @@ router.use("/sparepart", sparepart) router.use("/notification-log", notificationErrorLog) router.use("/notification-user", notificationErrorUser) router.use("/error-code", errorCode) +router.use("/notifikasi-wa", notifikasiWA) module.exports = router; diff --git a/routes/notifikasi-wa.route.js b/routes/notifikasi-wa.route.js new file mode 100644 index 0000000..8fd7b3a --- /dev/null +++ b/routes/notifikasi-wa.route.js @@ -0,0 +1,14 @@ +const express = require('express'); +const router = express.Router(); +const NotifikasiWaService = require('../services/notifikasi-wa.service'); + +router.post('/restart-wa', async (req, res) => { + try { + const result = await NotifikasiWaService.restartWhatsapp(); + return res.status(200).json(result); + } catch (error) { + return res.status(500).json(error); + } +}); + +module.exports = router; \ No newline at end of file diff --git a/services/notifikasi-wa.service.js b/services/notifikasi-wa.service.js index c6461c2..81d38ca 100644 --- a/services/notifikasi-wa.service.js +++ b/services/notifikasi-wa.service.js @@ -1,5 +1,8 @@ const { getAllContactDb } = require("../db/contact.db"); -const { InsertNotificationErrorDb, updateNotificationErrorDb } = require("../db/notification_error.db"); +const { + InsertNotificationErrorDb, + updateNotificationErrorDb, +} = require("../db/notification_error.db"); const { createNotificationErrorUserDb, updateNotificationErrorUserDb, @@ -11,6 +14,9 @@ const { } = require("../db/notification_wa.db"); const { getErrorCodeByBrandAndCodeDb } = require("../db/brand_code.db"); const { getDeviceNotificationByIdDb } = require("../db/notification_error.db"); +const { exec } = require("child_process"); +const fs = require("fs"); +const path = require("path"); class NotifikasiWaService { async onNotification(topic, message) { @@ -52,7 +58,10 @@ class NotifikasiWaService { Number(chanel.chanel_id) ); - const errorCode = await getErrorCodeByBrandAndCodeDb(deviceNotification?.brand_id ?? 0, chanel.value); + const errorCode = await getErrorCodeByBrandAndCodeDb( + deviceNotification?.brand_id ?? 0, + chanel.value + ); const data = { error_code_id: chanel.value, @@ -65,7 +74,7 @@ class NotifikasiWaService { const resultNotificationError = await InsertNotificationErrorDb(data); - let isSendNotification = false + let isSendNotification = false; for (const dataUser of dataUsers) { if (dataUser.is_active) { @@ -81,7 +90,9 @@ class NotifikasiWaService { const bodyMessage = `Hai ${dataUser.contact_name || "-"},\n` + - `Terjadi peringatan dengan kode ${chanel?.value ?? "-"} "${errorCode?.error_code_name ?? ""}", Chanel ${chanel?.chanel_id ?? "-"} ` + + `Terjadi peringatan dengan kode ${chanel?.value ?? "-"} "${ + errorCode?.error_code_name ?? "" + }", Chanel ${chanel?.chanel_id ?? "-"} ` + `pada device ${deviceNotification?.device_name ?? "berikut"},` + `\nSilahkan cek detail pada link :` + `${shortUrl}`; @@ -107,8 +118,6 @@ class NotifikasiWaService { param.bodyMessage ); - - await updateNotificationErrorUserDb( resultNotificationErrorUser[0].notification_error_user_id, { @@ -117,7 +126,7 @@ class NotifikasiWaService { ); if (resultSend.success) { - isSendNotification = resultSend.success + isSendNotification = resultSend.success; } } } @@ -131,11 +140,48 @@ class NotifikasiWaService { ); } } - } catch (error) { - // throw new ErrorHandler(error.statusCode, error.message); - return error; + } catch (err) { + return err; } } + + async restartWhatsapp() { + return new Promise((resolve, reject) => { + exec('pm2 jlist', (err, stdout) => { + if (err) return reject({ success: false, message: "Error list PM2" }); + + try { + const processes = JSON.parse(stdout); + const waProcess = processes.find(p => + p.name.toLowerCase().includes('whatsapp') || + p.name.toLowerCase().includes('wa-api') + ); + + if (!waProcess) return reject({ success: false, message: "PM2 List PM2 Not Found" }); + + const processId = waProcess.pm_id; + + exec(`pm2 stop ${processId}`, () => { + const paths = [ + path.join(__dirname, "../../.wwebjs_auth"), + path.join(__dirname, "../../.wwebjs_cache") + ]; + + paths.forEach(dir => { + if (fs.existsSync(dir)) fs.rmSync(dir, { recursive: true, force: true }); + }); + + exec(`pm2 restart ${processId}`, (reErr) => { + if (reErr) return reject({ success: false, message: "Gagal restart" }); + resolve({ success: true, message: `WA has been restart.` }); + }); + }); + } catch (e) { + reject({ success: false, message: "JSON Parse Error: " + e.message }); + } + }); + }); + } } -module.exports = new NotifikasiWaService(); +module.exports = new NotifikasiWaService(); \ No newline at end of file