Skip to content

Commit

Permalink
Merge pull request #256 from sharemindteam/feat/sms-api
Browse files Browse the repository at this point in the history
feat: sms 발송 api 연동
  • Loading branch information
aeyongdodam authored Aug 29, 2024
2 parents b4c27ef + 08605ec commit a9b577d
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
import com.example.sharemind.admin.dto.response.PostGetUnpaidPrivateResponse;
import com.example.sharemind.counselor.dto.response.CounselorGetProfileResponse;

import com.example.sharemind.sms.dto.response.SmsGetResponse;
import java.util.List;

public interface AdminService {
List<ConsultGetUnpaidResponse> getUnpaidConsults();

void updateConsultIsPaid(Long consultId);

SmsGetResponse updateConsultIsPaid(Long consultId);
List<CounselorGetProfileResponse> getPendingCounselors();

void updateProfileStatus(Long counselorId, Boolean isPassed);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
import com.example.sharemind.post.domain.Post;
import com.example.sharemind.post.exception.PostErrorCode;
import com.example.sharemind.post.exception.PostException;
import com.example.sharemind.sms.application.SmsService;
import com.example.sharemind.sms.dto.response.SmsGetResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
Expand All @@ -52,6 +54,7 @@
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class AdminServiceImpl implements AdminService {

private static final String SHUT_DOWN_KEY = "SHUT_DOWN";

private final ConsultService consultService;
Expand All @@ -62,6 +65,7 @@ public class AdminServiceImpl implements AdminService {
private final CustomerService customerService;
private final PostService postService;
private final EmailService emailService;
private final SmsService smsService;
private final RedisTemplate<String, Boolean> redisTemplate;

@Override
Expand All @@ -72,7 +76,7 @@ public List<ConsultGetUnpaidResponse> getUnpaidConsults() {
}

@Transactional
public void updateConsultIsPaid(Long consultId) {
public SmsGetResponse updateConsultIsPaid(Long consultId) {
Consult consult = consultService.getConsultByConsultId(consultId);
if (consult.getPayment().getIsPaid()) {
throw new ConsultException(ConsultErrorCode.CONSULT_ALREADY_PAID, consultId.toString());
Expand All @@ -90,6 +94,7 @@ public void updateConsultIsPaid(Long consultId) {
consult.updateIsPaidAndChat(chat);
}
}
return smsService.sendSmsCounselor(consult.getCounselor().getCounselorId());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.example.sharemind.admin.dto.response.PostGetUnpaidPrivateResponse;
import com.example.sharemind.counselor.dto.response.CounselorGetProfileResponse;
import com.example.sharemind.global.exception.CustomExceptionResponse;
import com.example.sharemind.sms.dto.response.SmsGetResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
Expand Down Expand Up @@ -44,7 +45,7 @@ public ResponseEntity<List<ConsultGetUnpaidResponse>> getUnpaidConsults() {

@Operation(summary = "상담(편지/채팅) 결제 여부 수정", description = "결제 여부(isPaid)가 false인 consult를 true로 수정")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "수정 성공"),
@ApiResponse(responseCode = "200", description = "수정 성공, resultCode로 sms api 발송 여부가 전달됩니다."),
@ApiResponse(responseCode = "400", description = "이미 결제 완료된 상담",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = CustomExceptionResponse.class))
Expand All @@ -58,9 +59,8 @@ public ResponseEntity<List<ConsultGetUnpaidResponse>> getUnpaidConsults() {
@Parameter(name = "consultId", description = "상담 아이디")
})
@PatchMapping("/unpaid-consults/{consultId}")
public ResponseEntity<Void> updateConsultIsPaid(@PathVariable Long consultId) {
adminService.updateConsultIsPaid(consultId);
return ResponseEntity.ok().build();
public ResponseEntity<SmsGetResponse> updateConsultIsPaid(@PathVariable Long consultId) {
return ResponseEntity.ok(adminService.updateConsultIsPaid(consultId));
}

@Operation(summary = "심사 대기 중인 상담사 프로필 조회", description = "심사 대기 중인 상담사 프로필 조회")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.example.sharemind.payment.domain.Payment;
import com.example.sharemind.post.application.PostService;
import com.example.sharemind.post.domain.Post;
import com.example.sharemind.sms.application.SmsService;
import jakarta.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
Expand Down Expand Up @@ -40,6 +41,7 @@ public class PayAppServiceImpl implements PayAppService {
private final PostService postService;
private final ChatService chatService;
private final LetterService letterService;
private final SmsService smsService;

private final RestClient restClient = RestClient.builder()
.baseUrl(PAY_APP_URL)
Expand Down Expand Up @@ -171,7 +173,8 @@ public String confirmConsult(HttpServletRequest request) {
URLDecoder.decode(request.getParameter("pay_date"), StandardCharsets.UTF_8));

if (!payAppUserId.equals(userId) || !payAppKey.equals(key) || !payAppValue.equals(value)) {
throw new PayAppException(PayAppErrorCode.CONFIRM_BASIC_INFO_FAIL, userId + " " + key + " " + value);
throw new PayAppException(PayAppErrorCode.CONFIRM_BASIC_INFO_FAIL,
userId + " " + key + " " + value);
}

Payment payment = paymentService.getPaymentByPayAppId(payAppId);
Expand All @@ -195,6 +198,7 @@ public String confirmConsult(HttpServletRequest request) {
consult.updateIsPaidAndChat(chat, payMethod.getMethod(), approvedAt);
}
}
smsService.sendSmsCounselor(consult.getCounselor().getCounselorId());
}

return "SUCCESS";
Expand All @@ -216,7 +220,8 @@ public String confirmPost(HttpServletRequest request) {
URLDecoder.decode(request.getParameter("pay_date"), StandardCharsets.UTF_8));

if (!payAppUserId.equals(userId) || !payAppKey.equals(key) || !payAppValue.equals(value)) {
throw new PayAppException(PayAppErrorCode.CONFIRM_BASIC_INFO_FAIL, userId + " " + key + " " + value);
throw new PayAppException(PayAppErrorCode.CONFIRM_BASIC_INFO_FAIL,
userId + " " + key + " " + value);
}

Post post = postService.getPostByPayAppId(payAppId);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.sharemind.sms.application;

import com.example.sharemind.sms.dto.response.SmsGetResponse;

public interface SmsService {

SmsGetResponse sendSmsCounselor(Long counselorId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.example.sharemind.sms.application;

import com.example.sharemind.counselor.application.CounselorService;
import com.example.sharemind.counselor.domain.Counselor;
import com.example.sharemind.sms.dto.response.SmsGetResponse;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClient;

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class SmsServiceImpl implements SmsService {

private static final String BASE_URL = "https://apis.aligo.in";
private static final String COUNSELOR_MESSAGE = "[셰어마인드] 익명의 셰어님으로부터 {편지||채팅} 상담 요청이 접수되었습니다. 내 정보>마인더로 전환>상담 탭에서 확인 부탁드립니다.";

private final CounselorService counselorService;

@Value("${spring.sms.key}")
private String key;

@Value("${spring.sms.id}")
private String id;

@Value("${spring.sms.sender}")
private String sender;

private final RestClient restClient = RestClient.builder()
.baseUrl(BASE_URL)
.build();
private final ObjectMapper objectMapper;

@Override
public SmsGetResponse sendSmsCounselor(Long counselorId) {
Counselor counselor = counselorService.getCounselorByCounselorId(counselorId);
return sendSms(counselor.getPhoneNumber(), COUNSELOR_MESSAGE);
}

private SmsGetResponse sendSms(String phoneNumber, String message) {

MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("key", key);
body.add("user_id", id);
body.add("sender", sender);
body.add("receiver", phoneNumber);
body.add("msg", message);
// body.add("testmode_yn", "Y");

String response = restClient.post()
.uri("/send/")
.body(body).retrieve()
.body(String.class);
try {
JsonNode rootNode = objectMapper.readTree(response);
int resultCode = rootNode.get("result_code").asInt();
String responseMessage = rootNode.get("message").asText();
return SmsGetResponse.of(resultCode, responseMessage);
} catch (Exception e) {
throw new RuntimeException("JSON 처리 중 오류 발생", e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.example.sharemind.sms.dto.response;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class SmsGetResponse {

private final int result_code;
private final String message;

public static SmsGetResponse of(int resultCode, String message) {
return new SmsGetResponse(resultCode, message);
}
}

0 comments on commit a9b577d

Please sign in to comment.