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;@Componentpublic class NotificationServiceImpl implements NotificationService {private static final Logger LOGGER = LogManager.getLogger(NotificationServiceImpl.class);@AutowiredUserCampaignRepository userCampaignRepository;@AutowiredUserRepository dtrUserRepository;@AutowiredUserAccountRepository userAccountRepository;@AutowiredNotificationCampaignRepository notificationCampaignRepository;@AutowiredDeviceRepository deviceRepository;@AutowiredPartnerRegionRepository partnerRegionRepository;@AutowiredFofoStoreRepository fofoStoreRepository;@AutowiredCsService csService;@AutowiredOptinRepository optinRepository;@AutowiredRetailerService retailerService;@AutowiredCustomerRepository customerRepository;@AutowiredPushNotificationRepository pushNotificationRepository;@Autowiredprivate Gson gson;@Autowiredprivate RestClient restClient;@Value("${prod}")private boolean isProd;@Autowiredprivate WhatsappMessageRepository whatsappMessageRepository;@Autowiredprivate WhatsappMessageService whatsappMessageService;@Overridepublic 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);}}@Overridepublic 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);}@Overridepublic 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);}@Overridepublic 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);}}@Overridepublic 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);}@Overridepublic 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;}@Overridepublic 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);}}@Overridepublic 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);}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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 payloadJSONObject 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);}}