forked from TheCurle/Camelot
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a0105c2
commit 6993f33
Showing
51 changed files
with
1,164 additions
and
427 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,3 +5,4 @@ run | |
bot_logs/ | ||
|
||
out/ | ||
lib/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
plugins { | ||
id 'groovy' | ||
id 'java-library' | ||
} | ||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
|
||
dependencies { | ||
api "org.apache.groovy:groovy:${project.groovy_version}" | ||
api "org.apache.groovy:groovy-contracts:${project.groovy_version}" | ||
implementation group: 'org.kohsuke', name: 'github-api', version: project.ghapi_version | ||
} |
92 changes: 92 additions & 0 deletions
92
config/src/main/groovy/net/neoforged/camelot/config/CamelotConfig.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package net.neoforged.camelot.config | ||
|
||
import groovy.transform.CompileStatic | ||
import groovy.transform.stc.ClosureParams | ||
import groovy.transform.stc.FromString | ||
import net.neoforged.camelot.config.module.ModuleConfiguration | ||
|
||
/** | ||
* The class holding Camelot's configuration, that is represented in a Groovy DSL. | ||
*/ | ||
@CompileStatic | ||
class CamelotConfig { | ||
static CamelotConfig instance | ||
|
||
private final Map<Class<? extends ModuleConfiguration>, ModuleConfiguration> modules | ||
|
||
CamelotConfig(Map<Class<? extends ModuleConfiguration>, ModuleConfiguration> modules) { | ||
this.modules = modules | ||
} | ||
|
||
/** | ||
* The bot's Discord API key. | ||
*/ | ||
String token | ||
|
||
/** | ||
* The prefix used by the bot for text commands | ||
*/ | ||
String prefix | ||
|
||
/** | ||
* The owner of the bot - the user with this ID will be able to use owner-only commands | ||
*/ | ||
long owner | ||
|
||
/** | ||
* Configure a module. | ||
* @param type the type of the module | ||
* @param configurator the closure that configures the module | ||
*/ | ||
<T extends ModuleConfiguration> void module(Class<T> type, @DelegatesTo(type = 'T', strategy = Closure.DELEGATE_FIRST) @ClosureParams(value = FromString, options = 'T') Closure configurator) { | ||
ConfigUtils.configure(module(type), configurator) | ||
} | ||
|
||
/** | ||
* Get the module of the given type. | ||
* @param type the type of the module | ||
* @return the module configuration | ||
*/ | ||
<T extends ModuleConfiguration> T module(Class<T> type) { | ||
final conf = modules[type] | ||
if (conf === null) { | ||
throw new IllegalArgumentException("Unknown module of type $type") | ||
} | ||
return (T)conf | ||
} | ||
|
||
void validate() { | ||
if (!token) { | ||
throw new IllegalArgumentException('Bot API Token must be provided!') | ||
} | ||
|
||
modules.values().each { | ||
if (it.enabled) { | ||
it.validate() | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Mark a value as a secret. Secrets will not be logged and any attempt at doing so will | ||
* be redacted. | ||
* @param value the secret value | ||
* @return the secret value | ||
*/ | ||
static String secret(String value) { | ||
return value | ||
} | ||
|
||
/** | ||
* Get the value of the environment variable with the given {@code key}. | ||
* @param key the key of the env var | ||
* @return the value | ||
*/ | ||
static String env(String key) { | ||
final value = System.getenv(key) | ||
if (value === null) { | ||
throw new IllegalArgumentException("Environment variable ${key} not found!") | ||
} | ||
return value | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
config/src/main/groovy/net/neoforged/camelot/config/ConfigUtils.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package net.neoforged.camelot.config | ||
|
||
import groovy.transform.CompileStatic | ||
import groovy.transform.stc.ClosureParams | ||
import groovy.transform.stc.FromString | ||
|
||
@CompileStatic | ||
class ConfigUtils { | ||
static <T> T configure(T object, @DelegatesTo(type = 'T', strategy = Closure.DELEGATE_FIRST) @ClosureParams(value = FromString, options = 'T') Closure closure) { | ||
closure.setResolveStrategy(Closure.DELEGATE_FIRST) | ||
closure.setDelegate(object) | ||
closure.call(object) | ||
return object | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
config/src/main/groovy/net/neoforged/camelot/config/Extensions.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package net.neoforged.camelot.config | ||
|
||
import groovy.transform.CompileStatic | ||
|
||
@CompileStatic | ||
class Extensions { | ||
static void camelot(Script obj, @DelegatesTo(value = CamelotConfig, strategy = Closure.DELEGATE_FIRST) Closure closure) { | ||
ConfigUtils.configure(CamelotConfig.instance, closure) | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
config/src/main/groovy/net/neoforged/camelot/config/MailConfiguration.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package net.neoforged.camelot.config | ||
|
||
import groovy.contracts.Requires | ||
import groovy.transform.CompileStatic | ||
|
||
/** | ||
* Base class for configuring Mail service clients. | ||
*/ | ||
@CompileStatic | ||
class MailConfiguration { | ||
/** | ||
* Mail service configuration | ||
*/ | ||
Map<String, ?> mailProperties | ||
|
||
/** | ||
* The username to use to connect to the mail server | ||
*/ | ||
String username | ||
|
||
/** | ||
* The password to use to connect to the mail server | ||
*/ | ||
String password | ||
|
||
/** | ||
* The email to send as | ||
*/ | ||
String sendAs | ||
|
||
@Requires({ username && password && sendAs }) | ||
void validate() { | ||
|
||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
config/src/main/groovy/net/neoforged/camelot/config/OAuthConfiguration.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package net.neoforged.camelot.config | ||
|
||
import groovy.contracts.Requires | ||
import groovy.transform.CompileStatic | ||
|
||
/** | ||
* Base class for configuring OAuth clients. | ||
*/ | ||
@CompileStatic | ||
class OAuthConfiguration { | ||
/** | ||
* The ID of the OAuth app | ||
*/ | ||
String clientId | ||
|
||
/** | ||
* The secret of the OAuth app | ||
*/ | ||
String clientSecret | ||
|
||
@Requires({ clientId && clientSecret }) | ||
void validate() { | ||
|
||
} | ||
} |
56 changes: 56 additions & 0 deletions
56
config/src/main/groovy/net/neoforged/camelot/config/module/BanAppeals.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package net.neoforged.camelot.config.module | ||
|
||
import groovy.transform.CompileStatic | ||
import groovy.transform.NamedParam | ||
import net.neoforged.camelot.config.ConfigUtils | ||
import net.neoforged.camelot.config.MailConfiguration | ||
import net.neoforged.camelot.config.OAuthConfiguration | ||
|
||
/** | ||
* Module for ban appeals. | ||
* | ||
* <p>Disabled by default. | ||
*/ | ||
@CompileStatic | ||
class BanAppeals extends ModuleConfiguration { | ||
{ | ||
enabled = false | ||
} | ||
|
||
/** | ||
* A guild->channel map of channels to send appeals to. | ||
*/ | ||
Map<Long, Long> appealsChannels = [:] | ||
|
||
/** | ||
* Configure the appeals channel of a guild. | ||
* Example: {@code appealsChannel(guild: 123L, channel: 124L)} | ||
* @param args the arguments. Must have a guild and a channel parameter | ||
*/ | ||
void appealsChannel(@NamedParam(value = 'guild', type = Long, required = true) @NamedParam(value = 'channel', type = Long, required = true) Map args) { | ||
if (!args.guild) { | ||
throw new IllegalArgumentException('Missing mandatory guild parameter') | ||
} else if (!args.channel) { | ||
throw new IllegalArgumentException('Missing mandatory channel parameter') | ||
} | ||
appealsChannels[args.guild as long] = args.channel as long | ||
} | ||
|
||
final OAuthConfiguration discordAuth = new OAuthConfiguration() | ||
|
||
/** | ||
* Configure the Discord OAuth client | ||
*/ | ||
void discordAuth(@DelegatesTo(value = OAuthConfiguration, strategy = Closure.DELEGATE_FIRST) Closure config) { | ||
ConfigUtils.configure(discordAuth, config) | ||
} | ||
|
||
final MailConfiguration mail = new MailConfiguration() | ||
|
||
/** | ||
* Configure the mail service | ||
*/ | ||
void mail(@DelegatesTo(value = MailConfiguration, strategy = Closure.DELEGATE_FIRST) Closure config) { | ||
ConfigUtils.configure(mail, config) | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
config/src/main/groovy/net/neoforged/camelot/config/module/CustomPings.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package net.neoforged.camelot.config.module | ||
|
||
import groovy.transform.CompileStatic | ||
|
||
/** | ||
* The module that allows users to set up custom pings. | ||
* Custom pings will send users a DM when a message matches a regex they've configured. | ||
*/ | ||
@CompileStatic | ||
class CustomPings extends ModuleConfiguration { | ||
/** | ||
* The channel in which to create ping private threads if a member does not have DMs enabled. | ||
*/ | ||
long pingThreadsChannel | ||
} |
18 changes: 18 additions & 0 deletions
18
config/src/main/groovy/net/neoforged/camelot/config/module/FilePreview.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package net.neoforged.camelot.config.module | ||
|
||
import groovy.transform.CompileStatic | ||
import org.kohsuke.github.GitHub | ||
|
||
/** | ||
* Module for file previews. | ||
* <p> | ||
* If enabled, messages containing attachments with specific suffixes will have a reaction added by the bot. | ||
* If the reaction is clicked by another user, a Gist will be created from the attachments of the message. | ||
*/ | ||
@CompileStatic | ||
class FilePreview extends ModuleConfiguration implements GHAuth { | ||
/** | ||
* The GitHub instance used to authenticate to create gists | ||
*/ | ||
GitHub auth | ||
} |
83 changes: 83 additions & 0 deletions
83
config/src/main/groovy/net/neoforged/camelot/config/module/GHAuth.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package net.neoforged.camelot.config.module | ||
|
||
import groovy.contracts.Requires | ||
import groovy.transform.CompileStatic | ||
import net.neoforged.camelot.config.ConfigUtils | ||
import org.kohsuke.github.GHApp | ||
import org.kohsuke.github.GHAppInstallation | ||
import org.kohsuke.github.GitHub | ||
import org.kohsuke.github.GitHubBuilder | ||
|
||
import java.nio.file.Files | ||
import java.nio.file.Path | ||
import java.util.function.Function | ||
|
||
@CompileStatic | ||
interface GHAuth { | ||
/** | ||
* Authenticate to GitHub using an application | ||
*/ | ||
default GitHub appAuthentication(@DelegatesTo(value = AppAuthBuilder, strategy = Closure.DELEGATE_FIRST) Closure configurator) { | ||
return AppAuthBuilder.appProvider.apply(ConfigUtils.configure(new AppAuthBuilder(), configurator)) | ||
} | ||
|
||
/** | ||
* Authenticate to GitHub using a PAT. | ||
*/ | ||
default GitHub patAuthentication(String pat) { | ||
return new GitHubBuilder() | ||
.withJwtToken(pat) | ||
.build() | ||
} | ||
|
||
static class AppAuthBuilder { | ||
static Function<AppAuthBuilder, GitHub> appProvider | ||
|
||
/** | ||
* The ID of the app. | ||
*/ | ||
String appId | ||
|
||
/** | ||
* The private key of the app | ||
*/ | ||
String privateKey | ||
|
||
/** | ||
* The installation of the app | ||
*/ | ||
String installation | ||
|
||
/** | ||
* Read text from a file | ||
*/ | ||
String readFile(String path) { | ||
return Files.readString(Path.of(path)) | ||
} | ||
|
||
/** | ||
* Organization-based installation | ||
*/ | ||
String organization(String name) { | ||
return name | ||
} | ||
|
||
/** | ||
* Repository-based installation | ||
*/ | ||
String repository(String owner, String name) { | ||
return owner + '/' + name | ||
} | ||
|
||
@Requires({ appId && privateKey && installation }) | ||
Function<GHApp, GHAppInstallation> build() { | ||
return { GHApp it -> | ||
if (installation.contains('/')) { | ||
return it.getInstallationByRepository(installation.split('/')[0], installation.split('/')[1]) | ||
} else { | ||
return it.getInstallationByOrganization(installation) | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.