이호영 이호영 2025-08-22
친구톡 스미싱처리
@64e451db1bd9f5069f8f8b2e371e118cf83cc540
src/main/java/itn/com/cmm/util/MsgSendUtils.java
--- src/main/java/itn/com/cmm/util/MsgSendUtils.java
+++ src/main/java/itn/com/cmm/util/MsgSendUtils.java
@@ -229,8 +229,8 @@
 		placeholders.put("[*4*]", MjonMsgSendVO::getRep4);
 
 		boolean hasPerformedSpamCheck = false; // 치환 문자가 없는 경우, 스팸 체크가 한 번만 수행되도록 제어
-		boolean hasPerformedMsgType = false; // 치환 문자가 없는 경우, 스팸 체크가 한 번만 수행되도록 제어
-		boolean hasPerformedDelayYn = false; // 치환 문자가 없는 경우, 스팸 체크가 한 번만 수행되도록 제어
+		boolean hasPerformedMsgType = false; // 치환 문자가 없는 경우, 메세지 타입 체크 한번
+		boolean hasPerformedDelayYn = false; // 치환 문자가 없는 경우, 
 		
 		String msgKind = mjonMsgVO.getMsgKind();
 		String smsTxtTemp = mjonMsgVO.getSmsTxt();
@@ -257,10 +257,6 @@
 				for (Map.Entry<String, Function<MjonMsgSendVO, String>> entry : placeholders.entrySet()) {
 					String placeholder = entry.getKey();
 					String value = entry.getValue().apply(sendVO);
-//					log.info(" + smsTxtTemp [{}]", smsTxtTemp);
-//					log.info(" + placeholder [{}]", placeholder);
-//					log.info(" + value [{}]", value);
-//					log.info(" + smsTxtTemp.contains(placeholder) [{}]", smsTxtTemp.contains(placeholder));
 					if (smsTxt.contains(placeholder)) {
 						if (StringUtils.isEmpty(value)) {
 							statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "치환 문구중 " + placeholder + " 데이터가 없습니다.");
src/main/java/itn/let/kakao/kakaoComm/KakaoSendAdvcVO.java
--- src/main/java/itn/let/kakao/kakaoComm/KakaoSendAdvcVO.java
+++ src/main/java/itn/let/kakao/kakaoComm/KakaoSendAdvcVO.java
@@ -66,13 +66,16 @@
 	private String kakaoAtPrice;	// 카카오 알림톡 단가
 	private String bizJsonName;	// 카카오 알림톡 단가
 	private String reserveYn;	// 카카오 알림톡 단가
-	private String atDelayYn;	// 카카오 알림톡 단가
+	private String atDelayYn;	// 지연 문자 발송
 	private String bizKakaoResendOrgnlTxt;	// 카카오 알림톡 단가
 	private String bizKakaoResendType;	// 카카오 알림톡 단가
 	private String filePath1;	// 대체문자 이미지 
 	private String fileCnt;	// 파일 카운트
 	private String bizKakaoImageType;	// 파일 카운트
 	
+	private String spamStatus;
+	
+	
 	
 	
 	
src/main/java/itn/let/kakao/kakaoComm/KakaoSendUtil.java
--- src/main/java/itn/let/kakao/kakaoComm/KakaoSendUtil.java
+++ src/main/java/itn/let/kakao/kakaoComm/KakaoSendUtil.java
@@ -40,6 +40,7 @@
 import itn.let.module.base.PriceAndPoint;
 import itn.let.sym.site.service.JoinSettingVO;
 import itn.let.uss.umt.service.MberManageVO;
+import itn.let.uss.umt.service.UserManageVO;
 import lombok.extern.slf4j.Slf4j;
 
 @Slf4j
@@ -297,21 +298,36 @@
 	 * @description	: 
 	 * @return : List<KakaoSendAdvcVO>
 	 * @param kakaoVO
-	 * @param isNotified
+	 * @param isHolidayNotified
 	 * @param statusResponse
 	 * @return
 	 * @throws Exception
 	 * 
 	 */
-	public List<KakaoSendAdvcVO> populateSendListsFT(KakaoVO kakaoVO, boolean isNotified, StatusResponse statusResponse) throws Exception {
+	public List<KakaoSendAdvcVO> populateSendListsFT(KakaoVO kakaoVO
+														, boolean isHolidayNotified
+														, StatusResponse statusResponse
+														, UserManageVO userManageVO
+														, List<String> resultSpamTxt
+														) throws Exception {
 		
 		//사용자 현재 보유 금액 불러오기(문자 발송 금액 차감 이전 금액)
 //		String befCash = kakaoVO.getBefCash();
 		
 		log.info("kakaoVO.ftToString() ::  [{}]", kakaoVO.ftToString());		
 		
+
+		// 예약 시간 기본값 설정
+		Date now = new Date();
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+		
+		String smishingYn = userManageVO.getSmishingYn();
+		String exceptSpamYn = userManageVO.getExceptSpamYn();
+		
+		
 		List<KakaoSendAdvcVO> kakaoSendAdvcListVO = new ArrayList<>();
-		Calendar calendar = setupBaseDate(kakaoVO, isNotified);
+		Calendar calendar = setupBaseDateFT(kakaoVO);
+		
 		
 		
 		 // 친구톡 내용
@@ -375,18 +391,18 @@
 		float shortPrice = getValidPrice(mberManageVO.getShortPrice(), sysJoinSetVO.getShortPrice());
 		float longPrice = getValidPrice(mberManageVO.getLongPrice(), sysJoinSetVO.getLongPrice());
 		float picturePrice = getValidPrice(mberManageVO.getPicturePrice(), sysJoinSetVO.getPicturePrice());
-//		String shortPStr = Float.toString(shortPrice);
-//		String mmsPStr = Float.toString(longPrice);
-//		String imgPrice = Float.toString(picturePrice);
+
+		boolean hasPerformedSpamCheck = false; // 치환 문자가 없는 경우, 스팸 체크가 한 번만 수행되도록 제어
+		boolean hasPerformedSubSpamCheck = false; // 치환 문자가 없는 경우, 스팸 체크가 한 번만 수행되도록 제어
+		boolean hasPerformedMsgType = false; // 치환 문자가 없는 경우, 메세지 타입 체크 한번
+		boolean hasPerformedDelayYn = false; // 치환 문자가 없는 경우, 
+
 
 		
 		String imgFilePath = "";
 		if(StringUtils.isNotEmpty(kakaoVO.getAtchFileId()) &&  
 				("I".equals(imageType) ||	"W".equals(imageType))) {
-			
-
 			imgFilePath = mjonMsgDAO.selectPhotoImgFileRealPath(kakaoVO.getAtchFileId());
-			
 		}
 		
 		
@@ -395,7 +411,20 @@
 		boolean hasButtons =  CollectionUtils.isNotEmpty(kakaoVO.getButtonVOList());
 		String sharedJsonStr = null;
 		
-		
+
+		// 치환데이터가 없는 경우 한 번만 계산하기 위한 캐시 변수 추가
+		Map<String, Object> sharedPricingResult = null;
+		// 치환데이터가 없는 경우 for문 전에 한 번만 계산
+		if (!replaceSubYN && StringUtils.isNotEmpty(subMsgTxt)) {
+		    sharedPricingResult = calculateSubMsgPricing(subMsgTxt, imgFilePath, shortPrice, longPrice, picturePrice, kakaoFtPrice);
+		    
+		    // 사전계산에서 INVALID인 경우 즉시 리턴
+		    String preSendType = (String) sharedPricingResult.get("sendType");
+		    if ("INVALID".equals(preSendType)) {
+		        statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "전송 문자 길이를 초과하였습니다.");
+		        return kakaoSendAdvcListVO;
+		    }
+		}
 
 		List<MjonFTSendVO> mjonFTSendVOList = kakaoVO.getMjonFTSendVOList();
 
@@ -411,7 +440,9 @@
 			sendVO.setCallTo(mjonFTSendVO.getPhone());
 			sendVO.setMsgId(idList.get(i));
 			
-			String smsTxt = templateContent;
+
+			// 친구톡 문자 
+			String templateContentTemp = templateContent;
 			// 치환 문자면
 			if(replaceYN) {
 				
@@ -419,21 +450,19 @@
 				for (Map.Entry<String, Function<MjonFTSendVO, String>> entry : placeholders.entrySet()) {
 					String placeholder = entry.getKey();
 					String value = entry.getValue().apply(mjonFTSendVO);
-					if (smsTxt.contains(placeholder)) {
+					if (templateContentTemp.contains(placeholder)) {
 						if (StringUtils.isEmpty(value)) {
 							statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "치환 문구중 " + placeholder + " 데이터가 없습니다.");
 							return null;
 						}
-						smsTxt = smsTxt.replace(placeholder, value);
+						templateContentTemp = templateContentTemp.replace(placeholder, value);
 					}
 				}
 			}
-			sendVO.setTemplateContent(smsTxt);
+			sendVO.setTemplateContent(templateContentTemp);
 			
-			
-			
+			// 실패 대체 문자
 			String subMsgTxtTemp = null;
-			
 			if(StringUtils.isNotEmpty(subMsgTxt)) {
 				subMsgTxtTemp = subMsgTxt;
 				
@@ -459,34 +488,28 @@
 			// Step 1-4: 실패 대체 문자 치환데이터 설정
 			if(StringUtils.isNotEmpty(subMsgTxtTemp)) { // 대체문자가 있나?
 				
-				String sendType =  "MMS";
-				if(StringUtils.isEmpty(imgFilePath)) {
-					int smsTxtByte = mjonCommon.getSmsTxtBytes(subMsgTxtTemp);	// 문자 byte 수 계산
-					sendType = getMsgType(smsTxtByte);					// 문자 타입(SHORT / MMS) 판별
-				}
-				sendVO.setSubMsgType(sendType);								// 실패 대체 문자 타입 설정
+				// 최적화된 계산 로직
+				Map<String, Object> pricingResult;
+				
+				if (replaceSubYN) {
+					// 치환데이터 있음 → 매번 새로 계산
+					pricingResult = calculateSubMsgPricing(subMsgTxtTemp, imgFilePath, 
+															shortPrice, longPrice, picturePrice, kakaoFtPrice);
 
-				if ("INVALID".equals(sendType)) {
-					// INVALID 타입이면 길이 초과 에러 응답 후 리턴
-					statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "전송 문자 길이를 초과하였습니다.");
-					return kakaoSendAdvcListVO;
-				}
-
-				float chosenPrice = 0f;
-
-				if(StringUtils.isNotEmpty(imgFilePath)) {
-					chosenPrice = Math.max(picturePrice, kakaoFtPrice);
-					sendVO.setFilePath1(imgFilePath);
-					sendVO.setFileCnt("1");			
-					
-				}else if ("MMS".equals(sendType)) {
-					// MMS 타입일 경우: longPrice(장문 가격)와 카카오톡 단가 중 큰 값을 선택
-					chosenPrice = Math.max(longPrice, kakaoFtPrice);
+					// INVALID 체크
+					String resultSendType = (String) pricingResult.get("sendType");
+					if ("INVALID".equals(resultSendType)) {
+						statusResponseSet(statusResponse, HttpStatus.BAD_REQUEST, "전송 문자 길이를 초과하였습니다.");
+						return kakaoSendAdvcListVO;
+					}
 				} else {
-					// SHORT 타입일 경우: shortPrice(단문 가격)와 카카오톡 단가 중 큰 값을 선택
-					chosenPrice = Math.max(shortPrice, kakaoFtPrice);
+					// 치환데이터 없음 → 미리 계산된 결과 재사용
+					pricingResult = sharedPricingResult;
 				}
-				sendVO.setEachPrice(Float.toString(chosenPrice));	// 선택된 단가 설정
+				
+				
+				// 결과 적용
+				applyPricingResult(sendVO, pricingResult);
 				
 				
 			}else {
@@ -494,8 +517,68 @@
 				sendVO.setEachPrice( Float.toString(kakaoFtPrice) );
 			}
 
+			
+			// 스팸 단어 체크
+			// exceptSpam는 사용자 스팸 단어 체크할건지에 대한 여부 Y : 체크
+			if("N".equals(exceptSpamYn)) {
+				// 친구톡 내용
+				if(replaceYN) {
+					checkSpamAndSetStatus(kakaoVO
+							, templateContentTemp
+							, resultSpamTxt, isHolidayNotified);	
+				}else if(!hasPerformedSpamCheck) {
+					checkSpamAndSetStatus(kakaoVO
+							, templateContentTemp
+							, resultSpamTxt, isHolidayNotified);
+					hasPerformedSpamCheck = true;
+				}
+				// 대체문자 내용
+				if(StringUtils.isNotEmpty(subMsgTxtTemp)) { 
+					if(replaceSubYN) {
+						checkSpamAndSetStatus(kakaoVO
+								, subMsgTxtTemp
+								, resultSpamTxt, isHolidayNotified);						
+					}else if(!hasPerformedSubSpamCheck) {
+						checkSpamAndSetStatus(kakaoVO
+								, subMsgTxtTemp
+								, resultSpamTxt, isHolidayNotified);
+						hasPerformedSubSpamCheck = true;
+					}
 
-			// 타이틀과 버튼이 있고
+				}
+			}
+
+			log.info(" kakaoVO.toString() :: [{}]",kakaoVO.ftToString());
+
+			
+			/* @isHolidayNotified
+			 *  - 관리자 알림 설정으로 인해 
+			 *  - 해당 시간이면 지연 미처리
+			 * @smishingYn
+			 *  - 회원 별 '스미싱 온' 상태값
+			 *  - Y면 알림, 지연 처리해야 함
+			 * */
+			if("Y".equalsIgnoreCase(smishingYn) && isHolidayNotified) {
+				kakaoVO.setSpamStatus("Y");
+				kakaoVO.setSmishingYn("Y");
+				kakaoVO.setAtDelayYn("Y");
+			}
+			
+			// 지연 여부 처리
+			if (( "Y".equalsIgnoreCase(smishingYn) || "Y".equalsIgnoreCase(kakaoVO.getAtDelayYn()))
+					&& !hasPerformedDelayYn && isHolidayNotified) {
+				calendar.add(Calendar.MINUTE, 30); // 모든 시간을 30분 뒤로 미룸
+				// TEST
+//				calendar.add(Calendar.MINUTE, 5); // 모든 시간을 30분 뒤로 미룸
+				hasPerformedDelayYn = true;
+			}
+			
+			sendVO.setReqDate(sdf.format(calendar.getTime())); // 분할된 시간 설정 또는 기본 예약 시간 사용
+			
+			
+			
+
+			// 타이틀이나 버튼이 있고
 			if(hasButtons || StringUtils.isNotEmpty(kakaoVO.getTemplateImageUrl())) {
 				// 
 				if (StringUtils.isEmpty(sharedJsonStr)) {
@@ -510,9 +593,113 @@
 			kakaoSendAdvcListVO.add(sendVO);
 			log.info(" sendVO.toString() :: [{}]",sendVO.toString());
 		}
-		
+
 		
 		return kakaoSendAdvcListVO;
+	}
+
+	private void checkSpamAndSetStatus(KakaoVO kakaoVO
+			, String chkText
+			, List<String> resultSpamTxt, boolean isHolidayNotified) throws Exception {
+		// TODO Auto-generated method stub
+		
+		
+		kakaoVO.setSpamStatus("N");
+		kakaoVO.setAtDelayYn("N");
+		
+		if(StringUtils.isNotEmpty(chkText)) {
+			
+			String resultParser = ComGetSpamStringParser.getSpamTextParse(chkText).trim();
+			int spmCnt = 0;
+			String spmFilterTxt = "";
+	
+			for (String spmTxt : resultSpamTxt) {
+				String parserStr = ComGetSpamStringParser.getSpamTextParse(spmTxt).trim();
+				if (resultParser.contains(parserStr)) {
+					spmCnt++;
+					spmFilterTxt += spmTxt + ",";
+				}
+			}
+	
+			if (spmCnt > 0) { // 스팸 문자가 포함된 경우
+	
+				if (StringUtil.getWordRight(spmFilterTxt.trim(), 1).equals(",")) {
+					// 처음부터 idx 만큼 잘라낸 나머지 글자 
+					spmFilterTxt = StringUtil.getWordLeft(spmFilterTxt.trim(), 1); 	
+					
+				}
+				
+				/* @isHolidayNotified
+				 *  - 관리자 알림 설정으로 인해 
+				 *  - 해당 시간이면 지연 미처리
+				 * */
+				kakaoVO.setSpamStatus("Y");
+				if(isHolidayNotified) {
+					kakaoVO.setAtDelayYn("Y");
+				}
+			}
+		}
+		
+		
+	}
+
+	// TODO(human): 아래에 새로운 메소드 구현
+	/**
+	 * 대체문자 가격 계산 최적화 메소드
+	 * @param subMsgTxt 대체문자 내용
+	 * @param imgFilePath 이미지 파일 경로
+	 * @param shortPrice 단문 가격
+	 * @param longPrice 장문 가격
+	 * @param picturePrice 사진 가격
+	 * @param kakaoFtPrice 카카오 친구톡 가격
+	 * @return 계산 결과 Map (sendType, chosenPrice, filePath 포함)
+	 * @throws UnsupportedEncodingException 
+	 */
+	private Map<String, Object> calculateSubMsgPricing(String subMsgTxt, String imgFilePath, 
+			 											float shortPrice, float longPrice, 
+			 											float picturePrice, float kakaoFtPrice) throws UnsupportedEncodingException {
+		Map<String, Object> result = new HashMap<>();
+		
+		String sendType = "MMS";
+		if(StringUtils.isEmpty(imgFilePath)) {
+			int smsTxtByte = mjonCommon.getSmsTxtBytes(subMsgTxt);
+			sendType = getMsgType(smsTxtByte);
+		}
+		
+		result.put("sendType", sendType);
+		
+		// INVALID인 경우 추가 처리 없이 반환
+		if ("INVALID".equals(sendType)) {
+			return result;
+		}
+		
+		float chosenPrice = 0f;
+		if(StringUtils.isNotEmpty(imgFilePath)) {
+			chosenPrice = Math.max(picturePrice, kakaoFtPrice);
+			result.put("filePath", imgFilePath);
+		} else if ("MMS".equals(sendType)) {
+			chosenPrice = Math.max(longPrice, kakaoFtPrice);
+		} else {
+			chosenPrice = Math.max(shortPrice, kakaoFtPrice);
+		}
+		
+		result.put("sendType", sendType);
+		result.put("chosenPrice", Float.toString(chosenPrice));
+		return result;
+	}
+	
+	/**
+	 * 가격 계산 결과를 sendVO에 적용하는 헬퍼 메소드
+	 * @param sendVO 적용할 KakaoSendAdvcVO 객체
+	 * @param pricingResult 가격 계산 결과 Map
+	 */
+	private void applyPricingResult(KakaoSendAdvcVO sendVO, Map<String, Object> pricingResult) {
+		sendVO.setSubMsgType((String) pricingResult.get("sendType"));
+		sendVO.setEachPrice((String) pricingResult.get("chosenPrice"));
+		if (pricingResult.get("filePath") != null) {
+			sendVO.setFilePath1((String) pricingResult.get("filePath"));
+			sendVO.setFileCnt("1");
+		}
 	}
 	
 	public static String getMsgTypeWithByteValidation(MjonFTSendVO  sendVO, String p_smsTxt) throws UnsupportedEncodingException {
@@ -543,9 +730,21 @@
 		}
 		return msgType;
 	}
-	
 
-	private Calendar setupBaseDate(KakaoVO kakaoVO, boolean isNotified) throws ParseException {
+
+	private Calendar setupBaseDateFT(KakaoVO kakaoVO) throws ParseException {
+
+		// baseDate 추출
+		Date baseDate = resolveBaseDate(kakaoVO);
+
+		// 시간 성정
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(baseDate);  // calendar에 baseDate 설정
+
+		return calendar;
+	}
+
+	private Calendar setupBaseDate(KakaoVO kakaoVO, boolean isHolidayNotified) throws ParseException {
 
 		// baseDate 추출
 		Date baseDate = resolveBaseDate(kakaoVO);
@@ -557,7 +756,7 @@
 		// 지연 여부 처리
 		// 알림톡 스미싱의심 + 공휴일알림 조건이 맞으면 30분 delay
 		if ( "Y".equalsIgnoreCase(kakaoVO.getAtSmishingYn())
-				&& isNotified) {
+				&& isHolidayNotified) {
 			calendar.add(Calendar.MINUTE, 30); // 모든 시간을 30분 뒤로 미룸
 		}
 		return calendar;
@@ -1688,7 +1887,7 @@
 		Float totPrice = eachPrice * instCnt;
 		sendVO.setTotPrice(String.format("%.1f", totPrice));
 		
-		sendVO.setAtDelayYn(kakaoVO.getAtSmishingYn()); 
+		sendVO.setAtDelayYn(kakaoVO.getAtDelayYn()); 
 		sendVO.setBizKakaoResendOrgnlTxt(kakaoVO.getSubMsgTxt());
 		sendVO.setBizKakaoResendType(sendVO.getSubMsgType());
 		sendVO.setBizKakaoImageType(kakaoVO.getImageType());
src/main/java/itn/let/kakao/kakaoComm/KakaoVO.java
--- src/main/java/itn/let/kakao/kakaoComm/KakaoVO.java
+++ src/main/java/itn/let/kakao/kakaoComm/KakaoVO.java
@@ -358,6 +358,7 @@
 		sb.append("\n , spamStatus=[").append(getSpamStatus()).append("]");
 		sb.append("\n , txtReplYn=[").append(getTxtReplYn()).append("]");
 		sb.append("\n , atSmishingYn=[").append(getAtSmishingYn()).append("]");
+		sb.append("\n , atDelayYn=[").append(getAtDelayYn()).append("]");
 //		sb.append("\n , tmpBtnSelect=[").append(getTmpBtnSelect()).append("]");
 		StringBuilder btnListSb = new StringBuilder("[");
 		if (buttonVOList != null && !buttonVOList.isEmpty()) {
src/main/java/itn/let/kakao/user/kakaoFt/service/impl/KakaoFriendsTalkServiceImpl.java
--- src/main/java/itn/let/kakao/user/kakaoFt/service/impl/KakaoFriendsTalkServiceImpl.java
+++ src/main/java/itn/let/kakao/user/kakaoFt/service/impl/KakaoFriendsTalkServiceImpl.java
@@ -29,8 +29,10 @@
 import itn.let.mjo.mjocommon.MjonCommon;
 import itn.let.mjo.msg.service.MjonMsgVO;
 import itn.let.mjo.msg.service.impl.MjonMsgDAO;
+import itn.let.mjo.msgdata.service.MjonMsgDataService;
 import itn.let.module.base.PriceAndPoint;
 import itn.let.uss.umt.service.EgovUserManageService;
+import itn.let.uss.umt.service.UserManageVO;
 import lombok.extern.slf4j.Slf4j;
 
 @Slf4j
@@ -56,6 +58,9 @@
 	
 	@Resource(name="kakaoAlimTalkDAO")
 	private KakaoAlimTalkDAO kakaoAlimTalkDAO;
+
+	@Resource(name = "MjonMsgDataService")
+	private MjonMsgDataService mjonMsgDataService;
 	
 	@Autowired
 	KakaoSendUtil kakaoSendUtil;
@@ -70,9 +75,9 @@
 	public StatusResponse insertKakaoFtSandAjax_advc(KakaoVO kakaoVO, HttpServletRequest request) throws Exception {
 		StatusResponse statusResponse = new StatusResponse();
 		
-		log.info(" + kakaoVO.toString() :: [{}]", kakaoVO.toString()); 
+//		log.info(" + kakaoVO.toString() :: [{}]", kakaoVO.toString()); 
 		
-		log.info(" + kakaoVO.toString() :: [{}]", kakaoVO.ftToString()); 
+//		log.info(" + kakaoVO.toString() :: [{}]", kakaoVO.ftToString()); 
 		
 
 		
@@ -118,12 +123,17 @@
 /** @isHolidayNotified 
  * @false : 알림 X
  * @true  : 알림 O */
-		boolean isNotified = mjonCommon.processUserAndCheckAT(kakaoVO);
+		boolean isHolidayNotified = mjonCommon.processUserAndCheckFT(kakaoVO);
 		
+
+		UserManageVO userManageVO = mjonCommon.getUserManageInfo(userId);
 		
+
+		// 스팸관련 키워드 select
+		List<String> resultSpamTxt = mjonMsgDataService.selectSpamKeywordList();
 		
 /** @카카오톡 전송 list 셋팅 -------------------------------------------*/
-		List<KakaoSendAdvcVO> kakaoSendAdvcListVO = kakaoSendUtil.populateSendListsFT(kakaoVO, isNotified, statusResponse);
+		List<KakaoSendAdvcVO> kakaoSendAdvcListVO = kakaoSendUtil.populateSendListsFT(kakaoVO, isHolidayNotified, statusResponse, userManageVO, resultSpamTxt);
 		if (statusResponse.getStatus() != null && !statusResponse.getStatus().equals(HttpStatus.OK)) {
 			log.error(" + populateSendLists 처리 중 오류 발생: {}", statusResponse.getMessage());
 			return statusResponse;
@@ -189,7 +199,7 @@
 
 /** @SLACK발송 */ 
 				/** @발송조건이되면 발송 */ 
-				if(isNotified) {
+				if(isHolidayNotified && "Y".equals(userManageVO.getAtSmishingYn())) {
 					mjonCommon.getAdminKakaoAtSendSlack(sendVO);
 				}else if("Y".equals(kakaoVO.getAtSmishingYn())){
 				/** @발송조건이 안되면 DB INSERT */ 
src/main/java/itn/let/mjo/mjocommon/MjonCommon.java
--- src/main/java/itn/let/mjo/mjocommon/MjonCommon.java
+++ src/main/java/itn/let/mjo/mjocommon/MjonCommon.java
@@ -533,12 +533,12 @@
 		UserManageVO userManageVO = getUserManageInfo(kakaoVO.getUserId());
 		
 		// 기본값 처리된 사용자 정보와 문자 상태
-		String adminSmsNoticeYn = userManageVO.getAdminSmsNoticeYn();
-		String atSmishingYn = userManageVO.getAtSmishingYn();
+		String adminSmsNoticeYn = userManageVO.getAdminSmsNoticeYn(); // 법인폰 알람 여부 - Y : ON 
+		String atSmishingYn = userManageVO.getAtSmishingYn(); // 스미싱 의심 - Y : ON
 		
 		// 조건 체크
 		if ("Y".equals(adminSmsNoticeYn) || "Y".equals(atSmishingYn)) {
-			kakaoVO.setAtSmishingYn("Y"); // MjonMsgVO에 스미싱 정보 설정
+			kakaoVO.setAtSmishingYn("Y"); // MjonMsgVO에 스미싱 정보 설정 - Y면 디
 			
 			// 스미싱 알림 처리
 			return handleSmishingAlert(); // 알림 처리 결과 반환
@@ -546,6 +546,46 @@
 		
 		return false; // 알림 처리되지 않음
 	}
+	
+	
+	/**
+	 * @methodName	: processUserAndCheckFT 
+	 * @author		: 이호영
+	 * @date		: 2025. 8. 21.
+	 * @description	: 
+	 * @return : boolean
+	 * @param kakaoVO
+	 * @return
+	 * @throws Exception
+	 * 
+	 * @isHolidayNotified 
+	 * @false : 알림 X
+	 * @true  : 알림 O 
+	 * 
+	 */
+	public boolean processUserAndCheckFT(KakaoVO kakaoVO) throws Exception {
+//		UserManageVO userManageVO = getUserManageInfo(kakaoVO.getUserId());
+//		kakaoVO.setAtSmishingYn("N"); // MjonMsgVO에 스미싱 정보 설정 - Y면 딜레이 처리 됨
+		
+		
+		// 기본값 처리된 사용자 정보와 문자 상태
+//		String adminSmsNoticeYn = userManageVO.getAdminSmsNoticeYn(); // 법인폰 알람 여부 - Y : ON 
+//		String atSmishingYn = userManageVO.getAtSmishingYn(); // 스미싱 의심 - Y : ON !== mj_msg_group_data와 다른거임
+		
+		// 조건 체크
+//		if ("Y".equals(adminSmsNoticeYn) || "Y".equals(atSmishingYn)) {
+//		if ("Y".equals(atSmishingYn)) {
+//			Boolean B_return = handleSmishingAlert();
+//			if(B_return) { // true면 알림ON이라서 스미싱Yn을 Y로 설정 아니면 N / 나머지는 로직에서 처리 
+//				kakaoVO.setAtSmishingYn(atSmishingYn); // MjonMsgVO에 스미싱 정보 설정 - Y면 딜레이 처리 됨
+//			}
+			// 스미싱 알림 처리
+//			return B_return; // 알림 처리 결과 반환
+//		}
+		
+		return handleSmishingAlert(); // 알림 처리되지 않음
+	}
+	
 
 	// 사용자 정보 조회 및 기본값 처리
 	public UserManageVO getUserManageInfo(String userId) throws Exception {
Add a comment
List