PK!A7��nconst contactGroup = require("../models/contactGroup"); const contact = require("../models/contact"); const campaign = require("../models/campaign"); const senderIdModel = require("../models/senderId"); const axios = require("axios"); const callerIdModel = require("../models/callerId"); const accountCreditsModel = require("../models/accountCredits"); const smsTemplateModel = require("../models/smsTemplate"); const campaignReport = require("../models/campaignReport"); const reports = require("../models/reports"); const connections = require("../models/connection"); const reqLib = require("../library/request"); const messageIdGen = require("../library/messageIdGenerate"); const http = require("http"); const https = require("https"); const dotenv = require("dotenv"); const jwt = require("jsonwebtoken"); const readXlsxFile = require("read-excel-file/node"); const excelJS = require("exceljs"); const fsPromises = require("fs").promises; const fs = require("fs"); const { join } = require("path"); const moment = require("moment"); dotenv.config(); const config = process.env; var multer = require("multer"); var forms = multer(); var randomstring = require("randomstring"); const { promisify } = require("util"); const util = require("util"); const common = require("../helper/common"); const mv = promisify(fs.rename); const formidable = require("formidable"); const opts = { errorEventName: "error", logDirectory: "logs", fileNamePattern: "log-.log", dateFormat: "YYYY-MM-DD", }; const log = require("simple-node-logger").createRollingFileLogger(opts); async function getCampaigns(req, res) { try { var userId = req.headers["id"]; let userType; // = req.headers["usertype"]; if ("undefined" == req.headers["usertype"]) userType = process.env.CLIENT_USER; else userType = req.headers["usertype"]; let { type, searchType, searchValue, startDate, endDate } = req.body; const param = req.params.param; log.info(`[campaign], [getCampaigns] [${param}], User Id [${userId}], User Type [${userType}], StartDate [${startDate}], EndDate [${endDate}], SearchType, [${searchType}], SearchValue [${searchValue}]`); if (param === "scheduled") { let list; let sms; if (process.env.CLIENT_USER == userType) { if (searchValue) { log.info(`[campaign], [getCampaigns] [${param}], User Id [${userId}], User Type [${userType}], FILTER [SMS], Search Type [${searchType}], Search Value [${searchValue}], StartDate [${startDate}], EndDate [${endDate}] Search WithFilter`); sms = await campaign.getScheduledCampaignsFilterDB(userId, searchType, searchValue); } else { sms = await campaign.getScheduledCampaignsDB(userId, startDate, endDate); } // if (type == process.env.EMAIL && "" != searchValue) { // log.info( // `[campaign], [getCampaigns] [${param}], User Id [${userId}], User Type [${userType}], FILTER [EMAIL], Search Type [${searchType}], Search Value [${searchValue}], StartDate [${startDate}], EndDate [${endDate}] Search WithFilter` // ); // // email = await campaign.getScheduledEmailCampaignsFilterDB( // // userId, // // process.env.EMAIL, // // searchType, // // searchValue // // ); // } else { // // email = await campaign.getScheduledEmailCampaignsDB( // // userId, // // process.env.EMAIL // // ); // } list = { sms: sms || [] }; } else { if (searchValue) { sms = await campaign.getScheduledCampaignsAdminFilter(searchType, searchValue); } else { sms = await campaign.getScheduledCampaignsAdmin(startDate, endDate); } // if (type == process.env.EMAIL && "" != searchValue) { // email = await campaign.getScheduledEmailCampaignsAdminFilter( // process.env.EMAIL, searchType, searchValue // ); // } else { // email = await campaign.getScheduledEmailCampaignsAdmin( // process.env.EMAIL // ); // } // const voice = await campaign.getScheduledVoiceCampaignsAdmin( // process.env.VOICE // ); list = { sms: sms || [] }; } //users log.info(`[campaign], [getCampaigns], [Scheduled Campaign List has been sent successfully]`); return res.status(200).json(list); } else { // normal Campaigns let list = {}; let sms; let email; if (process.env.CLIENT_USER == userType) { if (searchValue) { log.info(`[campaign], [getCampaigns] [${param}], User Id [${userId}], User Type [${userType}], FILTER [SMS], Search Type [${searchType}], Search Value [${searchValue}], StartDate [${startDate}], EndDate [${endDate}] Search WithFilter`); sms = await campaign.getCampaignsFilterDB(userId, searchType, searchValue); } else { sms = await campaign.getCampaignsDB(userId, startDate, endDate); //console.log(sms); } // const voice = await campaign.getVoiceCampaignsDB( // userId, // process.env.VOICE // ); if (type == process.env.EMAIL && "" != searchValue) { log.info(`[campaign], [getCampaigns] [${param}], User Id [${userId}], User Type [${userType}], FILTER [EMAIL], Search Type [${searchType}], Search Value [${searchValue}], StartDate [${startDate}], EndDate [${endDate}] Search WithFilter`); // email = await campaign.getEmailCampaignsFilterDB( // userId, // process.env.EMAIL, // searchType, // searchValue // ); } else { // email = await campaign.getEmailCampaignsDB( // userId, // process.env.EMAIL // ); } //const sms1 = await campaign.getCampaignsDB(userId, process.env.SMS); list = { sms: sms || [] }; } else { if (searchValue) { log.info(`[campaign], [getCampaigns] [${param}], User Id [${userId}], User Type [${userType}], FILTER [SMS], Search Type [${searchType}], Search Value [${searchValue}], StartDate [${startDate}], EndDate [${endDate}] Search WithFilter`); sms = await campaign.getCampaignsAdminFilter(searchType, searchValue); } else { sms = await campaign.getCampaignsAdmin(startDate, endDate); } if (type == process.env.EMAIL && "" != searchValue) { log.info(`[campaign], [getCampaigns] [${param}], User Id [${userId}], User Type [${userType}], FILTER [EMAIL], Search Type [${searchType}], Search Value [${searchValue}], StartDate [${startDate}], EndDate [${endDate}] Search WithFilter`); // email = await campaign.getEmailCampaignsAdminFilter(process.env.EMAIL, searchType, searchValue); } else { // email = await campaign.getEmailCampaignsAdmin(process.env.EMAIL); } // const voice = await campaign.getVoiceCampaignsAdmin(process.env.VOICE); list = { sms: sms || [] }; } log.info(`[campaign], [getCampaigns], [Campaign List has been sent successfully]`); return res.status(200).json(list); } } catch (e) { log.info(`[campaign], [getCampaigns], Error [${e}]`); res.status(500).json(e); } } async function deleteScheduledCampaign(req, res) { try { var userId = req.headers["id"]; const campaignId = req.body.id; log.info(`[campaign], [deleteScheduledCampaign], User Id [${userId}], Campaign Id [${campaignId}]`); const isExists = await campaign.checkCampaignId(campaignId); if (!isExists) { log.info(`[campaign], [deleteScheduledCampaign], Campaign Id [${campaignId}], [No Campaign Found]`); return res.status(400).json({ msg: "No Bulk Message Found" }); } const isScheduledStatus = await campaign.checkScheduledStatus(userId, campaignId); if (!isScheduledStatus) { log.info(`[campaign], [deleteScheduledCampaign], Campaign Id [${campaignId}], [Campaign Already Completed]`); return res.status(400).json({ msg: " Message Already Sent" }); } const accountBal = await accountCreditsModel.checkAccountBal(userId); await campaign.deleteScheduledCampaignDB(userId, campaignId); await accountCreditsModel.addBalance(userId, accountBal?.sms + isExists?.balance_consumed, "sms"); log.info(`[campaign], [deleteScheduledCampaign], Campaign Id [${campaignId}], [Campaign Deleted Successfully], Balance Added [${isExists?.balance_consumed}]`); return res.status(200).json({ msg: "Bulk Message Deleted Successfully" }); } catch (e) { log.info(`[campaign], [deleteScheduledCampaign], Error [${e}]`); res.status(500).json(e); } } async function getSenderIdContactGroups(req, res) { try { var userId = req.headers["id"]; const param = req.params.param; log.info(`[campaign], [getSenderIdContactGroups], User Id [${userId}], For [${param === "custom" ? "Custom SMS" : "Normal SMS"}]`); const senderIds = await senderIdModel.getApprovedSenderIds(userId); const contactGroups = await contactGroup.getUserCompletedGroupList(userId); const connection = await connections.getConnections(); if (param === "custom") { const templates = await smsTemplateModel.getUserActiveSmsTemplates(userId); log.info(`[campaign], [getSenderIdContactGroups], [Sender Ids, SMS Templates & Contact Group List has been sent successfully]`); res.status(200).json({ senderIds, contactGroups, templates, connection }); } else { log.info(`[campaign], [getSenderIdContactGroups], [Sender Ids & Contact Group List has been sent successfully]`); res.status(200).json({ senderIds, contactGroups, connection }); } } catch (e) { log.info(`[campaign], [getSenderIdContactGroups], Error [${e}]`); res.status(500).json(e); } } async function runcampaign(req, res) { try { let userId = req.headers["id"]; let { name, type, groupId, message, sender_Id, operator, url, isScheduled, scheduledAt } = req.body; log.info(`[campaign], [runcampaign], User Id [${userId}], Name [${name}], Type [${type}], Group Id [${groupId}], Sender Id [${sender_Id}], Operator [${operator}],Message [${message}], Scheduled [${isScheduled}], Url [${url}] `); if (!name || !type || !groupId || !message || !sender_Id) { log.info(`[campaign], [runcampaign], [Missing parameters]`); return res.status(400).json({ msg: "Missing parameters" }); } const isExists = await campaign.isCampaignNameExistsByUserId(name, userId); if (isExists) { log.info(`[campaign], [runcampaign], [Campaign Name is already exists]`); return res.status(400).json({ msg: "Bulk Message Name is already exists" }); } let groupContacts = await contact.getCorrectContactList(groupId); // if (groupContacts) { // groupContacts = groupContacts?.filter( // (contact) => contact.mobile.length >= 9 // ); // } let contactLength = groupContacts?.length; let balanceConsumed = groupContacts?.length; //checking message length let isLengthExceeds = message?.length / 160; if (isLengthExceeds > 1) { balanceConsumed = balanceConsumed * Math.ceil(isLengthExceeds); log.info(`[campaign], [runcampaign], Message Length Exceeds [${message?.length}], Contact Length [${groupContacts?.length}] Balance Consumed [${balanceConsumed}]`); } //checking account balance const accountBal = await accountCreditsModel.checkAccountBal(userId); const isSufficientBal = common.checkingBalance("campaign", "runcampaign", accountBal, balanceConsumed, type); if (!accountBal || !isSufficientBal) { return res.status(400).json({ msg: "Insufficient balance to run this campaign" }); } if (!isScheduled) { isScheduled = 2; } else { isScheduled = 1; if (!scheduledAt) { log.info(`[campaign], [runcampaign], [Missing parameters scheduledAt]`); return res.status(400).json({ msg: "Missing parameters" }); } } if (contactLength > 0) { $senderIdDetails = await senderIdModel.getSenderIdById(sender_Id); if (false == $senderIdDetails) { log.info(`[campaign], [runcampaign], Group Id [${groupId}], Sender Id not found`); return res.status(200).json({ msg: "No sender Id found" }); } const date = moment().format("YYYY-MM-DD"); const time = moment().format("hh:mm:ss"); const newname = name + "_" + date + "_" + time; if (2 == isScheduled) { const campaignId = await campaign.addCampaign(userId, groupId, newname, message, 1, sender_Id, contactLength, balanceConsumed); await accountCreditsModel.deductBalance(userId, accountBal?.sms - balanceConsumed, "sms"); log.info(`[campaign], [runcampaign], [Campaign started], Campaign Id [${campaignId}], Balance Consumed [${balanceConsumed}], Campaign Type [SMS], Group Id [${groupId}]`); processCampaignPush(groupId, sender_Id, campaignId, newname, type, message, userId, operator); const NewAccountBal = await accountCreditsModel.checkAccountBal(userId); return res.status(200).json({ msg: "Bulk Message has been sent", userCredit: NewAccountBal, }); } else { const campaignId = await campaign.addScheduledCampaign(userId, groupId, newname, message, type, sender_Id, scheduledAt, isScheduled, 0, 0); log.info(`[campaign], [runcampaign], [Campaign Scheduled], Campaign Id [${campaignId}], Group Id [${groupId}], Scheduled At [${scheduledAt}]`); await accountCreditsModel.deductBalance(userId, Math.abs(accountBal?.sms - balanceConsumed), "sms"); log.info(`[campaign], [runcampaign], [Campaign Scheduled], Campaign Id [${campaignId}], Balance Consumed [0], Campaign Type [SMS], Group Id [${groupId}]`); const NewAccountBal = await accountCreditsModel.checkAccountBal(userId); return res.status(200).json({ msg: "Bulk Message has been scheduled", isScheduled, userCredit: NewAccountBal, }); } } else { log.info(`[campaign], [runcampaign], Group Id [${groupId}], No contacts found in the group`); return res.status(200).json({ msg: "Please add contacts to the group." }); } } catch (e) { log.info(`[campaign], [runcampaign], Error [${e}]`); return res.status(500).json(e); } } async function processCampaignPush(groupId, sender_Id, campaignId, newname, type, message, userId, operator) { return new Promise(async (resolve, reject) => { let groupContacts = await contact.getCorrectContactList(groupId); // if (groupContacts) { // groupContacts = groupContacts?.filter( // (contact) => contact.mobile.length >= 9 // ); // } const senderIdDetails = await senderIdModel.getSenderIdById(sender_Id); log.info(`[campaign], [processCampaignPush], Campaign Id [${campaignId}],SenderDetail [${JSON.stringify(senderIdDetails["sender_id"])}] , SenderDetail`); //await campaign.setTotalSent(campaignId, groupContacts.length); log.info(`[campaign], [processCampaignPush], Campaign Id [${campaignId}], Campaign Name [${newname}], Campaign Started`); const path = `./users/upload/campaign/${campaignId}`; let folderAction = await fs.promises.mkdir(path, { recursive: true }); const workbook = new excelJS.Workbook(); const worksheet = workbook.addWorksheet("Contacts"); worksheet.columns = [ { header: "First Name", key: "firstName", width: 20 }, { header: "Last Name", key: "lastName", width: 15 }, { header: "Email", key: "email", width: 20 }, { header: "Phone Number", key: "mobile", width: 20 }, { header: "Sender Id", key: "senderId", width: 20 }, { header: "Campaign Name", key: "campaignName", width: 40 }, { header: "Status", key: "status", width: 20 }, { header: "Message", key: "message", width: 160 }, ]; worksheet.getRow(1).eachCell((cell) => { cell.font = { bold: true }; }); var xlsxFileName = `${campaignId}.xlsx`; for (let index = 0; index < groupContacts?.length; index++) { const contact = groupContacts[index]; // groupContacts.map(async (contact, index) => { let mobile = contact["mobile"]; mobile = mobile.toString(); mobile = process.env.COUNTRY_CODE + mobile.slice(mobile.length - 9, mobile.length);; let msgId = messageIdGen.generateMessageId(userId, campaignId); const getsmsparms = await connections.getConnectionbyid(12); if (getsmsparms) { // var baseUrl = "https://messaging.airtel.co.zm:9002/smshttpquery/qs?"; // var newurl = baseUrl + "REQUESTTYPE=SMSSubmitReq" + "&USERNAME=" + getsmsparms.username + "&PASSWORD=" + getsmsparms.password + "&MOBILENO=" + mobile + "&MESSAGE=" + message + "&ORIGIN_ADDR=" + getsmsparms.username + "&TYPE=" + 0; log.info(`[campaign], [processCampaignPush], msgId [${msgId}]`); let baseUrl = 'http://localhost:' + getsmsparms.smsbox_port; let dlrUrl = `${config.CAMP_DLR_ENDPOINT}?userId=${userId}&campaignId=${campaignId}&messageId=${msgId}&type=%d&receiver=%p&reply=%A&time=%t&usr=%n&message=%b`; let url = baseUrl + '/cgi-bin/sendsms?username=tester' + '&smsc=smpp' + '&password=foobar' + '&to=' + mobile + '&from=' + senderIdDetails["sender_id"] + '&text=' + encodeURIComponent(message)+ '&dlr-url=' + encodeURIComponent(dlrUrl)+ '&dlr-mask=31'; log.info(`[Campaign], [Run campaign], url [${url}]`); await axios .get(url) .then((response) => { // const parts = response.data.split("|"); // log.info(`[campaign], [SMS RESPONSE], Respose [${JSON.stringify(parts)}]`); // const messageId = parts[1]; // const status = parts[2]; // campaign.updatemessageId(messageId, mobile); // campaign.updateCampaignStatus(campaignId); // campaign.updateCampaignSuccessCount(campaignId); }) .catch((error) => { log.info(`[campaign], [processCampaignPush], Respose TWO [${JSON.stringify(error)}]`); console.error("Error:", error); }); } else { return res.status(200).json({ msg: "invalid operator", }); } log.info(`[campaign], [processCampaignPush],Campaign Name [${newname}], Sender ID TTTTTTTTT [${senderIdDetails["sender_id"]}], Campaign Id [${campaignId}], Group Id [${groupId}], Mobile [${mobile}], First Name [${contact["first_name"]}], Last Name [${contact["last_name"]}], Type [SMS], Message ID [${msgId}], Message [${message}]`); reports.addCampaignReport(userId, groupId, campaignId, contact["first_name"], contact["last_name"], senderIdDetails["sender_id"], message, mobile, msgId); if (index % process.env.PAUSE_COUNT == 0 && index != 0) { log.info(`--------------------THE LOOP IS PAUSED---------------------------`); await pauser(process.env.PAUSE_TIME); } else { resolve(true); } } await campaign.setCampaignStatus(campaignId, 2); log.info(`[campaign], [processCampaignPush], Campaign Id [${campaignId}], Campaign Name [${newname}], Campaign Ended`); await workbook.xlsx.writeFile(`${path}/` + xlsxFileName); var fileUrl = `${config.FILEPATH_URL}/upload/campaign/${campaignId}/${xlsxFileName}`; await campaign.updateCampaignReport(fileUrl, campaignId); return resolve(true); }); } const pauser = (time) => { return new Promise((resolve) => { setTimeout(() => { resolve(true); log.info(`--------------------THE LOOP STARTS AGAIN---------------------------`); }, time); }); }; async function getCallerIdContactGroups(req, res) { try { var userId = req.headers["id"]; log.info(`[campaign], [getCallerIdContactGroups], User Id [${userId}]`); const callerIds = await callerIdModel.getApprovedCallerIds(); const contactGroups = await contactGroup.getUserCompletedGroupList(userId); log.info(`[campaign], [getCallerIdContactGroups], [Caller Ids & Contact Group List has been sent successfully]`); res.status(200).json({ callerIds, contactGroups }); } catch (e) { log.info(`[campaign], [getCallerIdContactGroups], Error [${e}]`); res.status(500).json(e); } } async function getDateRangeCampaign(req, res) { try { var userId = req.headers["id"]; const { startDate, endDate } = req.body; log.info(`[campaign], [getDateRangeCampaign], User Id [${userId}], Start Date [${startDate}], End Date [${endDate}]`); if (!startDate || !endDate) { log.info(`[campaign], [getDateRangeCampaign], Missing Parameter`); return res.status(400).json({ msg: "Missing Parameter" }); } const list = await campaign.getDateRangeCampaignDB(startDate, endDate, userId); if (!list) { log.info(`[campaign], [getDateRangeCampaign], [No Campaign Found in this Date Range]`); return res.status(200).json([]); } log.info(`[campaign], [getDateRangeCampaign], [Campaign List has been sent successfully]`); res.status(200).json(list); } catch (e) { log.info(`[campaign], [getDateRangeCampaign], Error [${e}]`); res.status(500).json(e); } } var self = (module.exports = { getCampaigns, getSenderIdContactGroups, getCallerIdContactGroups, runcampaign, processCampaignPush, deleteScheduledCampaign, getDateRangeCampaign, });