알림톡 api 단문발송 진행중

This commit is contained in:
hehihoho3@gmail.com 2025-07-29 17:42:32 +09:00
parent 69d2cfb597
commit 0dba525775
22 changed files with 458 additions and 553 deletions

View File

@ -169,7 +169,9 @@ public class LogAspect {
lettnApiSendMsgLogMapper.insert(apiSendMsgLogVO);
// 메세지 그룹 테이블에 발송 구분 업데이트
this.updateMsgGroupTbSendKind(apiSendMsgLogVO);
// mjon_git에서 처리하는걸로 수정
// 20250729 이호영
// this.updateMsgGroupTbSendKind(apiSendMsgLogVO);
}

View File

@ -3,18 +3,14 @@ package com.itn.mjonApi.cmn.apiServer;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itn.mjonApi.cmn.domain.biz.template.detail.TemplateDetailResponse;
import com.itn.mjonApi.cmn.domain.biz.template.BizTemplateRequest;
import com.itn.mjonApi.cmn.domain.biz.template.detail.TemplateDetailResponse;
import com.itn.mjonApi.cmn.domain.biz.template.list.TemplateListResponse;
import com.itn.mjonApi.mjon.api.msg.send.mapper.domain.MjonResponseVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
/**
@ -72,6 +68,15 @@ public class ApiService <T> {
return MjonResponseVO.getMjonResponse(apiReturnNode);
}
/**
* @param
* @return
* @throws Exception 처리 예외 발생 가능
* @date 2025-07-29
* @Discription 알림톡 템플릿 리스트 조회
* @author hylee
*/
public TemplateListResponse postForBizTemplateListEntity(String url, BizTemplateRequest requestDto) throws JsonProcessingException {
@ -91,6 +96,15 @@ public class ApiService <T> {
return returnEntity;
}
/**
* @param
* @return
* @throws Exception 처리 예외 발생 가능
* @date 2025-07-29
* @Discription 알림톡 템플릿 상세 조회
* @author hylee
*/
public TemplateDetailResponse postForBizTemplateDetailEntity(String url, BizTemplateRequest requestDto) throws JsonProcessingException {

View File

@ -58,6 +58,7 @@ public enum StatMsg {
//======================================================================
, msgType4("단문","SMS")
, msgType6("장문","LMS")
, msgType8("알림톡","AT")
;

View File

@ -1,9 +1,6 @@
package com.itn.mjonApi.mjon.api.kakao.inqry.mapper;
package com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper;
import com.itn.mjonApi.mjon.api.kakao.inqry.mapper.domain.MjKakaoProfileInfoVO;
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.HstryDetailVO;
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.HstryVO;
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.MjonResponseVO;
import com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.domain.MjKakaoProfileInfoVO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;

View File

@ -1,4 +1,4 @@
package com.itn.mjonApi.mjon.api.kakao.inqry.mapper.domain;
package com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.domain;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

View File

@ -1,4 +1,4 @@
package com.itn.mjonApi.mjon.api.kakao.inqry.service.Impl;
package com.itn.mjonApi.mjon.api.kakao.at.inqry.service.Impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.itn.mjonApi.cmn.apiServer.ApiService;
@ -9,9 +9,9 @@ import com.itn.mjonApi.cmn.domain.biz.template.list.TemplateInfo;
import com.itn.mjonApi.cmn.domain.biz.template.list.TemplateListResponse;
import com.itn.mjonApi.cmn.msg.FailRestResponse;
import com.itn.mjonApi.cmn.msg.RestResponse;
import com.itn.mjonApi.mjon.api.kakao.inqry.mapper.InqryMapper;
import com.itn.mjonApi.mjon.api.kakao.inqry.mapper.domain.MjKakaoProfileInfoVO;
import com.itn.mjonApi.mjon.api.kakao.inqry.service.InqryService;
import com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.InqryMapper;
import com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.domain.MjKakaoProfileInfoVO;
import com.itn.mjonApi.mjon.api.kakao.at.inqry.service.InqryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.Response;
import org.springframework.beans.factory.annotation.Autowired;

View File

@ -1,9 +1,9 @@
package com.itn.mjonApi.mjon.api.kakao.inqry.service;
package com.itn.mjonApi.mjon.api.kakao.at.inqry.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.itn.mjonApi.cmn.domain.biz.template.BizTemplateRequest;
import com.itn.mjonApi.cmn.msg.RestResponse;
import com.itn.mjonApi.mjon.api.kakao.inqry.mapper.domain.MjKakaoProfileInfoVO;
import com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.domain.MjKakaoProfileInfoVO;
public interface InqryService {
RestResponse getChnlId(MjKakaoProfileInfoVO mjKakaoProfileInfoVO);

View File

@ -1,10 +1,10 @@
package com.itn.mjonApi.mjon.api.kakao.inqry.web;
package com.itn.mjonApi.mjon.api.kakao.at.inqry.web;
import com.itn.mjonApi.cmn.domain.biz.template.BizTemplateRequest;
import com.itn.mjonApi.cmn.msg.RestResponse;
import com.itn.mjonApi.mjon.api.kakao.inqry.mapper.domain.MjKakaoProfileInfoVO;
import com.itn.mjonApi.mjon.api.kakao.inqry.service.InqryService;
import com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.domain.MjKakaoProfileInfoVO;
import com.itn.mjonApi.mjon.api.kakao.at.inqry.service.InqryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
@ -22,6 +22,7 @@ import org.springframework.web.bind.annotation.*;
* 2025-06-27 hylee 최초 생성
*/
@Slf4j
@CrossOrigin("*") // 모든 요청에 접근 허용
@RestController
public class InqryRestContoller {
@ -36,7 +37,6 @@ public class InqryRestContoller {
* @date 2025-06-27
* @author hylee
*/
@CrossOrigin("*") // 모든 요청에 접근 허용
@PostMapping("/api/kakao/inqry/chnlId")
public ResponseEntity<RestResponse> getChnlId(MjKakaoProfileInfoVO mjKakaoProfileInfoVO) throws Exception {
@ -44,7 +44,14 @@ public class InqryRestContoller {
}
@CrossOrigin("*") // 모든 요청에 접근 허용
/**
* @param
* @return
* @throws Exception 처리 예외 발생 가능
* @date 2025-07-29
* @Discription 템플릿 리스트 호출
* @author hylee
*/
@PostMapping("/api/kakao/inqry/templates/list")
public ResponseEntity<RestResponse> getTemplates(BizTemplateRequest bizTemplateRequest) throws Exception {
@ -53,7 +60,14 @@ public class InqryRestContoller {
}
@CrossOrigin("*") // 모든 요청에 접근 허용
/**
* @param
* @return
* @throws Exception 처리 예외 발생 가능
* @date 2025-07-29
* @Discription 템플릿 상세
* @author hylee
*/
@PostMapping("/api/kakao/inqry/templates/detail")
public ResponseEntity<RestResponse> getTemplateDetail(BizTemplateRequest bizTemplateRequest) throws Exception {

View File

@ -0,0 +1,46 @@
package com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.*;
/**
* packageName : com.itn.mjonApi.cmn.msg
* fileName : mjonResponse
* author : hylee
* date : 2023-05-12
* description : 문자온 프로젝트에서 받은 리턴값
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2023-05-12 hylee 최초 생성
*/
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true) // JSON에 있지만 VO에 없는 필드를 무시하고 무사히 역직렬화해
@ToString
public class MjonAtResponseVO {
private String result;
private String message;
private String resultSts; // 전송결과 갯수
private String resultBlockSts; // 수신거부 갯수
private String msgGroupId;
private String afterCash;
private String msgType;
private String statCode;
/**
*
* @param apiReturnNode
* @return ResponseEntity vo convert
* @throws JsonProcessingException
*/
// public static MjonAtResponseVO getMjonResponse(JsonNode apiReturnNode) throws JsonProcessingException {
// ObjectMapper objectMapper = new ObjectMapper();
// return objectMapper.treeToValue(apiReturnNode, MjonAtResponseVO.class);
// }
}

View File

@ -0,0 +1,67 @@
package com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain;
import lombok.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* fileName : MsgAtRequestVO.java
* author : hylee
* date : 2025-07-29
* description : 알림톡
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2025-07-29 hylee 최초 생성
*/
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
@Getter
@Setter
public class MsgAtRequestVO implements Serializable {
private static final long serialVersionUID = 1L;
private String mberId; // value = "사용자 ID", example = "goodgkdus"
private String accessKey; // value = "Api Key", example = "0367a25ec370d1141898a0b9767103"
private String senderKey; // 카카오 알림톡 채널ID
private String templateCode; // 카카오 알림톡 템플릿 코드
private String[] callToList; // value = "수신번호리스트", dataType = "[Ljava.lang.String;", example = "01011112222,01022223333"
private String callFrom; // value = "발신번호 :: 정책이 필요함", example = "01011112222"
private String sendKind = "A";
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

@ -0,0 +1,44 @@
package com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class VarListMapVO {
/**
* @description : 수신자번호
*/
private String callToList;
//
// /**
// * @description : [*이름*] - 치환문자
// */
// private String name;
//
// /**
// * @description : [*1*] - 치환문자
// */
// private String rep1;
//
// /**
// * @description : [*2*] - 치환문자
// */
// private String rep2;
//
// /**
// * @description : [*3*] - 치환문자
// */
// private String rep3;
//
// /**
// * @description : [*4*] - 치환문자
// */
// private String rep4;
}

View File

@ -0,0 +1,19 @@
package com.itn.mjonApi.mjon.api.kakao.at.send.service;
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;
public interface SendAtService {
// RestResponse sendMsgData(MsgRequestVO msgRequestVO) throws Exception;
//
// RestResponse sendMsgData_advc(MsgRequestVO msgRequestVO) throws Exception;
//
// RestResponse sendMsgsData(MsgsRequestVO msgsRequestVO) throws Exception;
//
// RestResponse sendMsgsData_advc(MsgsRequestVO msgsRequestVO) throws Exception;
RestResponse sendAtData(MsgAtRequestVO msgAtRequestVO) throws JsonProcessingException;
}

View File

@ -0,0 +1,130 @@
package com.itn.mjonApi.mjon.api.kakao.at.send.service.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
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.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.mjon.api.msg.send.mapper.domain.SendSucRestResponse;
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;
@Slf4j
@Service
public class SendAtServiceImpl implements SendAtService {
private ApiService<Response> apiService;
@Autowired
SendMapper sendMapper;
@Autowired
PriceMapper priceMapper;
@Autowired
public SendAtServiceImpl(ApiService<Response> apiService) {
this.apiService = apiService;
}
private static final String replaseStrList = "[*이름*],[*1*],[*2*],[*3*],[*4*]";
/**
* @param
* @return
* @throws Exception 처리 예외 발생 가능
* @date 2025-07-29
* @Discription 치환없는 알림톡 데이터
* @author hylee
*/
@Override
public RestResponse sendAtData(MsgAtRequestVO msgAtRequestVO) throws JsonProcessingException {
if(StringUtils.isNotEmpty(msgAtRequestVO.getTest_yn())){
// YF => 실패 테스트 데이터
// return this._getTestMsgReturnData(msgRequestVO.getTest_yn());
}
// step2.수신자 전화번호 정상 여부 체크(정상 번호에 대해서만 발송 가능)
// 1020
// 폰번호 확인 - -> 유효성 정규식
if(MunjaUtil.getCallToListChk(msgAtRequestVO.getCallToList())){
return new RestResponse(new FailRestResponse("STAT_1020",""));
}
msgAtRequestVO.setTrnCallToList(msgAtRequestVO.getCallToList());
log.info("msgAtRequestVO.toString() :: [{}]", msgAtRequestVO.toString());
MjonResponseVO munjaSendResponse = apiService.postForEntity(
"/web/mjon/kakao/alimtalk/kakaoAlimTalkMsgSendAjax_advc.do"
, msgAtRequestVO
, String.class
);
// convertMjonDataToApiResponse => MjonResponseVO 데이터를 ApiResponse 데이터로 변환하는 메소드
log.info(" + munjaSendResponse :: [{}]", munjaSendResponse.toString());
if("OK".equals(munjaSendResponse.getResult())){ // 성공
return new RestResponse(SendSucRestResponse.convertMjonDataToApiResponse(munjaSendResponse));
}else{ // 실패
return new RestResponse(new FailRestResponse(munjaSendResponse.getStatCode(),""));
}
}
/*@Override
public RestResponse sendMsgData_advc(MsgRequestVO msgRequestVO) throws Exception {
log.info(" :: sendMsgData_advc ::");
msgRequestVO.setSendKind("A");
if(StringUtils.isNotEmpty(msgRequestVO.getTest_yn())){
// YF => 실패 테스트 데이터
return this._getTestMsgReturnData(msgRequestVO.getTest_yn());
}
// step2.수신자 전화번호 정상 여부 체크(정상 번호에 대해서만 발송 가능)
// 1020
// 폰번호 확인 - -> 유효성 정규식
if(this.getCallToListChk(msgRequestVO)){
return new RestResponse(new FailRestResponse("STAT_1020",""));
}
// 치환 데이터 수신자 번호 VO 생성
msgRequestVO.setMjonMsgSendVOList(this.buildMsgSendVOList(msgRequestVO));
// sms 변수 변경
msgRequestVO.setSmsTxtArea(msgRequestVO.getSmsTxt());
MjonResponseVO munjaSendResponse = apiService.postForEntity(
"/web/mjon/msgdata/sendMsgDataAjax_advc.do"
, msgRequestVO
, String.class
);
// convertMjonDataToApiResponse => MjonResponseVO 데이터를 ApiResponse 데이터로 변환하는 메소드
log.info(" + munjaSendResponse :: [{}]", munjaSendResponse.toString());
if("OK".equals(munjaSendResponse.getResult())){ // 성공
return new RestResponse(SendSucRestResponse.convertMjonDataToApiResponse(munjaSendResponse));
}else{ // 실패
return new RestResponse(new FailRestResponse(munjaSendResponse.getStatCode(),""));
}
}*/
}

View File

@ -0,0 +1,65 @@
package com.itn.mjonApi.mjon.api.kakao.at.send.web;
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.SendAtService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* packageName : com.itn.mjonApi.mjon.send.web
* fileName : SendRestController
* author : hylee
* date : 2023-02-15
* description :
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2023-02-15 hylee 최초 생성
*/
// 치환문자가 있으면 , => § 치환
@CrossOrigin("*") // 모든 요청에 접근 허용
@Slf4j
@RestController
public class SendAtRestController {
@Autowired
private SendAtService sendAtService;
/**
*
* @param msgRequestVO
* @Discription [문자 발송] 같은 내용으로 여려명에게 보냄
* @return
*/
@PostMapping("/api/kakao/at/sendMsg")
public ResponseEntity<RestResponse> sendMsg(MsgAtRequestVO msgAtRequestVO) throws Exception {
return ResponseEntity.ok().body(sendAtService.sendAtData(msgAtRequestVO));
// return ResponseEntity.ok().body(sendService.sendMsgData(msgRequestVO));
}
/**
*
* @param msgsRequestVO
* @description [문자 발송] 다른 내용으로 여려명에게 보냄
* @return
* @throws Exception
*/
/* @PostMapping("/api/send/sendMsgs")
public ResponseEntity<RestResponse> sendMsgs(MsgsRequestVO msgsRequestVO) throws Exception {
return ResponseEntity.ok().body(sendAtService.sendMsgsData_advc(msgsRequestVO));
}*/
}

View File

@ -7,11 +7,11 @@ import com.itn.mjonApi.mjon.api.msg.send.mapper.domain.MsgsRequestVO;
public interface SendService {
RestResponse sendMsgData(MsgRequestVO msgRequestVO) throws Exception;
// RestResponse sendMsgData(MsgRequestVO msgRequestVO) throws Exception;
RestResponse sendMsgData_advc(MsgRequestVO msgRequestVO) throws Exception;
RestResponse sendMsgsData(MsgsRequestVO msgsRequestVO) throws Exception;
// RestResponse sendMsgsData(MsgsRequestVO msgsRequestVO) throws Exception;
RestResponse sendMsgsData_advc(MsgsRequestVO msgsRequestVO) throws Exception;
}

View File

@ -1,30 +1,24 @@
package com.itn.mjonApi.mjon.api.msg.send.service.impl;
import com.itn.mjonApi.cmn.apiServer.ApiService;
import com.itn.mjonApi.cmn.model.Price;
import com.itn.mjonApi.cmn.msg.FailRestResponse;
import com.itn.mjonApi.cmn.msg.RestResponse;
import com.itn.mjonApi.cmn.msg.StatMsg;
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.PriceMapper;
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.PriceVO;
import com.itn.mjonApi.mjon.api.msg.send.mapper.SendMapper;
import com.itn.mjonApi.mjon.api.msg.send.mapper.domain.*;
import com.itn.mjonApi.mjon.api.msg.send.service.SendService;
import com.itn.mjonApi.util.MunjaUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.Response;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
@ -46,99 +40,6 @@ public class SendServiceImpl implements SendService {
private static final String replaseStrList = "[*이름*],[*1*],[*2*],[*3*],[*4*]";
@Override
public RestResponse sendMsgData(MsgRequestVO msgRequestVO) throws Exception {
if(StringUtils.isNotEmpty(msgRequestVO.getTest_yn())){
// YF => 실패 테스트 데이터
return this._getTestMsgReturnData(msgRequestVO.getTest_yn());
}
//sendMsg 문자 발송 체크 사항
//step1.발신자 전화번호 사용 가능 여부 체크(해당 사용자의 등록된 번호만 발송 가능)
// 1010
msgRequestVO.setCallFrom(MunjaUtil.removeCharactersWithRegex(msgRequestVO.getCallFrom()));
if(!sendMapper.findByCallFrom(msgRequestVO)){
return new RestResponse(new FailRestResponse("STAT_1010",""));
}
// step2.수신자 전화번호 정상 여부 체크(정상 번호에 대해서만 발송 가능)
// 1020
// 폰번호 확인 - -> 유효성 정규식
if(this.getCallToListChk(msgRequestVO)){
return new RestResponse(new FailRestResponse("STAT_1020",""));
}
//step3.문자 내용 정상 여부 확인 - 스미싱 문구는 발송 30분 지연으로 처리됨
// 1030 => 현재 사용안함
// 스팸체크 하는 부분
// apiService.postForEntity => restTemplate.postForEntity 호출 MjonResponseVO에 맞게 데이터 정제하는 메소드
MjonResponseVO spamChkEntity = apiService.postForEntity(
"/web/user/login/selectSpamTxtChkAjax.do"
, msgRequestVO
, String.class
);
// 스팸체크 결과값이 spams 이면 스팸문자로 처리
if("spams".equals(spamChkEntity.getResult())){
msgRequestVO.setSpamStatus("Y");
};
//step4.치환명 정상 여부 확인
// 1040
msgRequestVO.setTxtReplYn(this.getTxtReplYn(msgRequestVO));
// 치환데이터가 있을 경우
if("Y".equals(msgRequestVO.getTxtReplYn())){
//일괄변환 문자에 콤마(,) 들어가있으면 배열로 넘길때 문제가 발생하여 특수문자(§) 치환하여 넘겨주도록 한다.
msgRequestVO = this.getReplaceCommaToStrSymbol(msgRequestVO);
// 치환 단문 장문 개수 구하기
msgRequestVO = this.getLengthOfShortAndLongMsg(msgRequestVO);
}
PriceVO priceVO = Price.priceRefine(msgRequestVO.getMberId(), priceMapper);
// +""; => Double to String 같은 기능
msgRequestVO.setsPrice(priceVO.getShortPrice()+"");
msgRequestVO.setmPrice(priceVO.getLongPrice()+"");
msgRequestVO.setpPrice(priceVO.getPicturePrice()+"");
//문자열 길이 체크 해주기
// 문자 바이트 계산에 필요한 캐릭터 : 한글 2Byte로 계산
int FrBytes = getFrBytes(msgRequestVO);
// 단문 장문 단가과 타입 지정
if(FrBytes > 90){
msgRequestVO.setEachPrice(msgRequestVO.getsPrice());
msgRequestVO.setMsgType("6");
}else {
msgRequestVO.setEachPrice(msgRequestVO.getmPrice());
msgRequestVO.setMsgType("4");
}
// 문자 전송하는 부분
// apiService.postForEntity => restTemplate.postForEntity 호출 MjonResponseVO에 맞게 데이터 정제하는 메소드
MjonResponseVO munjaSendResponse = apiService.postForEntity(
"/web/user/login/sendMsgDataAjax.do"
, msgRequestVO
, String.class
);
log.info("munjaSendResponse : [{}]", munjaSendResponse.toString());
log.info("munjaSendResponse : [{}]", munjaSendResponse.getResult());
// convertMjonDataToApiResponse => MjonResponseVO 데이터를 ApiResponse 데이터로 변환하는 메소드
if(!"fail".equals(munjaSendResponse.getResult())){ // 성공
return new RestResponse(SendSucRestResponse.convertMjonDataToApiResponse(munjaSendResponse));
}else{ // 실패
return new RestResponse(new FailRestResponse(StatMsg.randomErrorStatCode(),""));
}
}
@Override
public RestResponse sendMsgData_advc(MsgRequestVO msgRequestVO) throws Exception {
log.info(" :: sendMsgData_advc ::");
@ -153,7 +54,7 @@ public class SendServiceImpl implements SendService {
// step2.수신자 전화번호 정상 여부 체크(정상 번호에 대해서만 발송 가능)
// 1020
// 폰번호 확인 - -> 유효성 정규식
if(this.getCallToListChk(msgRequestVO)){
if(MunjaUtil.getCallToListChk(msgRequestVO.getCallToList())){
return new RestResponse(new FailRestResponse("STAT_1020",""));
}
@ -227,11 +128,6 @@ public class SendServiceImpl implements SendService {
}
private static int getFrBytes(MsgRequestVO msgRequestVO) throws UnsupportedEncodingException {
String smsCont = msgRequestVO.getSmsTxt().replace("\r\n", "\n");
int FrBytes = smsCont.getBytes("euc-kr").length;
return FrBytes;
}
private RestResponse _getTestMsgReturnData(String testYn)
{
@ -291,102 +187,6 @@ public class SendServiceImpl implements SendService {
}
}
@Override
public RestResponse sendMsgsData(MsgsRequestVO msgsRequestVO) throws Exception {
if(StringUtils.isNotEmpty(msgsRequestVO.getTest_yn())){
return this._getTestMsgsReturnData(msgsRequestVO.getTest_yn());
}
// msgsVO -> msgVO List로 변환
List<MsgRequestVO> msgRequestVOList = this.getDataCleaning(msgsRequestVO);
//step1.발신자 전화번호 사용 가능 여부 체크(해당 사용자의 등록된 번호만 발송 가능)
// 1010
log.info("msgRequestVOList : [{}]", msgRequestVOList.size());
log.info("msgRequestVOList : [{}]", msgRequestVOList.get(0).toString());
if(!sendMapper.findByCallFrom(msgRequestVOList.get(0))){
return new RestResponse(new FailRestResponse("STAT_1010",""));
}
// step2.수신자 전화번호 정상 여부 체크(정상 번호에 대해서만 발송 가능)
// 1020
// 폰번호 확인 - -> 유효성 정규식
for(MsgRequestVO msgRequestVO : msgRequestVOList){
if(this.getCallToListChk(msgRequestVO)){
// if(StringUtils.isNotEmpty(this.getCallToListChk(msgRequestVO))){
return this.callToErrorReturnData(msgRequestVO);
}
}
//사용자 잔액
// double mberMoney = priceMapper.selectMberMoney(mberId);
// 이용단가, 발송가능 건수
// PriceVO priceVO = this.price_refine(mberId, mberMoney, priceMapper);
PriceVO priceVO = Price.priceRefine(msgsRequestVO.getMberId(), priceMapper);
// +""; => Double to String 같은 기능
String sPrice = priceVO.getShortPrice()+"";
String mPrice = priceVO.getLongPrice()+"";
String pPrice = priceVO.getPicturePrice()+"";
List<MjonResponseVO> mjonResponseVOList = new ArrayList<MjonResponseVO>();
for(MsgRequestVO msgRequestVO : msgRequestVOList){
//문자열 길이 체크 해주기
// 문자 바이트 계산에 필요한 캐릭터 : 한글 2Byte로 계산
int FrBytes = getFrBytes(msgRequestVO);
// 단문 장문 단가과 타입 지정
if(FrBytes > 90){
msgRequestVO.setEachPrice(sPrice);
msgRequestVO.setMsgType("6");
}else {
msgRequestVO.setEachPrice(mPrice);
msgRequestVO.setMsgType("4");
}
// 단가 셋팅
msgRequestVO.setsPrice(sPrice); // 단문
msgRequestVO.setmPrice(mPrice); // 장문
msgRequestVO.setpPrice(pPrice); // 사진
//step3.문자 내용 정상 여부 확인 - 스미싱 문구는 발송 30분 지연으로 처리됨
// 1030 => 현재 사용안함
// 스팸체크 하는 부분
MjonResponseVO spamChkEntity = apiService.postForEntity(
"/web/user/login/selectSpamTxtChkAjax.do"
, msgRequestVO
, String.class
);
// 스팸체크 결과값이 spams 이면 스팸문자로 처리
// if("spams".equals(spamChkEntity.getResult())){
// msgRequestVO.setSpamStatus("Y");
// };
log.info("msgRequestVO : [{}]", msgRequestVO.toString());
// 문자 전송하는 부분
// apiService.postForEntity => restTemplate.postForEntity 호출 MjonResponseVO에 맞게 데이터 정제하는 메소드
MjonResponseVO munjaSendResponse = apiService.postForEntity(
"/web/mjon/msgdata/sendMsgDataAjax_advc.do"
// "/web/user/login/sendMsgDataAjax.do"
, msgRequestVO
, String.class
);
//
mjonResponseVOList.add(munjaSendResponse);
}
return new RestResponse(SendSucRestResponse.SendSuccessMsgsRestResponse(mjonResponseVOList));
}
@Override
public RestResponse sendMsgsData_advc(MsgsRequestVO msgsRequestVO) throws Exception {
@ -433,91 +233,6 @@ public class SendServiceImpl implements SendService {
return new RestResponse(stat1020);
}
/**
* @description 최대 1~100개의 수신번호와 메세지를 MsgRequestVO로 정재하는 메소드.
* @param msgsRequestVO
* @return
*/
private static List<MsgRequestVO> getDataCleaning(MsgsRequestVO msgsRequestVO) {
List<MsgRequestVO> msgRequestVOList = new ArrayList<>();
// Reflection으로 Object Field에 접근한다.
Field[] declaredFields = msgsRequestVO.getClass().getDeclaredFields();
String mberId = null; // 사용자 ID
String accessKey = null; // accessKey
String callFrom = null; // 발신자 번호
String callTo = null; // 수신자 번호
for (Field field : declaredFields) {
Object value = null;
// private Field일 경우 접근을 허용한다.
field.setAccessible(true);
try {
// Field Value를 참조한다.
value = field.get(msgsRequestVO);
} catch (IllegalAccessException e) {
log.info("Reflection Error. {}", e);
}
// nullPointException 방지
if(value != null)
{
log.info("field.getName() : [{}]", field.getName());
log.info("value.toString() : [{}]", value.toString());
/**
* 필드 이름으로 분기하여
* 각각에 맞는 위치에 값을 넣어준다.
*/
if("mberId".equals(field.getName())){ // 사용자 ID
mberId = value.toString();
}else if("accessKey".equals(field.getName())){ // accessKey
accessKey = value.toString();
}else if("callFrom".equals(field.getName())){ // 발신자 번호
callFrom = value.toString();
}else if(field.getName().startsWith("callTo")){ // 수신자 번호
callTo = value.toString();
}else if(field.getName().startsWith("smsTxt")){ // 문자 내용
// 값이 비여 있으면 다음 반복문으로 넘어간다.
if(StringUtils.isEmpty(value.toString())){
callTo = "";
continue;
}
msgRequestVOList.add(
MsgRequestVO.builder()
.mberId(mberId)
.accessKey(accessKey)
.callFrom(callFrom)
.callToList(new String[]{callTo})
.smsTxt(value.toString())
.eachPrice("0") // 디폴트
.sPrice("0") // 디폴트
.totPrice("0") // 디폴트
.fileCnt("0") // 디폴트
.msgType("4") // 디폴트
.smsPrice(0) // 디폴트
.mmsPrice(0) // 디폴트
.imgFilePath(new String[0]) // 디폴트
.txtReplYn("N") // 디폴트
.reserveYn("N") // 디폴트
.msgKind("N") // 디폴트
.build()
);
// 초기화
callTo = "";
}
}
}
return msgRequestVOList;
}
private static List<MsgRequestVO> getDataCleaning_advc(MsgsRequestVO msgsRequestVO) {
@ -586,238 +301,10 @@ public class SendServiceImpl implements SendService {
}
return msgRequestVOList;
}
/**
* 치환 단문 장문 msg 개수 구하기
* @param msgRequestVO
* @return msgRequestVO
* @throws UnsupportedEncodingException
*/
private static MsgRequestVO getLengthOfShortAndLongMsg(MsgRequestVO msgRequestVO) throws UnsupportedEncodingException {
String charset = "euc-kr";
int totListCnt = msgRequestVO.getCallToList().length;
int shortMsgCnt=0; // 치환 단문 개수
int longMsgCnt=0; // 치환 장문 개수
for(int i=0; i < totListCnt; i ++) {
String smsTxt = msgRequestVO.getSmsTxt().replaceAll(String.valueOf((char)13), ""); //발송 문자 내용
String[] nameList = msgRequestVO.getNameList(); //치환 이름 리스트
String[] phone = msgRequestVO.getCallToList(); //수신자 휴대폰 번호
String[] rep1 = msgRequestVO.getRep1List(); //치환 문자1 리스트
String[] rep2 = msgRequestVO.getRep2List(); //치환 문자2 리스트
String[] rep3 = msgRequestVO.getRep3List(); //치환 문자3 리스트
String[] rep4 = msgRequestVO.getRep4List(); //치환 문자4 리스트
if (smsTxt.indexOf("[*이름*]") > -1) {
if(nameList.length > i && StringUtils.isNotEmpty(nameList[i])) {
smsTxt = smsTxt.replaceAll("\\[\\*이름\\*\\]", MunjaUtil.getString(nameList[i].replaceAll("§", ",")));
}else {
smsTxt = smsTxt.replaceAll("\\[\\*이름\\*\\]", "");
}
}
if (smsTxt.indexOf("[*1*]") > -1) {
if(rep1.length > i && StringUtils.isNotEmpty(rep1[i])) {
smsTxt = smsTxt.replaceAll("\\[\\*1\\*\\]", MunjaUtil.getString(rep1[i].replaceAll("§", ",")));
}else {
smsTxt = smsTxt.replaceAll("\\[\\*1\\*\\]", "");
}
}
if (smsTxt.indexOf("[*2*]") > -1) {
if(rep2.length > i && StringUtils.isNotEmpty(rep2[i])) {
smsTxt = smsTxt.replaceAll("\\[\\*2\\*\\]", MunjaUtil.getString(rep2[i].replaceAll("§", ",")));
}else {
smsTxt = smsTxt.replaceAll("\\[\\*2\\*\\]", "");
}
}
if (smsTxt.indexOf("[*3*]") > -1) {
if(rep3.length > i && StringUtils.isNotEmpty(rep3[i])) {
smsTxt = smsTxt.replaceAll("\\[\\*3\\*\\]", MunjaUtil.getString(rep3[i].replaceAll("§", ",")));
}else {
smsTxt = smsTxt.replaceAll("\\[\\*3\\*\\]", "");
}
}
if (smsTxt.indexOf("[*4*]") > -1) {
if(rep4.length > i && StringUtils.isNotEmpty(rep4[i])) {
smsTxt = smsTxt.replaceAll("\\[\\*4\\*\\]", MunjaUtil.getString(rep4[i].replaceAll("§", ",")));
}else {
smsTxt = smsTxt.replaceAll("\\[\\*4\\*\\]", "");
}
}
int bytes = smsTxt.getBytes(charset).length;
if(bytes > 90) {//장문문자 리스트 만들기
longMsgCnt++;
}else {//단문문자 리스트 만들기
shortMsgCnt++;
}
}
msgRequestVO.setLongMsgCnt(Integer.toString(longMsgCnt));
msgRequestVO.setShortMsgCnt(Integer.toString(shortMsgCnt));
return msgRequestVO;
}
/**
* 치환문자가 있으면 , => § 치환
* @param msgRequestVO
* @return
*/
private static MsgRequestVO getReplaceCommaToStrSymbol(MsgRequestVO msgRequestVO) {
AtomicInteger index = new AtomicInteger();
// 이름 배열
if(StringUtils.isNotEmpty(msgRequestVO.getNameStr()))
{
msgRequestVO.setNameList(msgRequestVO.getNameStr().split("\\|"));
String[] nameList = new String[msgRequestVO.getNameList().length];
Arrays.stream(msgRequestVO.getNameList()).forEach(name -> {
nameList[index.getAndIncrement()] = MunjaUtil.replaceCommaToStrSymbol(name);
});
msgRequestVO.setNameList(nameList);
}
// Rep1 배열
if(StringUtils.isNotEmpty(msgRequestVO.getRep1Str()))
{
index.set(0);
msgRequestVO.setRep1List(msgRequestVO.getRep1Str().split("\\|"));
String[] rep1List = new String[msgRequestVO.getRep1List().length];
Arrays.stream(msgRequestVO.getRep1List()).forEach(str -> {
rep1List[index.getAndIncrement()] = MunjaUtil.replaceCommaToStrSymbol(str);
});
msgRequestVO.setRep1List(rep1List);
}
// Rep2 배열
if(StringUtils.isNotEmpty(msgRequestVO.getRep2Str()))
{
index.set(0);
msgRequestVO.setRep2List(msgRequestVO.getRep2Str().split("\\|"));
String[] rep2List = new String[msgRequestVO.getRep2List().length];
Arrays.stream(msgRequestVO.getRep2List()).forEach(str -> {
rep2List[index.getAndIncrement()] = MunjaUtil.replaceCommaToStrSymbol(str);
});
msgRequestVO.setRep2List(rep2List);
}
// Rep3 배열
if(StringUtils.isNotEmpty(msgRequestVO.getRep3Str()))
{
index.set(0);
msgRequestVO.setRep3List(msgRequestVO.getRep3Str().split("\\|"));
String[] rep3List = new String[msgRequestVO.getRep3List().length];
Arrays.stream(msgRequestVO.getRep3List()).forEach(str -> {
rep3List[index.getAndIncrement()] = MunjaUtil.replaceCommaToStrSymbol(str);
});
msgRequestVO.setRep3List(rep3List);
}
// Rep4 배열
if(StringUtils.isNotEmpty(msgRequestVO.getRep4Str()))
{
index.set(0);
msgRequestVO.setRep4List(msgRequestVO.getRep4Str().split("\\|"));
String[] rep4List = new String[msgRequestVO.getRep4List().length];
Arrays.stream(msgRequestVO.getRep4List()).forEach(str -> {
rep4List[index.getAndIncrement()] = MunjaUtil.replaceCommaToStrSymbol(str);
});
msgRequestVO.setRep4List(rep4List);
}
return msgRequestVO;
}
/**
* 치환 문자 여부 확인
* @param msgRequestVO
* @return
*/
private static String getTxtReplYn(MsgRequestVO msgRequestVO) {
// 치환 데이터 확인
Arrays.stream(replaseStrList.split(",")).forEach(
str -> {
if(msgRequestVO.getSmsTxt().indexOf(str) > -1){
msgRequestVO.setTxtReplYn("Y");
}
}
);
return msgRequestVO.getTxtReplYn();
}
/**
* 수신자 목록 번호 검증
* message가 없으면 정상
* @param msgRequestVO
* @return String
*/
private static Boolean getCallToListChk(MsgRequestVO msgRequestVO) {
Boolean returnData = false;
String[] test = msgRequestVO.getCallToList();
if (ArrayUtils.isEmpty(test)) {
returnData = true;
}
for(String callTo : msgRequestVO.getCallToList()){
/*
if(!MunjaUtil.checkPhoneNumberEmpty(callTo)){
message = "수신 목록에 핸드폰 번호가 없는 항목이 있습니다."; break;};
if(!MunjaUtil.validatePNumWithRegex(callTo)){
message = "휴대폰 번호가 올바르지 않습니다. : " + callTo; break;};
*/
if(!MunjaUtil.checkPhoneNumberEmpty(callTo) // 비여있는지 체크
|| !MunjaUtil.validatePNumWithRegex(callTo) // 정규식으로 번호 체크
)
{
returnData = true;
break;
};
}
return returnData;
}
/**
* MjonResponseVO -> 변환 -> SendFailRestResponse
* @param mjonResponseVO
* @return
*/
public static String convertMjonDataToApiResponse(MjonResponseVO mjonResponseVO) {
String result = mjonResponseVO.getResult();
log.info("convertMjonDataToApiResponse : [{}]", result);
String message = mjonResponseVO.getMessage();
log.info("convertMjonDataToApiResponse : [{}]", message);
String statCode = "";
switch (result) {
case "statusFail" : statCode = "1070"; // 회원 정지
break;
case "smsLengFail" : statCode = "1080"; // 문자 길이 초과
break;
case "fail" : // 문자온 프로젝트에서 result가 fail로 다양한 에러가 리턴하여 분기처리함
if(message.indexOf("문자 치환 후 전송 문자 길이를 초과하였습니다.")>-1)
statCode = "1050"; // 치환 문자 길이 초과
else if(message.indexOf("치환문자 데이터가 없습니다")>-1)
statCode = "1040"; // 치환 데이터 오류
else if(message.indexOf("치환 후 전송 문자 길이를 초과")>-1)
statCode = "1050"; // 치환 데이터 오류
else
statCode = "1099"; // 기타 시스템 오류
break;
default: statCode = "1099"; // 기타 시스템 오류
break;
}
return "STAT_"+statCode;
}
}

View File

@ -10,7 +10,6 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* packageName : com.itn.mjonApi.mjon.send.web
@ -24,18 +23,11 @@ import org.springframework.web.client.RestTemplate;
* 2023-02-15 hylee 최초 생성
*/
// 치환문자가 있으면 , => § 치환
@Slf4j
@RestController
public class SendRestController {
private final RestTemplate restTemplate;
public SendRestController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@Autowired
private SendService sendService;

View File

@ -1,5 +1,6 @@
package com.itn.mjonApi.util;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
/**
@ -49,7 +50,7 @@ public class MunjaUtil {
* 파라미터를 String 타입으로 가져옵니다.<br>
* - null일 경우 문자열을 가져옵니다.<br>
* Get String(if object is null, return empty string).
* @param Object
* @param obj
* @return String
*/
public static String getString(Object obj) {
@ -59,5 +60,31 @@ public class MunjaUtil {
return String.valueOf(obj);
}
/**
* 수신자 목록 번호 검증
* message가 없으면 정상
* @param callToList
* @return String
*/
public static Boolean getCallToListChk(String[] callToList) {
Boolean returnData = false;
if (ArrayUtils.isEmpty(callToList)) {
return true;
}
for(String callTo : callToList){
if(!MunjaUtil.checkPhoneNumberEmpty(callTo) // 비여있는지 체크
|| !MunjaUtil.validatePNumWithRegex(callTo) // 정규식으로 번호 체크
)
{
return true;
};
}
return returnData;
}
}

View File

@ -3,9 +3,9 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itn.mjonApi.mjon.api.kakao.inqry.mapper.InqryMapper">
<mapper namespace="com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.InqryMapper">
<select id="getChnlIds" resultType="MjKakaoProfileInfoVO">
<select id="getChnlIds" resultType="com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.domain.MjKakaoProfileInfoVO">
SELECT
-- USER_ID