Skip to content

Commit

Permalink
Add Guild#createSoundboardSound
Browse files Browse the repository at this point in the history
  • Loading branch information
freya022 committed Oct 15, 2024
1 parent 4cbeab4 commit 000b874
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/main/java/net/dv8tion/jda/api/entities/Guild.java
Original file line number Diff line number Diff line change
Expand Up @@ -5028,6 +5028,10 @@ default AuditableRestAction<GuildSticker> createSticker(@Nonnull String name, @N
@CheckReturnValue
AuditableRestAction<Void> deleteSticker(@Nonnull StickerSnowflake id);

@Nonnull
@CheckReturnValue
SoundboardSoundCreateAction createSoundboardSound(@Nonnull String name, @Nonnull FileUpload file);

/**
* Creates a new {@link ScheduledEvent}.
* Events created with this method will be of {@link ScheduledEvent.Type#EXTERNAL Type.EXTERNAL}.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.dv8tion.jda.api.requests.restaction;

import net.dv8tion.jda.api.entities.SoundboardSound;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.requests.RestAction;

import javax.annotation.CheckReturnValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.concurrent.TimeUnit;
import java.util.function.BooleanSupplier;

/**
* Specialized {@link RestAction} used to create a {@link SoundboardSound} in a guild.
*/
public interface SoundboardSoundCreateAction extends AuditableRestAction<SoundboardSound>
{
@Nonnull
@Override
@CheckReturnValue
SoundboardSoundCreateAction timeout(long timeout, @Nonnull TimeUnit unit);

@Nonnull
@Override
@CheckReturnValue
SoundboardSoundCreateAction deadline(long timestamp);

@Nonnull
@Override
@CheckReturnValue
SoundboardSoundCreateAction setCheck(@Nullable BooleanSupplier checks);

@Nonnull
@Override
@CheckReturnValue
SoundboardSoundCreateAction addCheck(@Nonnull BooleanSupplier checks);

@Nonnull
@CheckReturnValue
SoundboardSoundCreateAction setVolume(double volume);

@Nonnull
@CheckReturnValue
SoundboardSoundCreateAction setEmoji(@Nonnull Emoji emoji);
}
11 changes: 11 additions & 0 deletions src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -1967,6 +1967,17 @@ public AuditableRestAction<Void> deleteSticker(@Nonnull StickerSnowflake id)
return new AuditableRestActionImpl<>(api, route);
}

@Nonnull
@Override
public SoundboardSoundCreateAction createSoundboardSound(@Nonnull String name, @Nonnull FileUpload file)
{
checkPermission(Permission.CREATE_GUILD_EXPRESSIONS);
Checks.notNull(name, "Name");
Checks.notNull(file, "File");
Route.CompiledRoute route = Route.SoundboardSounds.CREATE_GUILD_SOUNDBOARD_SOUNDS.compile(getId());
return new SoundboardSoundCreateActionImpl(getJDA(), route, name, file);
}

@Nonnull
@Override
public ChannelOrderAction modifyCategoryPositions()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/*
* Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.dv8tion.jda.internal.requests.restaction;

import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.SoundboardSound;
import net.dv8tion.jda.api.entities.emoji.CustomEmoji;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.entities.emoji.UnicodeEmoji;
import net.dv8tion.jda.api.requests.Request;
import net.dv8tion.jda.api.requests.Response;
import net.dv8tion.jda.api.requests.Route;
import net.dv8tion.jda.api.requests.restaction.SoundboardSoundCreateAction;
import net.dv8tion.jda.api.utils.FileUpload;
import net.dv8tion.jda.api.utils.data.DataObject;
import net.dv8tion.jda.internal.utils.Checks;
import net.dv8tion.jda.internal.utils.IOUtil;
import okhttp3.RequestBody;

import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import java.util.function.BooleanSupplier;

public class SoundboardSoundCreateActionImpl extends AuditableRestActionImpl<SoundboardSound> implements SoundboardSoundCreateAction
{
private final String name;
private final FileUpload file;
private double volume = 1;
private Emoji emoji;

public SoundboardSoundCreateActionImpl(JDA api, Route.CompiledRoute route, String name, FileUpload file)
{
super(api, route);
this.name = name;
this.file = file;
}

@Nonnull
@Override
public SoundboardSoundCreateAction timeout(long timeout, @Nonnull TimeUnit unit)
{
return (SoundboardSoundCreateAction) super.timeout(timeout, unit);
}

@Nonnull
@Override
public SoundboardSoundCreateAction addCheck(@Nonnull BooleanSupplier checks)
{
return (SoundboardSoundCreateAction) super.addCheck(checks);
}

@Nonnull
@Override
public SoundboardSoundCreateAction setCheck(BooleanSupplier checks)
{
return (SoundboardSoundCreateAction) super.setCheck(checks);
}

@Nonnull
@Override
public SoundboardSoundCreateAction deadline(long timestamp)
{
return (SoundboardSoundCreateAction) super.deadline(timestamp);
}

@Nonnull
@Override
public SoundboardSoundCreateAction setVolume(double volume)
{
Checks.check(volume >= 0 && volume <= 1, "Volume must be between 0 and 1");
this.volume = volume;
return this;
}

@Nonnull
@Override
public SoundboardSoundCreateAction setEmoji(@Nonnull Emoji emoji)
{
Checks.notNull(emoji, "Emoji");
this.emoji = emoji;
return this;
}

@Override
protected RequestBody finalizeData()
{
try
{
final DataObject json = DataObject.empty()
.put("name", name)
.put("sound", "data:" + getMime() + ";base64," + getBase64Sound())
.put("volume", volume);

if (emoji instanceof UnicodeEmoji) {
json.put("emoji_name", emoji.getName());
} else if (emoji instanceof CustomEmoji) {
json.put("emoji_id", ((CustomEmoji) emoji).getId());
}

return getRequestBody(json);
}
catch (IOException e)
{
throw new UncheckedIOException("Unable to get request body when creating a guild soundboard sound", e);
}
}

@Nonnull
private String getBase64Sound() throws IOException
{
final byte[] data = IOUtil.readFully(file.getData());
final byte[] b64 = Base64.getEncoder().encode(data);
return new String(b64, StandardCharsets.UTF_8);
}

@Nonnull
private String getMime()
{
int index = file.getName().lastIndexOf('.');
Checks.check(index > -1, "Filename for soundboard sound is missing file extension. Provided: '" + file.getName() + "'. Must be MP3 or OGG.");

String extension = file.getName().substring(index + 1).toLowerCase(Locale.ROOT);
String mime;
switch (extension)
{
case "mp3":
mime = "audio/mpeg";
break;
case "ogg":
mime = "audio/ogg";
break;
default:
throw new IllegalArgumentException("Unsupported file extension: '." + extension + "', must be MP3 or OGG.");
}
return mime;
}

@Override
protected void handleSuccess(Response response, Request<SoundboardSound> request)
{
request.onSuccess(api.getEntityBuilder().createSoundboardSound(response.getObject()));
}
}

0 comments on commit 000b874

Please sign in to comment.