친구톡 발송 완료
This commit is contained in:
parent
f5029faba2
commit
2376446be3
@ -351,9 +351,12 @@ public class LogAspect {
|
||||
case "MjKakaoProfileInfoVO":
|
||||
case "BizTemplateRequest":
|
||||
case "MsgAtRequestVO":
|
||||
case "MsgFtRequestVO":
|
||||
case "String":
|
||||
case "ArrayList":
|
||||
return ApiObjectUtil.toJson(returnValue);
|
||||
default:
|
||||
log.info("데이터를 추가해 주세요");
|
||||
log.info("데이터를 추가해 주세요 [{}]", classNm);
|
||||
return "데이터를 추가해 주세요";
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,6 +145,9 @@ public class ApiService <T> {
|
||||
if (msgFtRequestVO.getSendKind() != null) {
|
||||
body.add("sendKind", msgFtRequestVO.getSendKind());
|
||||
}
|
||||
if ( msgFtRequestVO.getTemplateMsgType() != null) {
|
||||
body.add("imageType", msgFtRequestVO.getTemplateMsgType());
|
||||
}
|
||||
if (msgFtRequestVO.getTemplateCode() != null) {
|
||||
body.add("templateCode", msgFtRequestVO.getTemplateCode());
|
||||
}
|
||||
@ -159,7 +162,7 @@ public class ApiService <T> {
|
||||
StatusResponse.class
|
||||
);
|
||||
|
||||
log.info("Upload response :: [{}]", response.getBody());
|
||||
// log.info("Upload response :: [{}]", response.getBody());
|
||||
return response.getBody();
|
||||
|
||||
}
|
||||
|
||||
@ -50,6 +50,7 @@ public enum StatMsg {
|
||||
, STAT_2040("2040","본문 데이터 오류")
|
||||
, STAT_2041("2041","타이틀 데이터 오류")
|
||||
, STAT_2042("2042","대체문자 데이터 오류")
|
||||
, STAT_2043("2043","대체문자 발송 시 발신번호가 필요합니다.")
|
||||
|
||||
, STAT_2050("2050","지원하지 않는 이미지 형식입니다.")
|
||||
, STAT_2051("2051","이미지 용량은 5MB 이내여야 합니다.")
|
||||
@ -60,6 +61,8 @@ public enum StatMsg {
|
||||
, STAT_2056("2056","비율 2:1 이상 또는 3:4 이하만 허용됩니다.")
|
||||
, STAT_2057("2057","대체문자(MMS) 이미지는 10MB를 초과할 수 없습니다.")
|
||||
|
||||
, STAT_2080("2080","친구톡은 20시 50분부터 익일 08시까지 발송이 제한됩니다.")
|
||||
|
||||
, STAT_2099("2099","기타 시스템 오류")
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
package com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
@ToString
|
||||
@Getter
|
||||
@Setter
|
||||
public class KakaoFTSendVO {
|
||||
|
||||
// 카카오 발신 관련
|
||||
private String mberId; // mberId
|
||||
private String senderKey; // 카카오 발신 키 (필수)
|
||||
private String adFlag; // 카카오 발신 키 (필수)
|
||||
|
||||
// 이미지 관련
|
||||
private String imageFileName; // 이미지 파일명
|
||||
private String imageType; // 이미지 타입 (I: 이미지, null: 텍스트만)
|
||||
private String atchFileId; // 첨부파일 ID
|
||||
private String templateImageUrl; // 친구톡 이미지 URL
|
||||
|
||||
// 메시지 내용
|
||||
private String templateContent; // 친구톡 발송 내용 (개별 수신자별)
|
||||
private String subMsgSendYn; // 대체문자 발송여부
|
||||
private String subMsgTxt; // 대체문자 내용 (개별 수신자별)
|
||||
|
||||
// 발송 관련
|
||||
private String reserveYn; // 예약발송 여부 (기본: N)
|
||||
private String callFrom; // 발신번호
|
||||
private String reqDate; // 요청일시 (예약발송시)
|
||||
private String sendKind; // 발송 구분 , A : API / H : 사이트
|
||||
|
||||
// 버튼 정보 (모든 수신자 공통)
|
||||
@Builder.Default
|
||||
private List<KakaoButtonVO> buttonVOList = new ArrayList<>();
|
||||
|
||||
// 수신자 목록 (핵심: 개별 발송시 1명만 포함)
|
||||
@Builder.Default
|
||||
private List<MjonFTSendVO> mjonFTSendVOList = new ArrayList<>();
|
||||
}
|
||||
@ -55,9 +55,6 @@ public class MsgFtRequestVO implements Serializable {
|
||||
@ToString.Exclude
|
||||
private MultipartFile templateImage;
|
||||
|
||||
@JsonIgnore
|
||||
@ToString.Exclude
|
||||
private MultipartFile subImage;
|
||||
|
||||
// ====== ⬇️ AOP/DB 저장용(문자열/숫자만) 메타데이터 필드들 ======
|
||||
// template
|
||||
@ -70,9 +67,31 @@ public class MsgFtRequestVO implements Serializable {
|
||||
private String templateImageSavedPath; // 서버 저장 경로(선택)
|
||||
private String templateAtchFileId; // 내부 첨부ID(선택)
|
||||
private String templateMsgType;
|
||||
private String templateImageUrl;
|
||||
|
||||
/**
|
||||
* @description : 친구톡 이미지 등록된 URL
|
||||
*/
|
||||
private String templateImageUrl;
|
||||
|
||||
/**
|
||||
* @description : 치환문자 이미지
|
||||
* 이미지 문자가 있고 대체문자가 있으면(subMsgSendYn="Y") filepath에 atchFileId 있어야함
|
||||
*/
|
||||
private String filePath1;
|
||||
|
||||
|
||||
/**
|
||||
* @description : 버튼 사용
|
||||
*/
|
||||
private List<FtButtonVO> buttons = new ArrayList<>();
|
||||
|
||||
|
||||
// sub
|
||||
|
||||
// @JsonIgnore
|
||||
// @ToString.Exclude
|
||||
// private MultipartFile subImage;
|
||||
|
||||
// private String subImageName;
|
||||
// private String subImageContentType;
|
||||
// private Long subImageSize;
|
||||
|
||||
@ -5,9 +5,6 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
@ -29,15 +26,6 @@ public class VarFtListMapVO {
|
||||
*/
|
||||
private String subMsgTxt;
|
||||
|
||||
/**
|
||||
* @description : 치환문자 이미지
|
||||
*/
|
||||
private String filePath1;
|
||||
|
||||
/**
|
||||
* @description : 버튼 사용
|
||||
*/
|
||||
private List<FtButtonVO> buttons = new ArrayList<>();
|
||||
|
||||
//
|
||||
// /**
|
||||
|
||||
@ -41,7 +41,7 @@ public class FtIndexedParameterParserService {
|
||||
* @param request HTTP 요청 객체
|
||||
* @return 파싱된 VarListMapVO 리스트
|
||||
*/
|
||||
public List<VarFtListMapVO> parseIndexedParameters(MsgFtRequestVO msgAtRequestVO, HttpServletRequest request) {
|
||||
public List<VarFtListMapVO> parseIndexedParameters(MsgFtRequestVO msgFtRequestVO, HttpServletRequest request) {
|
||||
List<VarFtListMapVO> varListMap = new ArrayList<>();
|
||||
|
||||
// 모든 파라미터 맵 가져오기
|
||||
@ -51,7 +51,7 @@ public class FtIndexedParameterParserService {
|
||||
Map<Integer, Map<String, String>> indexedDataMap = new HashMap<>();
|
||||
|
||||
|
||||
String subMsgSendYn = msgAtRequestVO.getSubMsgSendYn();
|
||||
String subMsgSendYn = msgFtRequestVO.getSubMsgSendYn();
|
||||
|
||||
// 모든 파라미터를 순회하며 인덱스된 파라미터 찾기
|
||||
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
|
||||
@ -84,18 +84,24 @@ public class FtIndexedParameterParserService {
|
||||
if("Y".equals(subMsgSendYn)){
|
||||
vo.setSubMsgTxt(dataMap.get("subMsgTxt"));
|
||||
}
|
||||
|
||||
// 버튼 데이터 처리
|
||||
String buttonData = dataMap.get("button");
|
||||
if (buttonData != null && !buttonData.trim().isEmpty()) {
|
||||
try {
|
||||
JsonNode buttonJson = objectMapper.readTree(buttonData);
|
||||
JsonNode buttonArray = buttonJson.get("button");
|
||||
|
||||
List<FtButtonVO> buttonList = new ArrayList<>();
|
||||
if (buttonArray != null && buttonArray.isArray()) {
|
||||
for (JsonNode button : buttonArray) {
|
||||
FtButtonVO ftButton = FtButtonVO.builder()
|
||||
// 필수 필드 중 하나라도 있으면 리스트에 추가
|
||||
if (vo.getPhone() != null || vo.getTemplateContent() != null) {
|
||||
varListMap.add(vo);
|
||||
}
|
||||
}
|
||||
|
||||
// 버튼 파라미터를 요청 레벨에서 한 번만 파싱
|
||||
String buttonData = request.getParameter("button");
|
||||
|
||||
if (buttonData != null && !buttonData.trim().isEmpty()) {
|
||||
try {
|
||||
JsonNode buttonJson = objectMapper.readTree(buttonData);
|
||||
JsonNode buttonArray = buttonJson.get("button");
|
||||
|
||||
List<FtButtonVO> buttonList = new ArrayList<>();
|
||||
if (buttonArray != null && buttonArray.isArray()) {
|
||||
for (JsonNode button : buttonArray) {
|
||||
FtButtonVO ftButton = FtButtonVO.builder()
|
||||
.name(getJsonText(button, "name"))
|
||||
.linkType(getJsonText(button, "linkType"))
|
||||
.linkTypeName(getJsonText(button, "linkTypeName"))
|
||||
@ -104,24 +110,17 @@ public class FtIndexedParameterParserService {
|
||||
.linkIos(getJsonText(button, "linkIos"))
|
||||
.linkAnd(getJsonText(button, "linkAnd"))
|
||||
.build();
|
||||
buttonList.add(ftButton);
|
||||
}
|
||||
buttonList.add(ftButton);
|
||||
}
|
||||
vo.setButtons(buttonList);
|
||||
} catch (Exception e) {
|
||||
log.error("버튼 JSON 파싱 실패 - index: {}, data: {}", index, buttonData, e);
|
||||
vo.setButtons(new ArrayList<>());
|
||||
}
|
||||
// ✅ MsgFtRequestVO에 버튼 설정 (모든 수신자 공통)
|
||||
msgFtRequestVO.setButtons(buttonList);
|
||||
} catch (Exception e) {
|
||||
log.error("버튼 JSON 파싱 실패: {}", buttonData, e);
|
||||
msgFtRequestVO.setButtons(new ArrayList<>());
|
||||
}
|
||||
|
||||
// 필수 필드 중 하나라도 있으면 리스트에 추가
|
||||
if (vo.getPhone() != null || vo.getTemplateContent() != null) {
|
||||
varListMap.add(vo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return varListMap;
|
||||
}
|
||||
|
||||
@ -1,23 +1,25 @@
|
||||
package com.itn.mjonApi.mjon.api.kakao.ft.send.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.itn.mjonApi.cmn.domain.biz.template.BizTemplateRequest;
|
||||
import com.itn.mjonApi.cmn.domain.biz.template.detail.TemplateDetailResponse;
|
||||
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||
import com.itn.mjonApi.cmn.apiServer.ApiService;
|
||||
import com.itn.mjonApi.cmn.domain.StatusResponse;
|
||||
import com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.domain.MjKakaoProfileInfoVO;
|
||||
import com.itn.mjonApi.mjon.api.kakao.at.inqry.service.InqryService;
|
||||
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.MsgFtRequestVO;
|
||||
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.VarFtListMapVO;
|
||||
import com.itn.mjonApi.mjon.api.kakao.utils.FtFileMetaUtil;
|
||||
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 javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* fileName : AtParameterProcessingService.java
|
||||
@ -40,6 +42,12 @@ public class FtParameterProcessingService {
|
||||
@Autowired
|
||||
private InqryService inqryService;
|
||||
|
||||
private ApiService<Response> apiService;
|
||||
|
||||
@Autowired
|
||||
public FtParameterProcessingService(ApiService<Response> apiService) {
|
||||
this.apiService = apiService;
|
||||
}
|
||||
/**
|
||||
* HttpServletRequest에서 동적으로 인덱스된 파라미터들을 파싱하고 검증하여
|
||||
* MsgAtRequestVO의 varListMap에 설정
|
||||
@ -63,11 +71,12 @@ public class FtParameterProcessingService {
|
||||
// if (STAT_2030 != null) return STAT_2030;
|
||||
|
||||
// 파싱 로직을 IndexedParameterParserService에 위임
|
||||
log.info("msgFtRequestVO.getAdFlag() :: [{}]", msgFtRequestVO.getAdFlag());
|
||||
List<VarFtListMapVO> parsedList = indexedParameterParserService.parseIndexedParameters(msgFtRequestVO, request);
|
||||
|
||||
// 파싱된 각 VO에 대해 검증 수행
|
||||
for (VarFtListMapVO vo : parsedList) {
|
||||
String validationError = MunjaUtil.kakaoFtValidate(vo, msgFtRequestVO.getSubMsgSendYn());
|
||||
String validationError = MunjaUtil.kakaoFtValidate(vo, msgFtRequestVO);
|
||||
|
||||
if (StringUtils.isNotEmpty(validationError)) {
|
||||
return validationError; // 검증 실패 시 오류 코드 반환
|
||||
@ -80,35 +89,6 @@ public class FtParameterProcessingService {
|
||||
return null; // 모든 검증 통과
|
||||
}
|
||||
|
||||
private String validateTemplateCode(String mberId, String senderKey, String templateCode) {
|
||||
try {
|
||||
BizTemplateRequest request = BizTemplateRequest.builder()
|
||||
.mberId(mberId)
|
||||
.senderKey(senderKey)
|
||||
.templateCode(templateCode)
|
||||
.build();
|
||||
|
||||
RestResponse response = inqryService.getTemplateDetail(request);
|
||||
JsonNode node = new ObjectMapper().valueToTree(response.getData());
|
||||
// 전체 출력
|
||||
// log.info("data 전체 :: {}", node.toPrettyString());
|
||||
// resultCode가 있으면 채널ID 오류 + inqryService.getTemplateDetail 참조
|
||||
if (node.has("resultCode")) {
|
||||
return "STAT_"+node.get("resultCode").asText();
|
||||
}
|
||||
|
||||
TemplateDetailResponse detail = (TemplateDetailResponse)
|
||||
response.getData();
|
||||
|
||||
// 템플릿 상세 정보 활용
|
||||
log.info("template detail :: [{}]", detail);
|
||||
return "200".equals(detail.getCode()) ? null : "STAT_2030";
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "STAT_2099";
|
||||
}
|
||||
}
|
||||
|
||||
public String validateSenderKey(String mberId, String senderKey) {
|
||||
if (StringUtils.isEmpty(senderKey)) {
|
||||
@ -120,6 +100,41 @@ public class FtParameterProcessingService {
|
||||
}
|
||||
|
||||
|
||||
public String getImagesInfo(MsgFtRequestVO msgFtRequestVO) throws IOException, NoSuchAlgorithmException {
|
||||
|
||||
log.info("msgFtRequestVO.getTemplateImage() : [{}]", msgFtRequestVO.getTemplateImage());
|
||||
if (FtFileMetaUtil.hasFile(msgFtRequestVO.getTemplateImage())) {
|
||||
String code = FtFileMetaUtil.fillTemplateMeta(msgFtRequestVO);
|
||||
if (StringUtils.isNotEmpty(code)) return code;
|
||||
|
||||
// 메타데이터 처리 성공 후 업로드 API 호출
|
||||
try {
|
||||
// Option 1: ApiService에 multipart 메소드 추가
|
||||
StatusResponse uploadResponse = apiService.postMultipartForEntity(
|
||||
"/web/mjon/kakao/template/sendKakaoFriendsTemplateImageUploadAjax_advc.do",
|
||||
msgFtRequestVO,
|
||||
msgFtRequestVO.getTemplateImage()
|
||||
);
|
||||
// .is2xxSuccessful() 상태코드가 200번대(200 ~ 299)인지 확인
|
||||
if (uploadResponse != null && uploadResponse.getStatus().is2xxSuccessful()) {
|
||||
Map<String, Object> obj = (Map<String, Object>) uploadResponse.getObject();
|
||||
String imgUrl = (String) obj.get("imgUrl");
|
||||
String atchFileId = (String) obj.get("atchFileId");
|
||||
|
||||
log.info("imgUrl: {}, atchFileId: {}", imgUrl, atchFileId);
|
||||
msgFtRequestVO.setTemplateImageUrl(imgUrl);
|
||||
msgFtRequestVO.setFilePath1(atchFileId);
|
||||
}else{
|
||||
// return new RestResponse(new FailRestResponse("STAT_2099", ""));
|
||||
return "STAT_2099";
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("템플릿 이미지 업로드 실패", e);
|
||||
return "STAT_2099";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,15 +1,14 @@
|
||||
package com.itn.mjonApi.mjon.api.kakao.ft.send.service.impl;
|
||||
|
||||
import com.itn.mjonApi.cmn.apiServer.ApiService;
|
||||
import com.itn.mjonApi.cmn.domain.StatusResponse;
|
||||
import com.itn.mjonApi.cmn.msg.FailRestResponse;
|
||||
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.MsgFtRequestVO;
|
||||
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.*;
|
||||
import com.itn.mjonApi.mjon.api.kakao.ft.send.service.FtParameterProcessingService;
|
||||
import com.itn.mjonApi.mjon.api.kakao.ft.send.service.SendFtService;
|
||||
import com.itn.mjonApi.mjon.api.kakao.utils.FtFileMetaUtil;
|
||||
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 lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.catalina.connector.Response;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -19,6 +18,8 @@ import org.springframework.stereotype.Service;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@ -60,48 +61,7 @@ public class SendFtServiceImpl implements SendFtService {
|
||||
// return this._getTestMsgReturnData(msgRequestVO.getTest_yn());
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (FtFileMetaUtil.hasFile(msgFtRequestVO.getTemplateImage())) {
|
||||
String code = FtFileMetaUtil.fillTemplateMeta(msgFtRequestVO);
|
||||
if (StringUtils.isNotEmpty(code)) return new RestResponse(new FailRestResponse(code, ""));
|
||||
}
|
||||
// if (FtFileMetaUtil.hasFile(msgFtRequestVO.getSubImage())) {
|
||||
// code = FtFileMetaUtil.fillSubMeta(msgFtRequestVO);
|
||||
// if (StringUtils.isNotEmpty(code)) return new RestResponse(new FailRestResponse(code, ""));
|
||||
// }
|
||||
if (FtFileMetaUtil.hasFile(msgFtRequestVO.getTemplateImage())) {
|
||||
String code = FtFileMetaUtil.fillTemplateMeta(msgFtRequestVO);
|
||||
if (StringUtils.isNotEmpty(code)) return new RestResponse(new FailRestResponse(code, ""));
|
||||
|
||||
// 메타데이터 처리 성공 후 업로드 API 호출
|
||||
try {
|
||||
// Option 1: ApiService에 multipart 메소드 추가
|
||||
StatusResponse uploadResponse = apiService.postMultipartForEntity(
|
||||
"/web/mjon/kakao/template/sendKakaoFriendsTemplateImageUploadAjax_advc.do",
|
||||
msgFtRequestVO,
|
||||
msgFtRequestVO.getTemplateImage()
|
||||
);
|
||||
|
||||
log.info("전체 StatusResponse :: [{}]", uploadResponse);
|
||||
log.info("object 필드만 :: [{}]", uploadResponse.getObject());
|
||||
|
||||
// 업로드 결과 처리
|
||||
// if ("OK".equals(uploadResponse.getResult())) {
|
||||
// // 성공 처리
|
||||
// log.info("템플릿 이미지 업로드 성공");
|
||||
// } else {
|
||||
// // 실패 처리
|
||||
// return new RestResponse(new FailRestResponse(uploadResponse.getStatCode(), ""));
|
||||
// }
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("템플릿 이미지 업로드 실패", e);
|
||||
return new RestResponse(new FailRestResponse("UPLOAD_ERROR", ""));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 데이터
|
||||
// Form-data의 인덱스된 파라미터들을 VarListMapVO 리스트로 변환 (동적 처리 _1~_100)
|
||||
String falseCode = ftParameterProcessingService.processIndexedParameters(msgFtRequestVO, request);
|
||||
if(StringUtils.isNotEmpty(falseCode)){
|
||||
@ -109,29 +69,128 @@ public class SendFtServiceImpl implements SendFtService {
|
||||
return new RestResponse(new FailRestResponse(falseCode,""));
|
||||
}
|
||||
|
||||
// 이미지 정제
|
||||
String falseImageCode = ftParameterProcessingService.getImagesInfo(msgFtRequestVO);
|
||||
if(StringUtils.isNotEmpty(falseImageCode)) return new RestResponse(new FailRestResponse(falseImageCode,""));
|
||||
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// MjonResponseVO munjaSendResponse = apiService.postForEntity(
|
||||
// "/web/mjon/kakao/friendstalk/kakaoFriendsTalkMsgSendAjax_advc.do"
|
||||
// , msgFtRequestVO
|
||||
// , String.class
|
||||
// );
|
||||
// ========== 새로운 개별 발송 코드 ==========
|
||||
List<MjonResponseVO> responses = new ArrayList<>();
|
||||
List<String> successList = new ArrayList<>();
|
||||
List<String> failList = new ArrayList<>();
|
||||
|
||||
|
||||
// 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(),""));
|
||||
// }
|
||||
log.info("msgFtRequestVO.toString() :: [{}]", msgFtRequestVO.toString());
|
||||
// 각 수신자별로 개별 발송 처리
|
||||
// List<KakaoFTSendVO> individualRequestList = new ArrayList<>();
|
||||
for (VarFtListMapVO recipient : msgFtRequestVO.getVarListMap()) {
|
||||
try {
|
||||
// 개별 수신자용 KakaoFTSendVO 생성
|
||||
KakaoFTSendVO individualRequest = createKakaoFTSendVO(msgFtRequestVO, recipient);
|
||||
// individualRequestList.add(individualRequest);
|
||||
|
||||
return new RestResponse(msgFtRequestVO);
|
||||
log.info("individualRequest: {}", individualRequest);
|
||||
|
||||
// 개별 API 호출
|
||||
MjonResponseVO response = apiService.postForEntity(
|
||||
"/web/mjon/kakao/friendstalk/kakaoFriendsTalkMsgSendAjax_advc.do",
|
||||
individualRequest,
|
||||
String.class
|
||||
);
|
||||
log.info("response: {}", response);
|
||||
|
||||
responses.add(response);
|
||||
successList.add(recipient.getPhone());
|
||||
|
||||
log.info("개별 발송 성공 - 수신번호: {}", recipient.getPhone());
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("개별 발송 실패 - 수신번호: {}, 오류: {}", recipient.getPhone(), e.getMessage());
|
||||
failList.add(recipient.getPhone());
|
||||
}
|
||||
}
|
||||
|
||||
// SMS API 형태의 응답 생성
|
||||
FtSendSuccessResponse ftResponse = FtSendSuccessResponse.createFtResponse(
|
||||
msgFtRequestVO.getVarListMap().size(),
|
||||
successList.size(),
|
||||
failList.size(),
|
||||
successList
|
||||
);
|
||||
|
||||
return new RestResponse(ftResponse);
|
||||
// return new RestResponse(individualRequestList);
|
||||
}
|
||||
|
||||
/**
|
||||
* MsgFtRequestVO + VarFtListMapVO를 KakaoFTSendVO로 변환
|
||||
* (개별 수신자용 객체 생성)
|
||||
*/
|
||||
private KakaoFTSendVO createKakaoFTSendVO(MsgFtRequestVO source, VarFtListMapVO recipient) {
|
||||
|
||||
// 버튼 변환 (FtButtonVO → KakaoButtonVO)
|
||||
List<KakaoButtonVO> kakaoButtons = source.getButtons().stream()
|
||||
.map(this::convertToKakaoButton)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 개별 수신자 객체 생성
|
||||
MjonFTSendVO mjonFTSend = MjonFTSendVO.builder()
|
||||
.phone(recipient.getPhone()) // 핵심: 수신번호
|
||||
// .callTo(recipient.getPhone()) // 동일값
|
||||
// .eventYn("N") // 기본값
|
||||
.build();
|
||||
|
||||
// KakaoFTSendVO 생성
|
||||
return KakaoFTSendVO.builder()
|
||||
// 공통 정보 (모든 요청에 동일)
|
||||
|
||||
.mberId(source.getMberId())
|
||||
.sendKind(source.getSendKind())
|
||||
.reserveYn("N")
|
||||
.adFlag(source.getAdFlag())
|
||||
|
||||
.senderKey(source.getSenderKey())
|
||||
.callFrom(source.getCallFrom())
|
||||
.buttonVOList(kakaoButtons)
|
||||
|
||||
// 이미지 관련
|
||||
.templateImageUrl(source.getTemplateImageUrl())
|
||||
.atchFileId(source.getFilePath1())
|
||||
.imageType(source.getTemplateImageUrl() != null ? source.getTemplateMsgType() : null)
|
||||
// .imageFileName(extractFileName(source.getTemplateImageUrl()))
|
||||
.imageFileName(source.getTemplateImageName())
|
||||
|
||||
// 개별 수신자 정보
|
||||
.templateContent(recipient.getTemplateContent()) // 개별 내용
|
||||
.subMsgSendYn(source.getSubMsgSendYn()) // 개별 대체문자
|
||||
.subMsgTxt(recipient.getSubMsgTxt()) // 개별 대체문자
|
||||
.mjonFTSendVOList(Arrays.asList(mjonFTSend)) // 단일 수신자만
|
||||
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* FtButtonVO를 KakaoButtonVO로 변환
|
||||
*/
|
||||
private KakaoButtonVO convertToKakaoButton(FtButtonVO source) {
|
||||
return KakaoButtonVO.builder()
|
||||
.name(source.getName())
|
||||
.linkType(source.getLinkType())
|
||||
.linkTypeName(source.getLinkTypeName())
|
||||
.linkMo(source.getLinkMo())
|
||||
.linkPc(source.getLinkPc())
|
||||
.linkIos(source.getLinkIos())
|
||||
.linkAnd(source.getLinkAnd())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 이미지 URL에서 파일명 추출
|
||||
*/
|
||||
private String extractFileName(String imageUrl) {
|
||||
if (imageUrl == null) return null;
|
||||
return imageUrl.substring(imageUrl.lastIndexOf('/') + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.itn.mjonApi.util;
|
||||
|
||||
import com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain.VarAtListMapVO;
|
||||
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.MsgFtRequestVO;
|
||||
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.VarFtListMapVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
@ -141,7 +142,7 @@ public class MunjaUtil {
|
||||
}
|
||||
|
||||
|
||||
public static String kakaoFtValidate(VarFtListMapVO vo, String subMsgSendYn) {
|
||||
public static String kakaoFtValidate(VarFtListMapVO vo, MsgFtRequestVO msgFtRequestVO) {
|
||||
|
||||
log.info(" vo.toString() [{}]", vo.toString());
|
||||
|
||||
@ -158,11 +159,17 @@ public class MunjaUtil {
|
||||
}
|
||||
|
||||
// 대체문자 검증 (대체문자 발송이 활성화된 경우에만)
|
||||
if ("Y".equals(subMsgSendYn)) {
|
||||
if ("Y".equals(msgFtRequestVO.getSubMsgSendYn())) {
|
||||
String subMsgTxt = vo.getSubMsgTxt();
|
||||
if (StringUtils.isEmpty(subMsgTxt)) {
|
||||
return "STAT_2042"; // 대체문자 데이터 오류
|
||||
}
|
||||
|
||||
String callFrom = msgFtRequestVO.getCallFrom();
|
||||
if (StringUtils.isEmpty(callFrom)) {
|
||||
return "STAT_2043"; // 대체문자 발송 시 발신번호 필요
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 모든 검증 통과
|
||||
|
||||
Loading…
Reference in New Issue
Block a user