diff --git a/common/src/main/java/com/github/twitch4j/common/config/Twitch4JGlobal.java b/common/src/main/java/com/github/twitch4j/common/config/Twitch4JGlobal.java index fcc6f012d..74ebdf8a7 100644 --- a/common/src/main/java/com/github/twitch4j/common/config/Twitch4JGlobal.java +++ b/common/src/main/java/com/github/twitch4j/common/config/Twitch4JGlobal.java @@ -15,6 +15,6 @@ public class Twitch4JGlobal { /** * Default UserAgent */ - public static String userAgent = "Twitch4J/1.0.0"; + public static String userAgent = "Twitch4J/1.2.0"; } diff --git a/common/src/main/java/com/github/twitch4j/common/feign/interceptor/JsonContentTypeHeaderInterceptor.java b/common/src/main/java/com/github/twitch4j/common/feign/interceptor/JsonContentTypeHeaderInterceptor.java new file mode 100644 index 000000000..b202f9674 --- /dev/null +++ b/common/src/main/java/com/github/twitch4j/common/feign/interceptor/JsonContentTypeHeaderInterceptor.java @@ -0,0 +1,33 @@ +package com.github.twitch4j.common.feign.interceptor; + +import feign.Request; +import feign.RequestInterceptor; +import feign.RequestTemplate; + +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Injects the content-type application/json into all PUT,PATCH,POST requests that didn't specify a content-type + */ +public class JsonContentTypeHeaderInterceptor implements RequestInterceptor { + + /** + * Holds all http methods that transmit a body (to set the content-type) + */ + private static final Set methodsWithBody = Stream.of(Request.HttpMethod.POST.name(), Request.HttpMethod.PATCH.name(), Request.HttpMethod.PUT.name()).collect(Collectors.toSet()); + + /** + * Interceptor + * + * @param t Feign RequestTemplate + */ + @Override + public void apply(RequestTemplate t) { + // set content-type if not specified in the TwitchKraken interface for POST, PATCH, PUT requests + if (!t.headers().containsKey("Content-Type") && !t.headers().containsKey("content-type") && methodsWithBody.contains(t.method())) { + t.header("Content-Type", "application/json"); + } + } +} diff --git a/rest-kraken/src/main/java/com/github/twitch4j/kraken/TwitchKraken.java b/rest-kraken/src/main/java/com/github/twitch4j/kraken/TwitchKraken.java index 1d21382ee..d2b42bd4d 100644 --- a/rest-kraken/src/main/java/com/github/twitch4j/kraken/TwitchKraken.java +++ b/rest-kraken/src/main/java/com/github/twitch4j/kraken/TwitchKraken.java @@ -45,7 +45,6 @@ public interface TwitchKraken { @RequestLine("GET /channels/{channelId}/editors") @Headers({ "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json" }) HystrixCommand getChannelEditors( @Param("token") String authToken, @@ -65,9 +64,6 @@ HystrixCommand getChannelEditors( * @return {@link KrakenFollowList} */ @RequestLine("GET /channels/{channelId}/follows?limit={limit}&offset={offset}&cursor={cursor}&direction={direction}") - @Headers({ - "Accept: application/vnd.twitchtv.v5+json" - }) HystrixCommand getChannelFollowers( @Param("channelId") String channelId, @Param("limit") Integer limit, @@ -87,8 +83,7 @@ HystrixCommand getChannelFollowers( */ @RequestLine("DELETE /channels/{channelId}/stream_key") @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json" + "Authorization: OAuth {token}" }) HystrixCommand resetChannelStreamKey( @Param("token") String authToken, @@ -109,8 +104,7 @@ HystrixCommand resetChannelStreamKey( */ @RequestLine("GET /channels/{channelId}/subscriptions?limit={limit}&offset={offset}&direction={direction}") @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json" + "Authorization: OAuth {token}" }) HystrixCommand getChannelSubscribers( @Param("token") String authToken, @@ -132,9 +126,7 @@ HystrixCommand getChannelSubscribers( @Unofficial @RequestLine("POST /chat/twitchbot/approve") @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json", - "Content-Type: application/json" + "Authorization: OAuth {token}" }) @Body("%7B\"msg_id\":\"{msg_id}\"%7D") HystrixCommand approveAutomodMessage( @@ -154,9 +146,7 @@ HystrixCommand approveAutomodMessage( @Unofficial @RequestLine("POST /chat/twitchbot/deny") @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json", - "Content-Type: application/json" + "Authorization: OAuth {token}" }) @Body("%7B\"msg_id\":\"{msg_id}\"%7D") HystrixCommand denyAutomodMessage( @@ -173,9 +163,6 @@ HystrixCommand denyAutomodMessage( * @return {@link KrakenClip} */ @RequestLine("GET /clips/{slug}") - @Headers({ - "Accept: application/vnd.twitchtv.v5+json" - }) HystrixCommand getClip( @Param("slug") String slug ); @@ -189,9 +176,6 @@ HystrixCommand getClip( * @return {@link KrakenCollectionMetadata} */ @RequestLine("GET /collections/{collection_id}") - @Headers({ - "Accept: application/vnd.twitchtv.v5+json" - }) HystrixCommand getCollectionMetadata( @Param("collection_id") String collectionId ); @@ -205,9 +189,6 @@ HystrixCommand getCollectionMetadata( * @return {@link KrakenCollection} */ @RequestLine("GET /collections/{collection_id}/items") - @Headers({ - "Accept: application/vnd.twitchtv.v5+json" - }) HystrixCommand getCollection( @Param("collection_id") String collectionId ); @@ -224,9 +205,6 @@ HystrixCommand getCollection( * @return {@link KrakenCollectionList} */ @RequestLine("GET /channels/{channel_id}/collections?limit={limit}&cursor={cursor}&containing_item={containing_item}") - @Headers({ - "Accept: application/vnd.twitchtv.v5+json" - }) HystrixCommand getCollectionsByChannel( @Param("channel_id") String channelId, @Param("limit") Integer limit, @@ -246,9 +224,7 @@ HystrixCommand getCollectionsByChannel( */ @RequestLine("POST /channels/{channel_id}/collections") @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json", - "Content-Type: application/json" + "Authorization: OAuth {token}" }) @Body("%7B\"title\":\"{title}\"%7D") HystrixCommand createCollection( @@ -269,9 +245,7 @@ HystrixCommand createCollection( */ @RequestLine("PUT /collections/{collection_id}") @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json", - "Content-Type: application/json" + "Authorization: OAuth {token}" }) @Body("%7B\"title\":\"{title}\"%7D") HystrixCommand updateCollection( @@ -293,8 +267,6 @@ HystrixCommand updateCollection( @RequestLine("PUT /collections/{collection_id}/thumbnail") @Headers({ "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json", - "Content-Type: application/json" }) @Body("%7B\"item_id\":\"{item_id}\"%7D") HystrixCommand createCollectionThumbnail( @@ -314,8 +286,7 @@ HystrixCommand createCollectionThumbnail( */ @RequestLine("DELETE /collections/{collection_id}") @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json" + "Authorization: OAuth {token}" }) HystrixCommand deleteCollection( @Param("token") String token, @@ -335,8 +306,6 @@ HystrixCommand deleteCollection( @RequestLine("POST /collections/{collection_id}/items") @Headers({ "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json", - "Content-Type: application/json" }) @Body("%7B\"id\":\"{id}\",\"type\":\"video\"%7D") HystrixCommand addItemToCollection( @@ -357,8 +326,7 @@ HystrixCommand addItemToCollection( */ @RequestLine("DELETE /collections/{collection_id}/items/{collection_item_id}") @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json" + "Authorization: OAuth {token}" }) HystrixCommand deleteItemFromCollection( @Param("token") String token, @@ -379,9 +347,7 @@ HystrixCommand deleteItemFromCollection( */ @RequestLine("PUT /collections/{collection_id}/items/{collection_item_id}") @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json", - "Content-Type: application/json" + "Authorization: OAuth {token}" }) @Body("%7B\"position\":\"{position}\"%7D") HystrixCommand moveItemWithinCollection( @@ -404,8 +370,7 @@ HystrixCommand moveItemWithinCollection( */ @RequestLine("GET /users/{user}/blocks?limit={limit}&offset={offset}") @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json" + "Authorization: OAuth {token}" }) HystrixCommand getUserBlockList( @Param("token") String authToken, @@ -426,8 +391,7 @@ HystrixCommand getUserBlockList( */ @RequestLine("PUT /users/{from_id}/blocks/{to_id}") @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json" + "Authorization: OAuth {token}" }) HystrixCommand blockUser( @Param("token") String authToken, @@ -447,8 +411,7 @@ HystrixCommand blockUser( */ @RequestLine("DELETE /users/{from_id}/blocks/{to_id}") @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json" + "Authorization: OAuth {token}" }) HystrixCommand unblockUser( @Param("token") String authToken, @@ -468,8 +431,7 @@ HystrixCommand unblockUser( */ @RequestLine("GET /users/{user}/emotes") @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json" + "Authorization: OAuth {token}" }) HystrixCommand getUserEmotes( @Param("token") String authToken, @@ -490,8 +452,7 @@ HystrixCommand getUserEmotes( @Deprecated @RequestLine("PUT /users/{user}/follows/channels/{targetUser}") @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json" + "Authorization: OAuth {token}" }) HystrixCommand addFollow( @Param("token") String authToken, @@ -507,7 +468,6 @@ HystrixCommand addFollow( * @return KrakenIngestList */ @RequestLine("GET /ingests") - @Headers("Accept: application/vnd.twitchtv.v5+json") HystrixCommand getIngestServers(); /** @@ -517,7 +477,6 @@ HystrixCommand addFollow( * @return KrakenTeamList */ @RequestLine("GET /channels/{channel_id}/teams") - @Headers("Accept: application/vnd.twitchtv.v5+json") HystrixCommand getChannelTeams( @Param("channel_id") String channelId ); @@ -532,7 +491,6 @@ HystrixCommand getChannelTeams( * @return KrakenTeamList */ @RequestLine("GET /teams?limit={limit}&offset={offset}") - @Headers("Accept: application/vnd.twitchtv.v5+json") HystrixCommand getAllTeams( @Param("limit") Integer limit, @Param("offset") Integer offset @@ -547,7 +505,6 @@ HystrixCommand getAllTeams( * @return KrakenTeam */ @RequestLine("GET /teams/{name}") - @Headers("Accept: application/vnd.twitchtv.v5+json") HystrixCommand getTeamByName( @Param("name") String name ); @@ -562,8 +519,7 @@ HystrixCommand getTeamByName( */ @RequestLine("GET /user") @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json", + "Authorization: OAuth {token}" }) HystrixCommand getUser( @Param("token") String authToken @@ -576,7 +532,6 @@ HystrixCommand getUser( * @return KrakenUser */ @RequestLine("GET /users/{user_id}") - @Headers("Accept: application/vnd.twitchtv.v5+json") HystrixCommand getUserById( @Param("user_id") String userId ); @@ -590,9 +545,6 @@ HystrixCommand getUserById( * @return KrakenUser */ @RequestLine(value = "GET /users?login={logins}", collectionFormat = CollectionFormat.CSV) - @Headers({ - "Accept: application/vnd.twitchtv.v5+json" - }) HystrixCommand getUsersByLogin( @Param("logins") List logins ); @@ -610,8 +562,7 @@ HystrixCommand getUsersByLogin( */ @Deprecated @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json", + "Authorization: OAuth {token}" }) @RequestLine("PUT /channels/{channelId}?channel[status]={title}") HystrixCommand updateTitle( @@ -651,8 +602,7 @@ HystrixCommand updateTitle( collectionFormat = CollectionFormat.CSV ) @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json" + "Authorization: OAuth {token}" }) HystrixCommand createVideo( @Param("token") String authToken, @@ -668,7 +618,6 @@ HystrixCommand createVideo( @RequestLine("PUT /upload/{video_id}?part={part}&upload_token={upload_token}") @Headers({ - "Accept: application/vnd.twitchtv.v5+json", "Content-Type: application/x-www-form-urlencoded" }) HystrixCommand uploadVideoPart( @@ -695,7 +644,6 @@ default HystrixCommand uploadVideoPart(String videoId, String uploadToken, } @RequestLine("POST /upload/{video_id}/complete?upload_token={upload_token}") - @Headers("Accept: application/vnd.twitchtv.v5+json") HystrixCommand completeVideoUpload( URI baseUrl, @Param("video_id") String videoId, @@ -734,8 +682,7 @@ default HystrixCommand completeVideoUpload(String videoId, String uploadTo collectionFormat = CollectionFormat.CSV ) @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json" + "Authorization: OAuth {token}" }) HystrixCommand updateVideo( @Param("token") String authToken, @@ -758,8 +705,7 @@ HystrixCommand updateVideo( */ @RequestLine("DELETE /videos/{video_id}") @Headers({ - "Authorization: OAuth {token}", - "Accept: application/vnd.twitchtv.v5+json" + "Authorization: OAuth {token}" }) HystrixCommand deleteVideo( @Param("token") String authToken, diff --git a/rest-kraken/src/main/java/com/github/twitch4j/kraken/TwitchKrakenBuilder.java b/rest-kraken/src/main/java/com/github/twitch4j/kraken/TwitchKrakenBuilder.java index 5df2e7ea0..8a122fc27 100644 --- a/rest-kraken/src/main/java/com/github/twitch4j/kraken/TwitchKrakenBuilder.java +++ b/rest-kraken/src/main/java/com/github/twitch4j/kraken/TwitchKrakenBuilder.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.github.twitch4j.common.config.ProxyConfig; import com.github.twitch4j.common.config.Twitch4JGlobal; +import com.github.twitch4j.common.feign.interceptor.JsonContentTypeHeaderInterceptor; import com.github.twitch4j.common.feign.interceptor.TwitchClientIdInterceptor; import com.github.twitch4j.common.util.TypeConvert; import com.netflix.config.ConfigurationManager; @@ -14,7 +15,11 @@ import feign.jackson.JacksonEncoder; import feign.okhttp.OkHttpClient; import feign.slf4j.Slf4jLogger; -import lombok.*; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.With; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.TimeUnit; @@ -110,7 +115,7 @@ public TwitchKraken build() { proxyConfig.apply(clientBuilder); // Build - TwitchKraken client = HystrixFeign.builder() + return HystrixFeign.builder() .client(new OkHttpClient(clientBuilder.build())) .encoder(new JacksonEncoder(mapper)) .decoder(new JacksonDecoder(mapper)) @@ -118,10 +123,10 @@ public TwitchKraken build() { .logLevel(logLevel) .errorDecoder(new TwitchKrakenErrorDecoder(new JacksonDecoder())) .requestInterceptor(new TwitchClientIdInterceptor(this.clientId, this.userAgent)) + .requestInterceptor(t -> t.header("Accept", "application/vnd.twitchtv.v5+json")) + .requestInterceptor(new JsonContentTypeHeaderInterceptor()) .options(new Request.Options(timeout / 3, TimeUnit.MILLISECONDS, timeout, TimeUnit.MILLISECONDS, true)) .retryer(new Retryer.Default(500, timeout, 2)) .target(TwitchKraken.class, baseUrl); - - return client; } }