"use strict"; const httpStatus = require("http-status"); const moment = require("moment"); const generateControllers = require("../../core/controllers"); const { buildContext } = require("../../core/controllers"); const notificationService = require("./notification.service"); const notificationDetailService = require("./notification_detail.service"); const userService = require("../auth/user.service"); const userDeviceService = require("./user_device.service"); const eventInscriptionService = require("../events/events_inscriptions.service"); const { usersIdsComposer } = require("../../helpers/composes.helper"); const pushHelper = require("../../helpers/push.helper"); const notificationHelper = require("../../helpers/notification.helpers"); const { extractParamsFromRequest, handleErrorResponse, handleResultResponse, } = require("../../helpers/controller.helper"); const { get } = require("lodash"); // Module Name const MODULE_NAME = "[notification.controller]"; const controllerOptions = { MODULE_NAME }; async function _sendNotificationAllActiveUsers(notification) { let limit = 33; let page = 1; let totalRows = 0; let totalPages = -1; do { let offset = (page - 1) * limit; let result = await userService._getActiveUserIds(offset, limit, notification.recipients.country); if (totalPages == -1) { totalPages = Math.ceil(result.count / limit); } page = page + 1; let ids = result.rows.map(function (item) { return item.id; }); notificationService.sendNotificationToUsers(notification, ids); } while (page <= totalPages); return "OK"; } async function _sendNotificationAllActiveDevices(notification) { let limit = 33; let page = 1; let totalRows = 0; let totalPages = -1; do { let offset = (page - 1) * limit; let result = await userDeviceService._getActiveDeviceIds(offset, limit, notification.recipients.country); console.log(result); if (totalPages == -1) { totalPages = Math.ceil(result.count / limit); } page = page + 1; notificationService.sendNotificationToDevices(notification, result.rows); } while (page <= totalPages); return "OK"; } async function _getUserIdsForEventId(eventId, segment) { let userIds = []; switch (segment) { //Todos los inscritos tanto invitados como libres case "ALL_VALIDATED": userIds = await eventInscriptionService._getInscriptionByEventAndValidated(eventId, true); break; //Todos los de lista de espera tanto invitados como libres (Actualmente en invitados no hay lista de espera) case "ALL_NOT_VALIDATED": userIds = await eventInscriptionService._getInscriptionByEventAndValidated(eventId, false); break; //Solo invitados como actualmente no se usa codigo de reserva para los coles, vale con filtrar por aquellos que tengan codigo de reserva case "PARTNERS_ALL": userIds = await eventInscriptionService._getInscriptionByEventFromPartner(eventId); break; //Todos los inscritos al evento, tanto validados como en lista de espera default: //ALL userIds = await eventInscriptionService._getInscriptionByEvent(eventId); break; } return usersIdsComposer(userIds); } const extraControllers = { sendNotification: (config) => { /** * notificationSample = { * "title": "título de la notificación", * "body": "cuerpo de la notificación", * "recipients": { * OPCION 1- Unos usuarios determinados * "userIds": ["*" | "f428a317-6d1f-4eda-aa3e-22baff3f48d7", ...] * "segment": "ALL" | "LAST_YEAR" | "LAST_MONTH" * "country": "*" | "ES" | "MX" * * OPCION 2 - A todos los usuarios inscritos a un evento, se puede segmentar * "eventId": "xxx-xxx-xxx-xxx", * "segment": "ALL" | "ALL_VALIDATED" | "ALL_NOT_VALIDATED" | * "PARTNERS_ALL" | "PARTNERS_VALIDATED" | "PARTNERS_NOT_VALIDATED" | * "COLLEGE_ALL" | "COLLEGE_VALIDATED" | "COLLEGE_NOT_VALIDATED" * OPCION 3 - A todos los dispositivos activos de un país * "deviceIds": ["*" | "ExponentPushToken[YbOS1AIZjQbchZbxNaVRqC]", ...] * "country": "*" | "ES" | "MX" * }, * "data": { * "type": "message", * "title": "Título del mensaje", * "message": "Cuerpo del mensaje", * "button": { * "caption": "Etiqueta del boton", * "url": "https://www.site.es", * "screen": "", * "paramId": "23", * } * } *} */ return async (req, res, next) => { config = config || { scopes: [], }; const context = buildContext(req, config); let params = extractParamsFromRequest(req, res); let receipt = undefined; let userIds = undefined; let deviceIds = undefined; let eventId = undefined; let segment = undefined; let country = undefined; const { body } = req; if (!body.title) { return handleErrorResponse( controllerOptions.MODULE_NAME, "sendNotification", new Error("Missing message title"), res ); } if (!body.body) { return handleErrorResponse( controllerOptions.MODULE_NAME, "sendNotification", new Error("Missing body content"), res ); } // Evento? if (body.recipients.eventId) { eventId = body.recipients.eventId; segment = body.recipients.segment; } else if (body.recipients.userIds) { userIds = body.recipients.userIds; segment = body.recipients.segment; country = body.recipients.country; } else if (body.recipients.deviceIds) { deviceIds = body.recipients.deviceIds; country = body.recipients.country; } else { return handleErrorResponse( controllerOptions.MODULE_NAME, "sendNotification", new Error("Missing user Ids or event Ids or devices Ids"), res ); } try { let notification = notificationHelper.createNotification({ ...body, userId: context.user.id, }); if (userIds && userIds.length == 1 && userIds[0] == "*") { receipt = _sendNotificationAllActiveUsers(notification); } else if (deviceIds && deviceIds.length == 1 && deviceIds[0] == "*") { receipt = _sendNotificationAllActiveDevices(notification); } else { let _userIds = null; if (userIds) { _userIds = userIds; } else { if (eventId) { _userIds = await _getUserIdsForEventId(eventId, segment); } else { return handleErrorResponse( controllerOptions.MODULE_NAME, "sendNotification", new Error("Missing event and segment"), res ); } } if (_userIds) { receipt = notificationService.sendNotificationToUsers(notification, _userIds); } } return handleResultResponse(receipt, null, null, res, httpStatus.OK); } catch (error) { console.error(error); return handleErrorResponse(controllerOptions.MODULE_NAME, "sendNotification", error, res); } }; }, updateNotificationsWithReceipts: (config) => { return async (req, res, next) => { /*config = config || { scopes: [], }; const context = buildContext(req, config); let params = extractParamsFromRequest(req, res); let getNotificationsWithoutReceipt = async () => { let params = { where: {} }; return await notificationDetailService.fetchAll(params, context); } let receipt = await Promise.all(getUserDevicesList).then( function (userDeviceList) { return Promise.all(userDeviceList.map(buildMessagePromise)) }) .then(sendNotificationsPromise) */ }; }, registerDevice: (config) => { return async (req, res, next) => { config = config || { scopes: [], }; try { const context = buildContext(req, config); const userId = context.user && context.user.id ? context.user.id : null; let data = { token: req.body.token, valid: 1, country: req.body.country, userId, }; let params = extractParamsFromRequest(req, res, { includeAll: false, paginate: { limit: 1, page: 1 }, params: { token: data.token, }, }); console.log(req.body, data, params); // Buscamos el token y el usuario console.log(">> Busco el token", params.params); let result = await userDeviceService.fetchOne(params, context); if (result) { // Borramos el registro donde aparece el token console.log(">> Borro el registro del token", params.params, data, context); result = await userDeviceService.delete(params, context); } // Dar de alta el token console.log(">> Dar de alta el token", data); result = await userDeviceService.create(data, context); } catch (error) { console.error(error); } // En todo caso devolver OK al cliente return handleResultResponse("OK", null, null, res, httpStatus.OK); }; }, }; module.exports = generateControllers(notificationService, extraControllers, controllerOptions);