Gate twitch integration

This commit is contained in:
2026-01-14 00:44:58 +01:00
parent a267f9b5ec
commit c3019a1c48
10 changed files with 267 additions and 38 deletions

View File

@@ -7,6 +7,7 @@ import static org.springframework.http.HttpStatus.NOT_FOUND;
import dev.kruhlmann.imgfloat.model.AdminRequest;
import dev.kruhlmann.imgfloat.model.AssetView;
import dev.kruhlmann.imgfloat.model.CanvasSettingsRequest;
import dev.kruhlmann.imgfloat.model.ChannelScriptSettingsRequest;
import dev.kruhlmann.imgfloat.model.CodeAssetRequest;
import dev.kruhlmann.imgfloat.model.OauthSessionUser;
import dev.kruhlmann.imgfloat.model.PlaybackRequest;
@@ -209,6 +210,25 @@ public class ChannelApiController {
return channelDirectoryService.updateCanvasSettings(broadcaster, request);
}
@GetMapping("/settings")
public ChannelScriptSettingsRequest getScriptSettings(@PathVariable("broadcaster") String broadcaster) {
return channelDirectoryService.getChannelScriptSettings(broadcaster);
}
@PutMapping("/settings")
public ChannelScriptSettingsRequest updateScriptSettings(
@PathVariable("broadcaster") String broadcaster,
@Valid @RequestBody ChannelScriptSettingsRequest request,
OAuth2AuthenticationToken oauthToken
) {
String sessionUsername = OauthSessionUser.from(oauthToken).login();
String logBroadcaster = LogSanitizer.sanitize(broadcaster);
String logSessionUsername = LogSanitizer.sanitize(sessionUsername);
authorizationService.userMatchesSessionUsernameOrThrowHttpError(broadcaster, sessionUsername);
LOG.info("Updating script settings for {} by {}", logBroadcaster, logSessionUsername);
return channelDirectoryService.updateChannelScriptSettings(broadcaster, request);
}
@PostMapping(value = "/assets", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<AssetView> createAsset(
@PathVariable("broadcaster") String broadcaster,

View File

@@ -33,6 +33,12 @@ public class Channel {
private double canvasHeight = 1080;
@Column(name = "allow_channel_emotes_for_assets", nullable = false)
private boolean allowChannelEmotesForAssets = true;
@Column(name = "allow_script_chat_access", nullable = false)
private boolean allowScriptChatAccess = true;
@Column(name = "created_at", nullable = false, updatable = false)
private Instant createdAt;
@@ -79,6 +85,22 @@ public class Channel {
this.canvasHeight = canvasHeight;
}
public boolean isAllowChannelEmotesForAssets() {
return allowChannelEmotesForAssets;
}
public void setAllowChannelEmotesForAssets(boolean allowChannelEmotesForAssets) {
this.allowChannelEmotesForAssets = allowChannelEmotesForAssets;
}
public boolean isAllowScriptChatAccess() {
return allowScriptChatAccess;
}
public void setAllowScriptChatAccess(boolean allowScriptChatAccess) {
this.allowScriptChatAccess = allowScriptChatAccess;
}
@PrePersist
@PreUpdate
public void normalizeFields() {

View File

@@ -0,0 +1,30 @@
package dev.kruhlmann.imgfloat.model;
public class ChannelScriptSettingsRequest {
private boolean allowChannelEmotesForAssets = true;
private boolean allowScriptChatAccess = true;
public ChannelScriptSettingsRequest() {}
public ChannelScriptSettingsRequest(boolean allowChannelEmotesForAssets, boolean allowScriptChatAccess) {
this.allowChannelEmotesForAssets = allowChannelEmotesForAssets;
this.allowScriptChatAccess = allowScriptChatAccess;
}
public boolean isAllowChannelEmotesForAssets() {
return allowChannelEmotesForAssets;
}
public void setAllowChannelEmotesForAssets(boolean allowChannelEmotesForAssets) {
this.allowChannelEmotesForAssets = allowChannelEmotesForAssets;
}
public boolean isAllowScriptChatAccess() {
return allowScriptChatAccess;
}
public void setAllowScriptChatAccess(boolean allowScriptChatAccess) {
this.allowScriptChatAccess = allowScriptChatAccess;
}
}

View File

@@ -12,6 +12,7 @@ import dev.kruhlmann.imgfloat.model.AudioAsset;
import dev.kruhlmann.imgfloat.model.CanvasEvent;
import dev.kruhlmann.imgfloat.model.CanvasSettingsRequest;
import dev.kruhlmann.imgfloat.model.Channel;
import dev.kruhlmann.imgfloat.model.ChannelScriptSettingsRequest;
import dev.kruhlmann.imgfloat.model.CodeAssetRequest;
import dev.kruhlmann.imgfloat.model.MarketplaceScriptHeart;
import dev.kruhlmann.imgfloat.model.PlaybackRequest;
@@ -193,6 +194,28 @@ public class ChannelDirectoryService {
return response;
}
public ChannelScriptSettingsRequest getChannelScriptSettings(String broadcaster) {
Channel channel = getOrCreateChannel(broadcaster);
return new ChannelScriptSettingsRequest(
channel.isAllowChannelEmotesForAssets(),
channel.isAllowScriptChatAccess()
);
}
public ChannelScriptSettingsRequest updateChannelScriptSettings(
String broadcaster,
ChannelScriptSettingsRequest request
) {
Channel channel = getOrCreateChannel(broadcaster);
channel.setAllowChannelEmotesForAssets(request.isAllowChannelEmotesForAssets());
channel.setAllowScriptChatAccess(request.isAllowScriptChatAccess());
channelRepository.save(channel);
return new ChannelScriptSettingsRequest(
channel.isAllowChannelEmotesForAssets(),
channel.isAllowScriptChatAccess()
);
}
public Optional<AssetView> createAsset(String broadcaster, MultipartFile file) throws IOException {
long fileSize = file.getSize();
if (fileSize > uploadLimitBytes) {