Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

YEL-220 [feat] 광고 보고 보상얻기 가능 여부 조회 #454

Merged
merged 5 commits into from
Feb 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 8 additions & 32 deletions src/docs/asciidoc/check-is-possible-admob.adoc
Original file line number Diff line number Diff line change
@@ -1,52 +1,28 @@
:reproducible:
== 상점에서 보상형 광고 가능한지 여부 (명세)
== 상점에서 보상형 광고 가능한지 여부

=== 요청

[http,json]
----
GET /api/v1/admob/{tag} HTTP/1.1
Authorization: Bearer your-access-token
Content-Type: application/json
----
include::{snippets}/api/v1/admob/possible/http-request.adoc[]

=== 요청 파라미터

include::{snippets}/api/v1/admob/possible/path-parameters.adoc[]

----
tag -> shop
tag -> ADMOB_POINT
----
* 보상형 광고 다른곳에서 사용할 수도 있으므로 tag로 어떤 곳에서 사용하고 있는곳인지 tag로 명시
* 현재는 상점 -> shop에서만 보상형 광고 진행
* 현재는 상점에 있는 보상형 광고 (ADMOB_POINT를 tag에 요청)

=== 응답

[http,json]
----
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
{
"status" : 200,
"message" : "광고 보고 포인트 얻기 가능 여부 조회에 성공했습니다.",
"data": {
"createdAt": "2024-01-01 12:00:00",
"isPossible" : true,
}
}
----

include::{snippets}/api/v1/admob/possible/http-response.adoc[]

=== NOTE

- Header에 무작위한 UUID4 값을 넣어주세요
* 예시) IdempotencyKey: 0397b5f3-ecdc-47d6-b5d7-2b1afcf00e87
- 주의사항
* 같은 멱등성키를 2번 요청하면, 400번 에러.
- ADMOB
* ADMOB 서버에 SSV(ServerSideVerification) Options의 customData에 입력한 것과 동일한 멱등성 키를 넘겨주세요.

=== CHANGELOG

- 2024.02.17 API 릴리즈
- 2024.02.16 명세서 작성
2 changes: 1 addition & 1 deletion src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,4 @@

* 🆕 link:reward-admob.html[광고보고 보상 얻기, 2024-02-11]

* 🆕 link:check-is-possible-admob.adoc[광고보고 보상 얻기 가능 여부 조회, 2024-02-16 (명세)]
* 🆕 link:check-is-possible-admob.adoc[광고보고 보상 얻기 가능 여부 조회, 2024-02-17]
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
package com.yello.server.domain.event.controller;

import static com.yello.server.global.common.ErrorCode.ADMOB_URI_BAD_REQUEST_EXCEPTION;
import static com.yello.server.global.common.ErrorCode.EMPTY_QUERY_STRING_EXCEPTION;
import static com.yello.server.global.common.SuccessCode.EVENT_JOIN_SUCCESS;
import static com.yello.server.global.common.SuccessCode.EVENT_NOTICE_SUCCESS;
import static com.yello.server.global.common.SuccessCode.EVENT_REWARD_SUCCESS;
import static com.yello.server.global.common.SuccessCode.GET_IS_POSSIBLE_ADMOB_SUCCESS;
import static com.yello.server.global.common.SuccessCode.REWARD_ADMOB_SUCCESS;
import static com.yello.server.global.common.SuccessCode.VERIFY_ADMOB_SSV_SUCCESS;
import static com.yello.server.global.common.util.ConstantUtil.IdempotencyKeyHeader;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ser.Serializers.Base;
import com.yello.server.domain.event.dto.request.AdmobRewardRequest;
import com.yello.server.domain.event.dto.request.EventJoinRequest;
import com.yello.server.domain.event.dto.response.EventResponse;
import com.yello.server.domain.event.dto.response.EventRewardResponse;
import com.yello.server.domain.event.dto.response.GetIsPossibleAdmob;
import com.yello.server.domain.event.exception.EventBadRequestException;
import com.yello.server.domain.event.exception.EventNotFoundException;
import com.yello.server.domain.event.service.EventService;
import com.yello.server.domain.user.entity.User;
import com.yello.server.global.common.annotation.AccessTokenUser;
Expand All @@ -30,6 +32,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
Expand Down Expand Up @@ -71,6 +74,10 @@ public BaseResponse<EventRewardResponse> rewardEvent(@AccessTokenUser User user,
public ResponseEntity<?> verifyAdmob(HttpServletRequest request) {
URI uri;
System.out.println(request.getQueryString() + " alalalalalal");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오타인거 같은데 지워주세용

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 verify할 때 signature, keyId 확인하려고 테스트겸 넣은거예욤 서버에서 로그로 확인하려구요

if (request.getQueryString()==null) {
throw new EventNotFoundException(EMPTY_QUERY_STRING_EXCEPTION);
}

try {
uri =
new URI(request.getScheme(), null, request.getServerName(), request.getServerPort(),
Expand All @@ -85,8 +92,16 @@ public ResponseEntity<?> verifyAdmob(HttpServletRequest request) {
}

@PostMapping("/v1/admob/reward")
public BaseResponse<EventRewardResponse> rewardAdmob(@AccessTokenUser User user, @RequestBody AdmobRewardRequest request) {
public BaseResponse<EventRewardResponse> rewardAdmob(@AccessTokenUser User user,
@RequestBody AdmobRewardRequest request) {
val data = eventService.rewardAdmob(user.getId(), request);
return BaseResponse.success(REWARD_ADMOB_SUCCESS, data);
}

@GetMapping("/v1/admob/possible/{tag}")
public BaseResponse<GetIsPossibleAdmob> getIsPossibleAdmob(@AccessTokenUser User user,
@PathVariable("tag") String tag) {
val data = eventService.getIsPossibleAdmob(user.getId(), tag);
return BaseResponse.success(GET_IS_POSSIBLE_ADMOB_SUCCESS, data);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.yello.server.domain.event.dto.response;

import com.yello.server.domain.user.entity.UserData;
import com.yello.server.global.common.factory.TimeFactory;
import lombok.Builder;

@Builder
public record GetIsPossibleAdmob(
String createdAt,
Boolean isPossible
) {
public static GetIsPossibleAdmob of(UserData userAdmob) {
return GetIsPossibleAdmob.builder()
.createdAt(userAdmob.getValue())
.isPossible(userAdmob.isPossible())
.build();
}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package com.yello.server.domain.event.service;

import static com.yello.server.domain.user.entity.UserDataType.fromCode;
import static com.yello.server.global.common.ErrorCode.DUPLICATE_ADMOB_REWARD_EXCEPTION;
import static com.yello.server.global.common.ErrorCode.EVENT_COUNT_BAD_REQUEST_EXCEPTION;
import static com.yello.server.global.common.ErrorCode.EVENT_DATE_BAD_REQUEST_EXCEPTION;
import static com.yello.server.global.common.ErrorCode.EVENT_TIME_BAD_REQUEST_EXCEPTION;
import static com.yello.server.global.common.ErrorCode.IDEMPOTENCY_KEY_CONFLICT_EXCEPTION;
import static com.yello.server.global.common.ErrorCode.IDEMPOTENCY_KEY_NOT_FOUND_EXCEPTION;
import static com.yello.server.global.common.factory.TimeFactory.minusTime;
import static com.yello.server.global.common.factory.TimeFactory.toDateFormattedString;
import static com.yello.server.global.common.util.ConstantUtil.ADMOB_SHOP_TIME;
import static com.yello.server.global.common.util.ConstantUtil.GlobalZoneId;

import com.fasterxml.jackson.core.JsonProcessingException;
Expand All @@ -17,6 +21,7 @@
import com.yello.server.domain.event.dto.request.EventJoinRequest;
import com.yello.server.domain.event.dto.response.EventResponse;
import com.yello.server.domain.event.dto.response.EventRewardResponse;
import com.yello.server.domain.event.dto.response.GetIsPossibleAdmob;
import com.yello.server.domain.event.entity.Event;
import com.yello.server.domain.event.entity.EventHistory;
import com.yello.server.domain.event.entity.EventInstance;
Expand All @@ -33,13 +38,16 @@
import com.yello.server.domain.event.exception.EventNotFoundException;
import com.yello.server.domain.event.repository.EventRepository;
import com.yello.server.domain.user.entity.User;
import com.yello.server.domain.user.entity.UserData;
import com.yello.server.domain.user.repository.UserDataRepository;
import com.yello.server.domain.user.repository.UserRepository;
import com.yello.server.global.common.factory.UuidFactory;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.net.URI;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.OffsetTime;
import java.time.ZonedDateTime;
import java.util.ArrayList;
Expand All @@ -61,6 +69,7 @@ public class EventService {
private final EventRepository eventRepository;
private final ObjectMapper objectMapper;
private final UserRepository userRepository;
private final UserDataRepository userDataRepository;

public List<EventResponse> getEvents(Long userId) throws JsonProcessingException {
// exception
Expand Down Expand Up @@ -290,9 +299,25 @@ public EventRewardResponse rewardAdmob(Long userId, AdmobRewardRequest request)
EventInstanceReward rewardInstance =
eventRepository.save(EventInstanceReward.of(eventInstance, eventReward));

// user-data cooldown 추가
UserData userAdmob =
userDataRepository.findByUserIdAndTag(userId, fromCode(request.rewardType()))
.orElseGet(() -> userDataRepository.save(UserData.of(fromCode(request.rewardType()),
toDateFormattedString(LocalDateTime.now()), user)));

userAdmob.setValue(toDateFormattedString(LocalDateTime.now()));

return EventRewardResponse.of(rewardInstance);
}

public GetIsPossibleAdmob getIsPossibleAdmob(Long userId, String tag) {
final User user = userRepository.getById(userId);
UserData userAdmob = userDataRepository.findByUserIdAndTag(userId, fromCode(tag))
.orElse(UserData.of(fromCode(tag),
toDateFormattedString(minusTime(LocalDateTime.now(), ADMOB_SHOP_TIME)), user));
return GetIsPossibleAdmob.of(userAdmob);
}

private EventReward handleRewardByType(AdmobRewardRequest request, User user) {
switch (RewardType.fromCode(request.rewardType())) {
case ADMOB_POINT -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,12 @@ public SearchFriendResponse searchFriend(Long userId, Pageable pageable,
userRepository.findAllByGroupContainingName(groupName, keyword, uuidList));
friendList.addAll(
userRepository.findAllByOtherGroupContainingName(groupName, keyword, uuidList));

friendList.addAll(userRepository.findAllByGroupNameContainingAndFriendListNotContaining(keyword, uuidList, friendList));
} else {
friendList.addAll(
userRepository.findAllByGroupContainingYelloId(groupName, keyword, uuidList));
friendList.addAll(
userRepository.findAllByOtherGroupContainingYelloId(groupName, keyword, uuidList));
friendList.addAll(userRepository.findAllByGroupNameContainingAndFriendListNotContaining(keyword, uuidList, friendList));
}

List<SearchFriendVO> pageList = PaginationFactory.getPage(friendList, pageable)
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/yello/server/domain/user/entity/UserData.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.yello.server.domain.user.entity;

import static com.yello.server.global.common.factory.TimeFactory.getSecondsBetween;
import static com.yello.server.global.common.util.ConstantUtil.ADMOB_TIMER_TIME;

import com.yello.server.global.common.factory.TimeFactory;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
import jakarta.persistence.Entity;
Expand All @@ -10,6 +14,8 @@
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
Expand Down Expand Up @@ -53,4 +59,9 @@ public static UserData of(UserDataType tag, String value, User user) {
public void setValue(String value) {
this.value = value;
}

public Boolean isPossible(){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return TimeFactory.getSecondsBetween(LocalDateTime.now(), LocalDateTime.parse(this.value, formatter)) >= ADMOB_TIMER_TIME;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static com.yello.server.global.common.ErrorCode.ENUM_BAD_REQUEST_EXCEPTION;

import com.yello.server.global.exception.EnumIllegalArgumentException;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.Arrays;
import lombok.Getter;
Expand All @@ -16,7 +17,8 @@ public enum UserDataType {
*/
WITHDRAW_REASON(String.class, "withdraw-reason"),
ACCOUNT_UPDATED_AT(ZonedDateTime.class, "account-updated-at"),
RECOMMENDED(ZonedDateTime.class, "recommended");
RECOMMENDED(ZonedDateTime.class, "recommended"),
ADMOB_POINT(LocalDateTime.class, "ADMOB_POINT");

private final Class<?> classType;
private final String initial;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public enum ErrorCode {
IDEMPOTENCY_KEY_NOT_FOUND_EXCEPTION(NOT_FOUND, "멱등키의 이벤트가 존재하지 않습니다. 이벤트 참여를 먼저 해주세요"),
EVENT_RANDOM_NOT_FOUND_EXCEPTION(NOT_FOUND, "해당 EventRandom가 존재하지 않습니다."),
NOT_FOUND_EVENT_REWARD_EXCEPTION(NOT_FOUND, "해당 EventReward가 존재하지 않습니다."),
EMPTY_QUERY_STRING_EXCEPTION(NOT_FOUND, "query string 값이 null 입니다."),

/**
* 409 CONFLICT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public enum SuccessCode {
EVENT_JOIN_SUCCESS(OK, "이벤트 참여에 성공하였습니다."),
EVENT_REWARD_SUCCESS(OK, "이벤트 보상에 성공하였습니다."),
VERIFY_ADMOB_SSV_SUCCESS(OK, "Admob ssv 검증에 성공하였습니다."),
GET_IS_POSSIBLE_ADMOB_SUCCESS(OK, "광고 보고 포인트 얻기 가능 여부 조회에 성공했습니다."),

/**
* 201 CREATED
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ public class ConstantUtil {
public static final int NO_FRIEND_COUNT = 0;
public static final int SUBSCRIBE_DAYS = 7;
public static final int PLUS_BASIC_TIME = 0;
public static final String USER_VOTE_TYPE = "send";
public static final String ALL_VOTE_TYPE = "all";
public static final int ADMOB_SHOP_TIME = 60;
public static final long ADMOB_TIMER_TIME = 3600L;

private ConstantUtil() {
throw new IllegalStateException();
Expand Down
Loading
Loading