PK!A7��nconst contactGroup = require("../models/contactGroup"); const contact = require("../models/contact"); const campaign = require("../models/campaign"); const senderIdModel = require("../models/senderId"); const accountCreditsModel = require("../models/accountCredits"); const campaignReport = require("../models/campaignReport"); const connections = require("../models/connection"); const smsTemplate = require("../models/smsTemplate"); const reports = require("../models/reports"); const reqLib = require("../library/request"); const messageIdGen = require("../library/messageIdGenerate"); const http = require("http"); const https = require("https"); const dotenv = require("dotenv"); const axios = require("axios"); 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 mv = promisify(fs.rename); var format = require("text-template"); const common = require("../helper/common"); const opts = { errorEventName: "error", logDirectory: "logs", fileNamePattern: "log-.log", dateFormat: "YYYY-MM-DD", }; const log = require("simple-node-logger").createRollingFileLogger(opts); async function runcampaign(req, res) { try { const userId = req.headers["id"]; let { name, type, groupId, message, sender_Id, templateId, isScheduled, scheduledAt, operator } = req.body; log.info(`[Custom Campaign], [runcampaign], User Id [${userId}], name [${name}], Type [${type}], Group Id [${groupId}], Sender Id [${sender_Id}], Operator [${operator}] Template Id [${templateId}]`); const isExists = await campaign.isCampaignNameExistsByUserId(name, userId); if (isExists) { log.info(`[Custom Campaign], [runcampaign], [Campaign Name is already exists]`); return res.status(400).json({ msg: "Campaign Name is already exists" }); } if (!name || !type || !groupId || !message || !sender_Id || !templateId) { log.info(`[Custom Campaign], [runcampaign], [Missing parameters]`); return res.status(400).json({ msg: "Missing parameters" }); } 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(`[Custom 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("Custom Campaign", "runcampaign", accountBal, balanceConsumed, type); if (!isSufficientBal) { return res.status(400).json({ msg: "Insufficient balance to run this campaign" }); } if (!isScheduled) { isScheduled = 2; } else { isScheduled = 1; if (!scheduledAt) { log.info(`[Custom Campaign], [runcampaign], [Missing parameters scheduledAt]`); return res.status(400).json({ msg: "Missing parameters" }); } } if (contactLength > 0) { let senderIdDetails = await senderIdModel.getSenderIdById(sender_Id); if (false == senderIdDetails) { log.info(`[Custom Campaign], [runcampaign], Campaign Id [], Group Id [${groupId}], Sender Id not found`); return res.status(400).json({ msg: "No sender Id found" }); } let template = await smsTemplate.getTemplateById(templateId); if (false == template) { log.info(`[Custom Campaign], [runcampaign], Group Id [${groupId}], Template Id [${templateId}], SMS template not found`); return res.status(400).json({ msg: "SMS template not found" }); } let customMessage = template["data"]; let mergeFields = template["merge_fields"]; let templateName = template["name"]; 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.addTemplateCampaign(userId, groupId, newname, customMessage, type, sender_Id, contactLength, templateId, balanceConsumed); const newAccountBalance = accountBal?.sms - balanceConsumed; await accountCreditsModel.deductBalance(userId, newAccountBalance, "sms"); log.info(`[Custom Campaign], [runcampaign], [Campaign started], Campaign Id [${campaignId}], Balance Consumed [${balanceConsumed}], Campaign Type [SMS], Group Id [${groupId}], Template Name [${templateName}]`); //const NewAccountBal = await accountCreditsModel.checkAccountBal(userId); processCampaignPush(groupId, sender_Id, campaignId, newname, type, customMessage, mergeFields, userId, operator, templateName); log.info(`[Custom Campaign], [runcampaign], CampaignCHECKKKK`); return res.status(200).json({ msg: "Campaign has been started", userCredit: newAccountBalance, }); } else { const campaignId = await campaign.addScheduleTemplateCampaign(userId, groupId, newname, customMessage, type, sender_Id, 0, templateId, 0, scheduledAt, isScheduled); log.info(`[Custom Campaign], [runcampaign], [Campaign Scheduled], Campaign Id [${campaignId}], Group Id [${groupId}]`); await accountCreditsModel.deductBalance(userId, accountBal?.sms - balanceConsumed, "sms"); log.info(`[Custom Campaign], [runcampaign], [Campaign started], Campaign Id [${campaignId}], Balance Consumed [0], Campaign Type [SMS], Group Id [${groupId}], Template Name [${templateName}]`); return res.status(200).json({ msg: "Campaign has been scheduled", isScheduled }); } } else { log.info(`[Custom Campaign], [runcampaign], Group Id [${groupId}], No contacts found in the group`); return res.status(400).json({ msg: "Please add contacts to the group." }); } } catch (e) { log.info(`[Custom Campaign], [runcampaign], Error [${e}]`); return res.status(500).json(e); } } async function processCampaignPush(groupId, sender_Id, campaignId, newname, type, customMessage, mergeFields, userId, operator, templateName) { return new Promise(async (resolve, reject) => { try { let groupContacts = await contact.getCorrectContactList(groupId); const senderIdDetails = await senderIdModel.getSenderIdById(sender_Id); // await campaign.setTotalSent(campaignId, groupContacts.length); log.info(`[campaign], SENDERID [${JSON.stringify(senderIdDetails)}] )}]`); log.info(`[campaign], [processCampaignPush], Campaign Id [${campaignId}], Campaign Name [${newname}], Campaign Started )}]`); log.info(`contact ${JSON.stringify(groupContacts)}`); const path = `./users/upload/campaign/${campaignId}`; let folderAction = await fs.promises.mkdir(path, { recursive: true }); var xlsxFileName = `${campaignId}.xlsx`; for (let index = 0; index < groupContacts?.length; index++) { // await groupContacts.map(async (contact) => { const contact = groupContacts[index]; let message = customMessage || ""; var fields = mergeFields.split(","); var jsonObj = {}; await fields.map((field) => { if (field.trim() == "First Name") { message = message.replace(/{{First Name}}/g, contact["first_name"]); } if (field.trim() == "Last Name") { message = message.replace(/{{Last Name}}/g, contact["last_name"]); } if (field.trim() == "Mobile Number") { message = message.replace(/{{Mobile Number}}/g, contact["mobile"]); } if (field.trim() == "Email") { message = message.replace(/{{Email}}/g, contact["email"]); } }); log.info(`[campaign], [processCampaignPush],Campaign Name [${newname}], Sender ID [${senderIdDetails["sender_id"]}], Campaign Id [${campaignId}], Group Id [${groupId}], Mobile [${contact["mobile"]}], First Name [${contact["first_name"]}], Last Name [${contact["last_name"]}], Type [SMS], Template Name [${templateName}], Message [${message}]`); const getsmsparms = await connections.getConnectionbyid(operator); let count = 0; if (getsmsparms) { var baseUrl = "https://messaging.airtel.co.zm:9002/smshttpquery/qs?"; var newurl = baseUrl + "REQUESTTYPE=SMSSubmitReq" + "&USERNAME=" + getsmsparms.username + "&PASSWORD=" + getsmsparms.password + "&MOBILENO=" + contact["mobile"] + "&MESSAGE=" + message + "&ORIGIN_ADDR=" + getsmsparms.username + "&TYPE=" + 0; log.info(`[Quick Message], [runQuickMessage], url [${newurl}]`); let count = 0; await axios .get(newurl) .then((response) => { const parts = response.data.split("|"); log.info(`[campaign], [runQuickMessage], Respose [${JSON.stringify(parts)}]`); 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],FUNCTION Caliing SendrId [${senderIdDetails["sender_id"]}]`); campaignReport.createCampaignReport(campaignId, groupId, userId, contact["first_name"], contact["last_name"], senderIdDetails["sender_id"], templateName, contact["mobile"], message); log.info(`[campaign], [processCampaignPush],FUNCTION ENding`); if (index % process.env.PAUSE_COUNT == 0 && index != 0) { log.info(`--------------------THE LOOP IS PAUSED---------------------------`); await pauser(process.env.PAUSE_TIME); } else { resolve(true); } } log.info(`[campaign], [processCampaignPush],UPDATING CAMPAIGN STATUS`); 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); } catch (error) { log.info(`[campaign], [processCampaignPush], Campaign Id [${campaignId}], ERROR [${error}] `); } }); } var self = (module.exports = { runcampaign, processCampaignPush, });