알림톡 api 단체 발송 - request 데이터 받기 완료

This commit is contained in:
hehihoho3@gmail.com 2025-08-18 18:37:12 +09:00
parent e9aa136932
commit d87651a558
7 changed files with 105 additions and 124 deletions

View File

@ -44,6 +44,12 @@ public enum StatMsg {
, STAT_1090("1090","요청 발송일시에 발송 불가") // 아직 사용 안함
, STAT_1099("1099","기타 시스템 오류")
//카톡발송======================================================================
, STAT_2040("2040","본문 데이터 오류")
, STAT_2041("2041","타이틀 데이터 오류")
, STAT_2042("2042","대체문자 데이터 오류")
//전체발송======================================================================
, STAT_3099("3099","기타 시스템 오류")

View File

@ -4,10 +4,7 @@ import com.itn.mjonApi.cmn.domain.SendRequestCmnVO;
import lombok.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.*;
/**
@ -32,8 +29,6 @@ public class MsgAtRequestVO extends SendRequestCmnVO implements Serializable {
private String sendKind = "A";
private String mberId; // value = "사용자 ID", example = "goodgkdus"
private String accessKey; // value = "Api Key", example = "0367a25ec370d1141898a0b9767103"
@ -42,42 +37,16 @@ public class MsgAtRequestVO extends SendRequestCmnVO implements Serializable {
private String templateCode; // 카카오 알림톡 템플릿 코드
// private String[] callToList; // value = "수신번호리스트", dataType = "[Ljava.lang.String;", example = "01011112222,01022223333"
private String callFrom; // value = "발신번호 :: 정책이 필요함", example = "01011112222"
private String templateContent_1; // 카카오 분문
private String templateContent_2; // 카카오 분문
private String templateTitle_1; // 카카오 타이틀
private String templateTitle_2; // 카카오 타이틀
// 대체문자 여부
private String subMsgSendYn;
// 대체문자 내용
private String subMsgTxt;
private String test_yn;
private List<VarListMapVO> varListMap = new ArrayList<>();
public void setTrnCallToList(String[] callToList) {
this.callToList = callToList;
if (callToList != null) {
this.varListMap = Arrays.stream(callToList)
.map(num -> {
VarListMapVO vo = new VarListMapVO();
vo.setCallToList(num);
return vo;
})
.collect(Collectors.toList());
} else {
this.varListMap = new ArrayList<>();
}
}
}

View File

@ -14,22 +14,22 @@ public class VarListMapVO {
/**
* @description : 수신자번호
*/
private String callToList;
//
// /**
// * @description : [*이름*] - 치환문자
// */
// private String name;
//
// /**
// * @description : [*1*] - 치환문자
// */
// private String rep1;
//
// /**
// * @description : [*2*] - 치환문자
// */
// private String rep2;
private String callTo;
/**
* @description : 카카오 내용
*/
private String templateContent;
/**
* @description : 카카오템플릿
*/
private String templateTitle;
/**
* @description : 치환문자
*/
private String subMsgTxt;
//
// /**
// * @description : [*3*] - 치환문자

View File

@ -4,6 +4,8 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.itn.mjonApi.cmn.msg.RestResponse;
import com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain.MsgAtRequestVO;
import javax.servlet.http.HttpServletRequest;
public interface SendAtService {
@ -15,5 +17,5 @@ public interface SendAtService {
//
// RestResponse sendMsgsData_advc(MsgsRequestVO msgsRequestVO) throws Exception;
RestResponse sendAtData(MsgAtRequestVO msgAtRequestVO) throws JsonProcessingException;
RestResponse sendAtData(MsgAtRequestVO msgAtRequestVO, HttpServletRequest request) throws JsonProcessingException;
}

View File

@ -5,24 +5,26 @@ import com.itn.mjonApi.cmn.apiServer.ApiService;
import com.itn.mjonApi.cmn.msg.FailRestResponse;
import com.itn.mjonApi.cmn.msg.RestResponse;
import com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain.MsgAtRequestVO;
import com.itn.mjonApi.mjon.api.kakao.at.send.service.AtParameterProcessingService;
import com.itn.mjonApi.mjon.api.kakao.at.send.service.SendAtService;
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.PriceMapper;
import com.itn.mjonApi.mjon.api.msg.send.mapper.SendMapper;
import com.itn.mjonApi.mjon.api.msg.send.mapper.domain.MjonResponseVO;
import com.itn.mjonApi.util.MunjaUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.Response;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
@Slf4j
@Service
public class SendAtServiceImpl implements SendAtService {
@Autowired
private AtParameterProcessingService atParameterProcessingService;
private ApiService<Response> apiService;
@Autowired
@ -48,7 +50,7 @@ public class SendAtServiceImpl implements SendAtService {
* @author hylee
*/
@Override
public RestResponse sendAtData(MsgAtRequestVO msgAtRequestVO) throws JsonProcessingException {
public RestResponse sendAtData(MsgAtRequestVO msgAtRequestVO, HttpServletRequest request) throws JsonProcessingException {
if(StringUtils.isNotEmpty(msgAtRequestVO.getTest_yn())){
@ -56,30 +58,27 @@ public class SendAtServiceImpl implements SendAtService {
// return this._getTestMsgReturnData(msgRequestVO.getTest_yn());
}
// 1. [공통 모듈 호출] 'callTo_' 필드에서 전화번호를 한번만 추출합니다.
List<String> phoneNumbers = MunjaUtil.extractCallToNumbers(msgAtRequestVO);
// step2.수신자 전화번호 정상 여부 체크(정상 번호에 대해서만 발송 가능)
// 1020
// 폰번호 확인 - -> 유효성 정규식
if(MunjaUtil.getCallToListChk(msgAtRequestVO.getCallToList())){
return new RestResponse(new FailRestResponse("STAT_1020",""));
// Form-data의 인덱스된 파라미터들을 VarListMapVO 리스트로 변환 (동적 처리 _1~_100)
String falseCode = atParameterProcessingService.processIndexedParameters(msgAtRequestVO, request);
if(StringUtils.isNotEmpty(falseCode)){
return new RestResponse(new FailRestResponse(falseCode,""));
}
msgAtRequestVO.setTrnCallToList(msgAtRequestVO.getCallToList());
log.info("msgAtRequestVO.toString() :: [{}]", msgAtRequestVO.toString());
MjonResponseVO munjaSendResponse = apiService.postForEntity(
"/web/mjon/kakao/alimtalk/kakaoAlimTalkMsgSendAjax_advc.do"
, msgAtRequestVO
, String.class
);
//
//
//
//
// MjonResponseVO munjaSendResponse = apiService.postForEntity(
// "/web/mjon/kakao/alimtalk/kakaoAlimTalkMsgSendAjax_advc.do"
// , msgAtRequestVO
// , String.class
// );
// convertMjonDataToApiResponse => MjonResponseVO 데이터를 ApiResponse 데이터로 변환하는 메소드
log.info(" + munjaSendResponse :: [{}]", munjaSendResponse.toString());
// log.info(" + munjaSendResponse :: [{}]", munjaSendResponse.toString());
/*
if("OK".equals(munjaSendResponse.getResult())){ // 성공
return new RestResponse(SendSucRestResponse.convertMjonDataToApiResponse(munjaSendResponse));
@ -88,7 +87,7 @@ public class SendAtServiceImpl implements SendAtService {
}
*/
return null;
return new RestResponse(msgAtRequestVO);
}
}

View File

@ -10,6 +10,8 @@ import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
/**
* packageName : com.itn.mjonApi.mjon.send.web
* fileName : SendRestController
@ -37,15 +39,17 @@ public class SendAtRestController {
/**
*
* @param msgAtRequestVO
* @param request
* @Discription [문자 발송] 같은 내용으로 여려명에게 보냄
* @return
*/
@PostMapping("/api/kakao/at/sendMsg")
public ResponseEntity<RestResponse> sendMsg(MsgAtRequestVO msgAtRequestVO) throws Exception {
public ResponseEntity<RestResponse> sendMsg(MsgAtRequestVO msgAtRequestVO, HttpServletRequest request) throws Exception {
// https://smartsms.aligo.in/alimapi.html
return ResponseEntity.ok().body(sendAtService.sendAtData(msgAtRequestVO));
return ResponseEntity.ok().body(sendAtService.sendAtData(msgAtRequestVO, request));
// return ResponseEntity.ok().body(new RestResponse(msgAtRequestVO));
}

View File

@ -1,12 +1,9 @@
package com.itn.mjonApi.util;
import com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain.VarListMapVO;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* packageName : com.itn.mjonApi.util
* fileName : SendUtil
@ -79,58 +76,21 @@ public class MunjaUtil {
}
return returnData;
}
public static Boolean getCallToChk(String callTo) {
Boolean returnData = false;
/**
* [핵심 공통 모듈]
* 객체에서 'callTo_' 시작하는 모든 필드 값을 추출하여 리스트로 반환합니다.
* @param vo 'callTo_' 필드를 가진 객체
* @return 추출된 전화번호 문자열 리스트 (값이 없는 필드는 제외됨)
*/
public static List<String> extractCallToNumbers(Object vo) {
List<String> phoneNumbers = new ArrayList<>();
if (vo == null) {
return phoneNumbers;
}
try {
Field[] fields = vo.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.getName().startsWith("callTo_")) {
field.setAccessible(true);
Object value = field.get(vo);
// 필드 값이 존재하고, 문자열이 아닌 경우에만 리스트에 추가
if (value instanceof String && org.springframework.util.StringUtils.hasText((String) value)) {
phoneNumbers.add((String) value);
}
}
}
} catch (IllegalAccessException e) {
// 실제 운영에서는 로깅 처리가 필요합니다.
e.printStackTrace();
}
return phoneNumbers;
}
/**
* [리팩토링된 유효성 검사]
* 추출된 번호 리스트를 받아 유효성을 검사합니다.
* @param phoneNumbers 검사할 번호 리스트
* @return 유효하지 않으면 true, 모두 유효하면 false
*/
public static boolean hasInvalidPhoneNumber(List<String> phoneNumbers) {
// 1. 추출된 번호가 하나도 없으면 실패
if (phoneNumbers == null || phoneNumbers.isEmpty()) {
if(!MunjaUtil.checkPhoneNumberEmpty(callTo) // 비여있는지 체크
|| !MunjaUtil.validatePNumWithRegex(callTo) // 정규식으로 번호 체크
)
{
return true;
}
};
// 2. 리스트의 모든 번호가 정규식에 맞는지 확인
// 하나라도(!allMatch) 정규식에 맞지 않으면 true 반환
return !phoneNumbers.stream().allMatch(MunjaUtil::validatePNumWithRegex);
return returnData;
}
// 기존 정규식 검사 메서드 (변경 없음)
public static boolean validatePNumWithRegex(String pNum) {
return pNum != null && pNum.matches("^\\d{10,11}$");
@ -138,4 +98,45 @@ public class MunjaUtil {
/**
* VarListMapVO의 필드들을 검증
*
* @param vo 검증할 VarListMapVO 객체
* @param subMsgSendYn 대체문자 발송 여부
* @return 검증 실패 오류 코드, 성공 null
*/
public static String kakaoCmnValidate(VarListMapVO vo, String subMsgSendYn) {
// 수신번호 검증
String callTo = vo.getCallTo();
if (MunjaUtil.getCallToChk(callTo)) {
return "STAT_1020"; // 수신자 전화번호 오류
}
// 본문 데이터 검증
String templateContent = vo.getTemplateContent();
if (StringUtils.isEmpty(templateContent)) {
return "STAT_2040"; // 본문 데이터 오류
}
// 타이틀 데이터 검증
String templateTitle = vo.getTemplateTitle();
if (StringUtils.isEmpty(templateTitle)) {
return "STAT_2041"; // 타이틀 데이터 오류
}
// 대체문자 검증 (대체문자 발송이 활성화된 경우에만)
if ("Y".equals(subMsgSendYn)) {
String subMsgTxt = vo.getSubMsgTxt();
if (StringUtils.isEmpty(subMsgTxt)) {
return "STAT_2042"; // 대체문자 데이터 오류
}
}
// 모든 검증 통과
return null;
}
}