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

Dynamically create and delete voice channels based on activity #1114

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
7 changes: 6 additions & 1 deletion application/config.json.template
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,10 @@
"fallbackChannelPattern": "java-news-and-changes",
"pollIntervalInMinutes": 10
},
"memberCountCategoryPattern": "Info"
"memberCountCategoryPattern": "Info",
"dynamicVoiceChannelPatterns": [
"Gaming",
"Support/Studying Room",
"Chit Chat"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public final class Config {
private final RSSFeedsConfig rssFeedsConfig;
private final String selectRolesChannelPattern;
private final String memberCountCategoryPattern;
private final List<String> dynamicVoiceChannelPatterns;

@SuppressWarnings("ConstructorWithTooManyParameters")
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
Expand Down Expand Up @@ -94,7 +95,9 @@ private Config(@JsonProperty(value = "token", required = true) String token,
required = true) FeatureBlacklistConfig featureBlacklistConfig,
@JsonProperty(value = "rssConfig", required = true) RSSFeedsConfig rssFeedsConfig,
@JsonProperty(value = "selectRolesChannelPattern",
required = true) String selectRolesChannelPattern) {
required = true) String selectRolesChannelPattern,
@JsonProperty(value = "dynamicVoiceChannelPatterns",
required = true) List<String> dynamicVoiceChannelPatterns) {
this.token = Objects.requireNonNull(token);
this.githubApiKey = Objects.requireNonNull(githubApiKey);
this.databasePath = Objects.requireNonNull(databasePath);
Expand Down Expand Up @@ -127,6 +130,7 @@ private Config(@JsonProperty(value = "token", required = true) String token,
this.featureBlacklistConfig = Objects.requireNonNull(featureBlacklistConfig);
this.rssFeedsConfig = Objects.requireNonNull(rssFeedsConfig);
this.selectRolesChannelPattern = Objects.requireNonNull(selectRolesChannelPattern);
this.dynamicVoiceChannelPatterns = Objects.requireNonNull(dynamicVoiceChannelPatterns);
}

/**
Expand Down Expand Up @@ -418,4 +422,14 @@ public String getMemberCountCategoryPattern() {
public RSSFeedsConfig getRSSFeedsConfig() {
return rssFeedsConfig;
}

/**
* Gets the list of voice channel patterns that are treated dynamically.
*
* @return the list of dynamic voice channel patterns
*/
public List<String> getDynamicVoiceChannelPatterns() {
return this.dynamicVoiceChannelPatterns;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.togetherjava.tjbot.features.code.CodeMessageAutoDetection;
import org.togetherjava.tjbot.features.code.CodeMessageHandler;
import org.togetherjava.tjbot.features.code.CodeMessageManualDetection;
import org.togetherjava.tjbot.features.dynamicvc.DynamicVoiceListener;
import org.togetherjava.tjbot.features.filesharing.FileSharingMessageListener;
import org.togetherjava.tjbot.features.github.GitHubCommand;
import org.togetherjava.tjbot.features.github.GitHubReference;
Expand Down Expand Up @@ -151,6 +152,9 @@ public static Collection<Feature> createFeatures(JDA jda, Database database, Con
features.add(new SlashCommandEducator());
features.add(new PinnedNotificationRemover(config));

// Voice receivers
features.add(new DynamicVoiceListener(config));

// Event receivers
features.add(new RejoinModerationRoleListener(actionsStore, config));
features.add(new GuildLeaveCloseThreadListener(config));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package org.togetherjava.tjbot.features;

import net.dv8tion.jda.api.events.guild.voice.GuildVoiceDeafenEvent;
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceMuteEvent;
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceStreamEvent;
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceUpdateEvent;
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceVideoEvent;

import java.util.regex.Pattern;

/**
* Receives incoming Discord guild events from voice channels matching a given pattern.
* <p>
* All voice receivers have to implement this interface. For convenience, there is a
* {@link VoiceReceiverAdapter} available that implemented most methods already. A new receiver can
* then be registered by adding it to {@link Features}.
* <p>
* <p>
* After registration, the system will notify a receiver whenever a new event was sent or an
* existing event was updated in any channel matching the {@link #getChannelNamePattern()} the bot
* is added to.
*/
public interface VoiceReceiver extends Feature {
/**
* Retrieves the pattern matching the names of channels of which this receiver is interested in
* receiving events from. Called by the core system once during the startup in order to register
* the receiver accordingly.
* <p>
* Changes on the pattern returned by this method afterwards will not be picked up.
*
* @return the pattern matching the names of relevant channels
*/
Pattern getChannelNamePattern();

/**
* Triggered by the core system whenever a member joined, left or moved voice channels.
*
* @param event the event that triggered this
*/
void onVoiceUpdate(GuildVoiceUpdateEvent event);

/**
* Triggered by the core system whenever a member toggled their camera in a voice channel.
*
* @param event the event that triggered this
*/
void onVideoToggle(GuildVoiceVideoEvent event);

/**
* Triggered by the core system whenever a member started or stopped a stream.
*
* @param event the event that triggered this
*/
void onStreamToggle(GuildVoiceStreamEvent event);

/**
* Triggered by the core system whenever a member toggled their mute status.
*
* @param event the event that triggered this
*/
void onMuteToggle(GuildVoiceMuteEvent event);

/**
* Triggered by the core system whenever a member toggled their deafened status.
*
* @param event the event that triggered this
*/
void onDeafenToggle(GuildVoiceDeafenEvent event);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package org.togetherjava.tjbot.features;

import net.dv8tion.jda.api.events.guild.voice.GuildVoiceDeafenEvent;
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceMuteEvent;
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceStreamEvent;
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceUpdateEvent;
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceVideoEvent;

import java.util.regex.Pattern;

public class VoiceReceiverAdapter implements VoiceReceiver {

private final Pattern channelNamePattern;

protected VoiceReceiverAdapter() {
this(Pattern.compile(".*"));
}

protected VoiceReceiverAdapter(Pattern channelNamePattern) {
this.channelNamePattern = channelNamePattern;
}

@Override
public Pattern getChannelNamePattern() {
return channelNamePattern;
}

@Override
public void onVoiceUpdate(GuildVoiceUpdateEvent event) {
// Adapter does not react by default, subclasses may change this behavior
}

@Override
public void onVideoToggle(GuildVoiceVideoEvent event) {
// Adapter does not react by default, subclasses may change this behavior
}

@Override
public void onStreamToggle(GuildVoiceStreamEvent event) {
// Adapter does not react by default, subclasses may change this behavior
}

@Override
public void onMuteToggle(GuildVoiceMuteEvent event) {
// Adapter does not react by default, subclasses may change this behavior
}

@Override
public void onDeafenToggle(GuildVoiceDeafenEvent event) {
// Adapter does not react by default, subclasses may change this behavior
}
}
Loading
Loading