Skip to content

Commit 3d2263a

Browse files
authored
feat: YouTube 검색 기능 구현 (#51)
* chore: youtube api 의존성 추가 * chore: youtube.yml 생성 * chore: youtube properties 추가 * feat: 유튜브 검색 기능 구현 * refactor: 엔드포인트 수정 * fix: 멤버 유틸리티 추가
1 parent 0b5d4d1 commit 3d2263a

8 files changed

Lines changed: 101 additions & 0 deletions

File tree

build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ dependencies {
5858

5959
// Spotify
6060
implementation 'se.michaelthelin.spotify:spotify-web-api-java:8.4.1'
61+
62+
// Youtube API
63+
implementation 'com.google.api-client:google-api-client:1.33.0'
64+
implementation 'com.google.oauth-client:google-oauth-client-jetty:1.23.0'
65+
implementation 'com.google.apis:google-api-services-youtube:v3-rev20230816-2.0.0'
66+
implementation 'com.google.http-client:google-http-client-jackson2:1.39.2'
6167
}
6268

6369
tasks.named('test') {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.amcamp.domain.youtube.api;
2+
3+
import com.amcamp.domain.youtube.application.YouTubeService;
4+
import com.amcamp.domain.youtube.dto.response.YouTubeVideoIdResponse;
5+
import lombok.RequiredArgsConstructor;
6+
import org.springframework.web.bind.annotation.GetMapping;
7+
import org.springframework.web.bind.annotation.RequestMapping;
8+
import org.springframework.web.bind.annotation.RequestParam;
9+
import org.springframework.web.bind.annotation.RestController;
10+
11+
import java.io.IOException;
12+
13+
@RestController
14+
@RequiredArgsConstructor
15+
@RequestMapping("/music")
16+
public class YouTubeController {
17+
18+
private final YouTubeService youTubeService;
19+
20+
@GetMapping("/youtube")
21+
public YouTubeVideoIdResponse getYouTubeLink(@RequestParam String query) throws IOException {
22+
return youTubeService.getYouTubeLink(query);
23+
}
24+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.amcamp.domain.youtube.application;
2+
3+
import com.amcamp.domain.youtube.dto.response.YouTubeVideoIdResponse;
4+
import com.amcamp.global.util.MemberUtil;
5+
import com.amcamp.infra.config.youtube.YoutubeProperties;
6+
import com.google.api.client.http.javanet.NetHttpTransport;
7+
import com.google.api.client.json.jackson2.JacksonFactory;
8+
import com.google.api.services.youtube.YouTube;
9+
import com.google.api.services.youtube.YouTubeRequestInitializer;
10+
import com.google.api.services.youtube.model.SearchListResponse;
11+
import com.google.api.services.youtube.model.SearchResult;
12+
import lombok.RequiredArgsConstructor;
13+
import org.springframework.stereotype.Service;
14+
15+
import java.io.IOException;
16+
import java.util.Collections;
17+
import java.util.List;
18+
19+
@Service
20+
@RequiredArgsConstructor
21+
public class YouTubeService {
22+
23+
private final MemberUtil memberUtil;
24+
private final YoutubeProperties youtubeProperties;
25+
26+
public YouTubeVideoIdResponse getYouTubeLink(String query) throws IOException {
27+
memberUtil.getCurrentMember();
28+
29+
YouTube youtube = new YouTube.Builder(
30+
new NetHttpTransport(),
31+
new JacksonFactory(),
32+
request -> {
33+
})
34+
.setYouTubeRequestInitializer(new YouTubeRequestInitializer(youtubeProperties.apiKey()))
35+
.build();
36+
37+
YouTube.Search.List search = youtube.search().list(Collections.singletonList("id"));
38+
search.setQ(query);
39+
search.setMaxResults(1L);
40+
41+
SearchListResponse searchResponse = search.execute();
42+
List<SearchResult> results = searchResponse.getItems();
43+
44+
if (!results.isEmpty()) {
45+
String videoId = results.get(0).getId().getVideoId();
46+
return new YouTubeVideoIdResponse(videoId);
47+
}
48+
49+
return null;
50+
}
51+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.amcamp.domain.youtube.dto.response;
2+
3+
public record YouTubeVideoIdResponse(String videoId) {
4+
}

src/main/java/com/amcamp/infra/config/properties/PropertiesConfig.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.amcamp.infra.config.oauth.KakaoProperties;
66
import com.amcamp.infra.config.redis.RedisProperties;
77
import com.amcamp.infra.config.spotify.SpotifyProperties;
8+
import com.amcamp.infra.config.youtube.YoutubeProperties;
89
import org.springframework.boot.context.properties.EnableConfigurationProperties;
910
import org.springframework.context.annotation.Configuration;
1011

@@ -14,6 +15,7 @@
1415
JwtProperties.class,
1516
ChatProperties.class,
1617
SpotifyProperties.class,
18+
YoutubeProperties.class
1719
})
1820
@Configuration
1921
public class PropertiesConfig {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.amcamp.infra.config.youtube;
2+
3+
import org.springframework.boot.context.properties.ConfigurationProperties;
4+
5+
@ConfigurationProperties("youtube")
6+
public record YoutubeProperties(String apiKey) {
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
spring:
2+
config:
3+
activate:
4+
on-profile: "youtube"
5+
youtube:
6+
api-key: ${YOUTUBE_API_KEY}

src/main/resources/application.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ spring:
88
- redis
99
- gemini
1010
- spotify
11+
- youtube

0 commit comments

Comments
 (0)