Subversion Repositories SmartDukaan

Rev

Rev 36064 | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.spice.profitmandi.service;

import com.google.gson.Gson;
import com.spice.profitmandi.common.enumuration.MessageType;
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.ProfitMandiConstants;
import com.spice.profitmandi.common.model.SendNotificationModel;
import com.spice.profitmandi.common.web.client.RestClient;
import com.spice.profitmandi.dao.entity.auth.AuthUser;
import com.spice.profitmandi.dao.entity.dtr.*;
import com.spice.profitmandi.dao.entity.fofo.Customer;
import com.spice.profitmandi.dao.entity.user.Device;
import com.spice.profitmandi.dao.entity.whatsapp.WhatsappMessage;
import com.spice.profitmandi.dao.model.SimpleCampaign;
import com.spice.profitmandi.dao.model.SimpleCampaignParams;
import com.spice.profitmandi.dao.repository.catalog.DeviceRepository;
import com.spice.profitmandi.dao.repository.cs.CsService;
import com.spice.profitmandi.dao.repository.cs.PartnerRegionRepository;
import com.spice.profitmandi.dao.repository.dtr.*;
import com.spice.profitmandi.dao.repository.fofo.CustomerRepository;
import com.spice.profitmandi.dao.repository.whatsapp.WhatsappMessageRepository;
import com.spice.profitmandi.service.user.RetailerService;
import com.spice.profitmandi.service.whatsapp.WhatsappMessageService;
import com.spice.profitmandi.service.whatsapp.WhatsappMessageType;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class NotificationServiceImpl implements NotificationService {

    private static final Logger LOGGER = LogManager.getLogger(NotificationServiceImpl.class);
    @Autowired
    UserCampaignRepository userCampaignRepository;
    @Autowired
    UserRepository dtrUserRepository;
    @Autowired
    UserAccountRepository userAccountRepository;
    @Autowired
    NotificationCampaignRepository notificationCampaignRepository;
    @Autowired
    DeviceRepository deviceRepository;

    @Autowired
    PartnerRegionRepository partnerRegionRepository;


    @Autowired
    FofoStoreRepository fofoStoreRepository;
    @Autowired
    CsService csService;
    @Autowired
    OptinRepository optinRepository;
    @Autowired
    RetailerService retailerService;
    @Autowired
    CustomerRepository customerRepository;
    @Autowired
    PushNotificationRepository pushNotificationRepository;
    @Autowired
    private Gson gson;
    @Autowired
    private RestClient restClient;
    @Value("${prod}")
    private boolean isProd;

    @Autowired
    private WhatsappMessageRepository whatsappMessageRepository;

    @Autowired
    private WhatsappMessageService whatsappMessageService;

    @Override
    public void sendNotification(SendNotificationModel sendNotificationModel) throws ProfitMandiBusinessException {

        SimpleCampaignParams scp = new SimpleCampaignParams();
        scp.setMessage(sendNotificationModel.getMessage());
        scp.setTitle(sendNotificationModel.getTitle());
        scp.setImageUrl(sendNotificationModel.getImageUrl());
        scp.setType(sendNotificationModel.getType());
        scp.setUrl(sendNotificationModel.getUrl());
        scp.setShowImage(sendNotificationModel.getShowImage());
        scp.setExpireTimestamp(sendNotificationModel.getExpiresat());
        SimpleCampaign sc = new SimpleCampaign(scp);
        sc.setSimpleCampaignParams(scp);

        NotificationCampaign nc = new NotificationCampaign();
        nc.setName(sendNotificationModel.getCampaignName());
        nc.setImplementationType("SimpleCampaign");
        nc.setImplementationParams(gson.toJson(scp));
        nc.setMessageType(sendNotificationModel.getMessageType());
        nc.setDocumentId(sendNotificationModel.getDocumentId());
        nc.setCreatedTimestamp(LocalDateTime.now());
        notificationCampaignRepository.persist(nc);

        Set<Integer> userIds = new HashSet<>();
        if (sendNotificationModel.getUserIds() != null && sendNotificationModel.getUserIds().size() > 0) {
            userIds.addAll(sendNotificationModel.getUserIds());
        }

        if (sendNotificationModel.getStateIds() != null && sendNotificationModel.getStateIds().size() > 0) {
            List<Integer> fofoIds = fofoStoreRepository.selectByWarehouseIds(sendNotificationModel.getStateIds()).stream()
                    .map(x -> x.getId()).collect(Collectors.toList());
            if (fofoIds.size() > 0) {
                userIds.addAll(userAccountRepository.selectUserIdsByRetailerIds(fofoIds));
            }

        }
        if(sendNotificationModel.getRegionIds() != null && sendNotificationModel.getRegionIds().size() > 0) {
            List<Integer> fofoIds = partnerRegionRepository.selectAllByRegionIds(sendNotificationModel.getRegionIds()).stream().map(x->x.getFofoId()).collect(Collectors.toList());
            if(fofoIds.size()>0) {
                userIds.addAll(userAccountRepository.selectUserIdsByRetailerIds(fofoIds));
            }
        }

        if (userIds.size() > 0) {
            for (Integer userId : userIds) {
                UserCampaign uc = new UserCampaign();
                uc.setCampaignId(nc.getId());
                uc.setUserId(userId);
                uc.setPushTimestamp(LocalDateTime.now());
                userCampaignRepository.persist(uc);
            }
            List<Device> devices = deviceRepository.selectByUserIdAndModifiedTimestamp(new ArrayList<>(userIds),
                    LocalDateTime.now().minusMonths(1), LocalDateTime.now());
            pushNotification(nc.getId(), devices);
        } else {
            LOGGER.info("Failed to send notification to any retailer with this model - {}", sendNotificationModel);
        }

    }

    @Override
    public void sendNotificationToAll(SendNotificationModel sendNotificationModel) throws ProfitMandiBusinessException {
        sendNotificationModel.setUserIds(fofoStoreRepository.selectAllDtrUserIds());
        Set<AuthUser> authUsers = new HashSet<>(
                csService.getAuthUserByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_RBM));
        authUsers.addAll(csService.getAuthUserByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_CATEGORY));
        authUsers.addAll(csService.getAuthUserByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_SALES));
        authUsers.addAll(csService.getAuthUserByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_ABM));
        List<String> emailIds = authUsers.stream().map(x -> x.getEmailId()).collect(Collectors.toList());
        emailIds.add("devkinandan.lal@smartdukaan.com");
        List<User> systemUsers = dtrUserRepository.selectAllByEmailIds(emailIds);
        sendNotificationModel.getUserIds()
                .addAll(systemUsers.stream().map(x -> x.getId()).collect(Collectors.toList()));
        this.sendNotification(sendNotificationModel);
    }

    @Override
    public void sendNotificationToSystemUsers(SendNotificationModel sendNotificationModel) throws ProfitMandiBusinessException {
        Set<AuthUser> authUsers = new HashSet<>(csService.getAuthUserByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_RBM));
        authUsers.addAll(csService.getAuthUserByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_CATEGORY));
        authUsers.addAll(csService.getAuthUserByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_SALES));
        authUsers.addAll(csService.getAuthUserByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_ABM));
        List<String> emailIds = authUsers.stream().map(x -> x.getEmailId()).collect(Collectors.toList());
        emailIds.add("devkinandan.lal@smartdukaan.com");
        List<User> systemUsers = dtrUserRepository.selectAllByEmailIds(emailIds);
        sendNotificationModel.setUserIds(systemUsers.stream().map(x -> x.getId()).collect(Collectors.toList()));
        this.sendNotification(sendNotificationModel);
    }

    @Override
    public void sendNotification(int fofoId, String campaignName, MessageType messageType, String title, String message)
            throws ProfitMandiBusinessException {
        SendNotificationModel sendNotificationModel = this.getDefaultNotificationModel();
        sendNotificationModel.setCampaignName(campaignName);
        sendNotificationModel.setMessageType(messageType);
        sendNotificationModel.setTitle(title);
        sendNotificationModel.setMessage(message);
        int userId = userAccountRepository.selectUserIdByRetailerId(fofoId);
        sendNotificationModel.setUserIds(Arrays.asList(userId));
        sendNotificationModel.setMessageType(MessageType.wallet);
        this.sendNotification(sendNotificationModel);
    }

    public SendNotificationModel getDefaultNotificationModel() {
        SendNotificationModel sendNotificationModel = new SendNotificationModel();
        sendNotificationModel.setType("url");
        sendNotificationModel.setUrl("https://app.smartdukaan.com/pages/home/notifications");
        sendNotificationModel.setExpiresat(LocalDateTime.now().plusDays(1));
        sendNotificationModel.setMessageType(MessageType.notification);
        return sendNotificationModel;
    }

    public void pushNotification(int cid, List<Device> devices) {

        for (Device device : devices) {
            PushNotifications pn = new PushNotifications();
            pn.setNotificationCampaignid(cid);
            pn.setDeviceId(device.getId());
            pn.setUserId(device.getUser_id());
            pushNotificationRepository.persist(pn);
        }

    }

    @Override
    public void sendNotification(int fofoId, String campaignName, MessageType messageType, String title, String message, String url) throws ProfitMandiBusinessException {
        SendNotificationModel sendNotificationModel = this.getDefaultNotificationModel();
        sendNotificationModel.setCampaignName(campaignName);
        sendNotificationModel.setMessageType(messageType);
        sendNotificationModel.setTitle(title);
        sendNotificationModel.setMessage(message);
        int userId = userAccountRepository.selectUserIdByRetailerId(fofoId);
        sendNotificationModel.setUserIds(Arrays.asList(userId));
        sendNotificationModel.setMessageType(messageType);
        sendNotificationModel.setUrl(url);
        this.sendNotification(sendNotificationModel);
    }

    @Override
    public boolean sendWhatsappMessage(String message, String title, String mobile) throws Exception {
        boolean isSend=false;
        LOGGER.info("Is Prod - {}", isProd);
        if (isProd) {
            isSend=this.sendWhatsappMessage(WhatsappMessageType.TEXT, message, title, mobile, null, null);
        }
        return isSend;
    }

    @Override
    public void sendADLDWhatsappMessage(String mobile) throws Exception {
        LOGGER.info("Is Prod - {}", isProd);
        if (isProd) {
            String message = "क्या आपने SmartDukaan Protect Plus Plan लिया है?\n\n" +
                    "सिर्फ ₹199 से शुरू, पाएं अपने मोबाइल के लिए 1 साल की स्मार्ट सुरक्षा —\n" +
                    "Liquid Damage Protection\n" +
                    "Accidental Damage Protection\n" +
                    "अपने फोन को महंगे रिपेयर खर्च से बचाएं।\n" +
                    "अभी जानकारी लें और अपने फोन को सुरक्षित बनाएं!";
            String title = "SmartDukaan से खरीदारी करने के लिए धन्यवाद!";

            this.sendWhatsappMessage(WhatsappMessageType.TEXT, message, title, mobile, null, null);
        }
    }

    @Override
    public boolean sendWhatsappInvoice(int customerId, int fofoId, String invoiceNumber, String whatsAppNo) throws Exception {
        boolean shouldSend = shouldSendWhatsappMessage(whatsAppNo);
        if (!shouldSend) return false;

        Customer customer = customerRepository.selectById(customerId);
        String mobileNumber = (whatsAppNo != null && !whatsAppNo.isEmpty()) ? whatsAppNo : customer.getMobileNumber();

        String message = "*SmartDukaan's One-Time Offer Unlocked!*\n" +
                "Thank you for your purchase.\n" +
                "\n" +
                "Abhi-abhi naya phone liya hai...\n" +
                "Par kya aapne uski poori suraksha li hai?\n" +
                "SmartDukaan par sabse kam daam mein plans available hain:\n" +
                "\n" +
                "*Complete Protection Plan* (Accidental & Liquid Damage) - Starting ₹199\n" +
                "\n" +
                "*Extended 1 Year Warranty* - ₹199 se shuru\n" +
                "\n" +
                "Abhi store par iski jaankari lein.\n" +
                "\n" +
                "*Ye offer phone ki kharidari ke sirf 24 hours tak hi valid hai!*";

        String mediaUrl = "https://partners.smartdukaan.com/wa-invoice-send/"
                + Base64.getMimeEncoder().encodeToString(invoiceNumber.getBytes(StandardCharsets.UTF_8)) + ".pdf";
        String fileName = "INV-" + invoiceNumber.replace("/", "-") + ".pdf";

        LOGGER.info("sendWhatsappInvoice: mobile={} mediaUrl={}", mobileNumber, mediaUrl);
        return sendWhatsappMediaMessage(message, mobileNumber, mediaUrl, fileName, WhatsappMessageType.DOCUMENT);
    }

    @Override
    public boolean sendWhatsappMediaMessage(String message, String mobile, String mediaUrl, String fileName, WhatsappMessageType whatsappMessageType) throws Exception {
        boolean isSend=false;
//        if (isProd) {
//            isSend=this.sendWhatsappMessage(whatsappMessageType, message, null, mobile, mediaUrl, fileName);
//        }
        isSend = this.sendWhatsappMessage(whatsappMessageType, message, null, mobile, mediaUrl, fileName);
        return isSend;
    }

    @Override
    public void optIn(String phoneNumber) throws Exception {
        Map<String, String> requestheaders = new HashMap<>();
        requestheaders.put("Content-Type", "application/x-www-form-urlencoded");
        Map<String, String> requestParams = new HashMap<>();
        requestParams.put("userid", String.valueOf(2000215976));
        requestParams.put("password", "MFRd!BBL");
        requestParams.put("phone_number", phoneNumber);
        requestParams.put("auth_scheme", "plain");
        requestParams.put("v", "1.1");
        requestParams.put("format", "json");

        requestParams.put("method", "OPT_IN");

        requestParams.put("channel", "WHATSAPP");
        String response = restClient.get("https://media.smsgupshup.com/GatewayAPI/rest", requestParams, requestheaders);
        LOGGER.info("response" + response);
    }

    private boolean sendWhatsappMessage(WhatsappMessageType whatsappMessageType, String message, String title, String mobile, String mediaUrl, String fileName)
            throws Exception {
        String sendTo = null;
        boolean isSend=false;
        if (mobile.length() != 10) {
            return isSend;
        } else {
            sendTo = 91 + mobile;
        }
        Map<String, String> requestheaders = new HashMap<>();
        requestheaders.put("Content-Type", "application/x-www-form-urlencoded");
        Map<String, String> requestParams = new HashMap<>();
        requestParams.put("userid", String.valueOf(2000215976));
        requestParams.put("password", "MFRd!BBL");
        requestParams.put("send_to", sendTo);
        requestParams.put("v", "1.1");
        requestParams.put("format", "json");
        requestParams.put("auth_scheme", "plain");
        Optin optin = optinRepository.selectByMobile(mobile);
        if (optin == null) {
            this.optIn(sendTo);
            optin = new Optin();
            optin.setCreated(LocalDateTime.now());
            optin.setMobile(mobile);
            optinRepository.persist(optin);
        }
        if (mediaUrl == null) {
            requestParams.put("method", "SENDMESSAGE");
            requestParams.put("msg_type", whatsappMessageType.name());
            requestParams.put("msg", message);
            requestParams.put("isTemplate", "true");
            requestParams.put("header", title);
        } else if (mediaUrl != null) {
            requestParams.put("method", "SENDMEDIAMESSAGE");
            requestParams.put("msg_type", whatsappMessageType.name());
            requestParams.put("caption", message);
            requestParams.put("media_url", mediaUrl);
            requestParams.put("filename", fileName);
        }
        String response = restClient.post("https://media.smsgupshup.com/GatewayAPI/rest", requestParams, requestheaders);
        LOGGER.info("response  - {}", response);

        JSONObject jsonObject = new JSONObject(response);

        JSONObject whatsappResponse = (JSONObject) jsonObject.get("response");
        if (whatsappResponse.getString("status").equals("error")) {
            LOGGER.error("Invalid Whatsapp message, Reason - {}", whatsappResponse.getString("details"));
            return isSend;
        }else{
            isSend=true;
        }
        String externalId = whatsappResponse.getString("id");
        String phone = whatsappResponse.getString("phone");

        WhatsappMessage whatsappMessage = new WhatsappMessage();
        whatsappMessage.setCreatedTimestamp(LocalDateTime.now());
        whatsappMessage.setExternalId(externalId);
        whatsappMessage.setDestAddr(phone);
        whatsappMessageRepository.persist(whatsappMessage);
        return isSend;
    }

    @Override
    public boolean shouldSendWhatsappMessage(String mobile) {
        String destAddr = "91" + mobile;
        boolean shouldSend = true;
        List<WhatsappMessage> whatsappMessages = whatsappMessageRepository.selectByDestAddr(destAddr, LocalDate.now());
        if (!whatsappMessages.isEmpty()) {
            long failedCount = whatsappMessages.stream().filter(x -> x.getFailed() != null && x.getFailed().equals("FAILED")).collect(Collectors.counting());
            if (failedCount >= 2) {
                shouldSend = false;
            }
        }
        return shouldSend;
    }


    @Override
    public void sendPaymentWhatsappMessage(String mobile, String message) throws Exception {
        String sendTo = "91" + mobile;
//        String sendTo = "917082253510";

        Map<String, String> requestHeaders = new HashMap<>();
        requestHeaders.put("Content-Type", "application/x-www-form-urlencoded");
        Map<String, String> requestParams = new HashMap<>();
        requestParams.put("userid", String.valueOf(2000215976));
        requestParams.put("password", "MFRd!BBL");
        requestParams.put("send_to", sendTo);
        requestParams.put("v", "1.1");
        requestParams.put("format", "json");
        requestParams.put("auth_scheme", "plain");
        requestParams.put("method", "SENDMESSAGE");
        requestParams.put("msg_type", "TEXT");
        requestParams.put("msg", message);
        requestParams.put("isTemplate", "true");
        requestParams.put("header", "Payment Link!");

        String response = restClient.post("https://media.smsgupshup.com/GatewayAPI/rest", requestParams, requestHeaders);
        LOGGER.info("response  - {}", response);

        JSONObject jsonObject = new JSONObject(response);
        JSONObject whatsappResponse = jsonObject.getJSONObject("response");
        if (whatsappResponse.getString("status").equals("error")) {
            LOGGER.error("Invalid Whatsapp message, Reason - {}", whatsappResponse.getString("details"));
            return;
        }

        String externalId = whatsappResponse.getString("id");
        String phone = whatsappResponse.getString("phone");

        WhatsappMessage whatsappMessage = new WhatsappMessage();
        whatsappMessage.setCreatedTimestamp(LocalDateTime.now());
        whatsappMessage.setExternalId(externalId);
        whatsappMessage.setDestAddr(phone);
        whatsappMessageRepository.persist(whatsappMessage);
    }

    private boolean sendWhatsAppMessageByMeta(WhatsappMessageType whatsappMessageType, String message, String title, String mobile, String mediaUrl, String fileName) throws Exception {

        mobile = this.optInUsersByMobiles(mobile);

        String token = "###############";
        String phoneNumberId = "000000000000000000";
        String url = "https://graph.facebook.com/v22.0/" + phoneNumberId + "/messages";

        HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Authorization", "Bearer " + token);
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setDoOutput(true);

        // Construct the payload
        JSONObject payload = new JSONObject();
        payload.put("messaging_product", "whatsapp");
        payload.put("to", "918529003611");

        if (mediaUrl != null) {
            JSONObject image = new JSONObject();
            image.put("link", mediaUrl);
            if (fileName != null) image.put("caption", message);
            payload.put("type", "image");
            payload.put("image", image);
        } else {
            payload.put("type", "template");
            JSONObject template = new JSONObject();
            template.put("name", "bid_live");
            JSONObject language = new JSONObject();
            language.put("code", "en_US");
            template.put("language", language);
            JSONArray components = new JSONArray();
            JSONObject body = new JSONObject();
            body.put("type", "body");

            JSONArray parameters = new JSONArray();
            parameters.put(new JSONObject().put("type", "text").put("text", "*Oppo Reno 10 Pro 5G (12GB 256GB) Silvery Grey* at 54.55% Off"));
            parameters.put(new JSONObject().put("type", "text").put("text", "44000.0"));
            parameters.put(new JSONObject().put("type", "text").put("text", "20000.0"));
            parameters.put(new JSONObject().put("type", "text").put("text", "05/05/2025 06:00PM"));
            body.put("parameters", parameters);
            components.put(body);

            template.put("components", components);
            payload.put("template", template);
        }
        LOGGER.info("Final WhatsApp payload: \n{}", payload.toString(2));
        try (OutputStream os = conn.getOutputStream()) {
            os.write(payload.toString().getBytes(StandardCharsets.UTF_8));
        }

        int status = conn.getResponseCode();
        String response = new BufferedReader(new InputStreamReader(status >= 400 ? conn.getErrorStream() : conn.getInputStream())).lines().collect(Collectors.joining("\n"));

        LOGGER.info("WhatsApp API response: {}", response);

        if (status != 200 && status != 201) {
            LOGGER.error("Failed to send WhatsApp message. Status: {}, Response: {}", status, response);
            return false;
        }

        JSONObject jsonResponse = new JSONObject(response);
        JSONArray messages = jsonResponse.optJSONArray("messages");
        String externalId = null;

        if (messages != null && messages.length() > 0) {
            externalId = messages.getJSONObject(0).optString("id");
            WhatsappMessage whatsappMessage = new WhatsappMessage();
            whatsappMessage.setCreatedTimestamp(LocalDateTime.now());
            whatsappMessage.setExternalId(externalId);
            whatsappMessage.setDestAddr(mobile);
            whatsappMessageRepository.persist(whatsappMessage);
        }

        return externalId != null;
    }

    private String optInUsersByMobiles(String mobiles) throws Exception {
        List<String> savedMobiles = new ArrayList<>();
        if (mobiles == null || mobiles.isEmpty()) return String.join(",",savedMobiles);
        String[] mobileNumbers = mobiles.split(",");
        for (String mobile : mobileNumbers) {
            mobile = mobile.trim();
            if (mobile.isEmpty()) continue;
            Optin optin = optinRepository.selectByMobile(mobile);
            if (optin == null) {
                this.optIn(mobile);
                optin = new Optin();
                optin.setCreated(LocalDateTime.now());
                optin.setMobile(mobile);
                optinRepository.persist(optin);
            }
            savedMobiles.add("91"+mobile);
        }
        return String.join(",",savedMobiles);
    }
}