├── .gitignore
├── LICENSE.md
├── README.md
├── _config.yml
├── build.gradle.kts
├── commands.md
├── docker
└── Dockerfile
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── guide.md
├── setup.md
└── src
└── main
├── kotlin
└── me
│ └── jakejmattson
│ └── embedbot
│ ├── MainApp.kt
│ ├── arguments
│ ├── EmbedArg.kt
│ ├── FieldArg.kt
│ ├── FieldIndexArg.kt
│ └── GroupArg.kt
│ ├── commands
│ ├── CoreCommands.kt
│ ├── EditCommands.kt
│ ├── FieldCommands.kt
│ ├── GroupCommands.kt
│ ├── GuildConfigurationCommands.kt
│ ├── InfoCommands.kt
│ ├── OwnerCommands.kt
│ └── UtilityCommands.kt
│ ├── dataclasses
│ ├── Cluster.kt
│ ├── Configuration.kt
│ ├── Embed.kt
│ ├── GuildEmbeds.kt
│ └── OperationResult.kt
│ ├── extensions
│ ├── Command.kt
│ ├── Guild.kt
│ └── Message.kt
│ ├── listeners
│ └── SetupListeners.kt
│ ├── preconditions
│ ├── LoadedEmbedPrecondition.kt
│ └── PermissionPrecondition.kt
│ ├── services
│ ├── EmbedService.kt
│ └── PermissionsService.kt
│ └── utils
│ └── Constants.kt
└── resources
└── templates
└── readme-template.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # Configuration
2 | config/
3 |
4 | # IntelliJ
5 | .idea/
6 | *.iml
7 |
8 | # Gradle
9 | .gradle/
10 | build/
11 | gradle.properties
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jacob Mattson
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | # EmbedBot
21 | EmbedBot is a simple bot interface to create and modify embeds via commands. Creating embeds is not possible with a user account via the traditional Discord interface. You can create and store as many embeds as you want. These can be imported and exported as JSON for easy sharing between servers or persistent storage. You can also group embeds together, allowing you to deploy and manage multiple embeds at once. This will allow servers to easily set up a rules channel, keeping all of the related embeds grouped together and ready to send with a single command.
22 |
23 | ## Add it
24 | You can either [invite](https://discordapp.com/oauth2/authorize?client_id=439163847618592782&scope=bot&permissions=101440) it to your server or host it yourself with the [setup guide](setup.md).
25 |
26 | ## Using it
27 | To use the bot, see the [User Guide](guide.md) or a full list of [commands](commands.md).
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-modernist
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
2 |
3 | group = "me.jakejmattson"
4 | version = Versions.BOT
5 |
6 | plugins {
7 | kotlin("jvm") version "1.4.0"
8 | id("com.github.johnrengelman.shadow") version "6.0.0"
9 | }
10 |
11 | repositories {
12 | mavenCentral()
13 | jcenter()
14 | }
15 |
16 | dependencies {
17 | implementation("me.jakejmattson:DiscordKt:${Versions.DISCORDKT}")
18 | }
19 |
20 | tasks {
21 | withType {
22 | kotlinOptions.jvmTarget = "1.8"
23 | }
24 |
25 | copy {
26 | from(file("src/main/resources/templates/readme-template.md"))
27 | into(file("."))
28 | rename{ "README.md" }
29 | expand(
30 | "kotlin" to kotlin.coreLibrariesVersion,
31 | "discordkt" to Versions.DISCORDKT
32 | )
33 | }
34 |
35 | shadowJar {
36 | archiveFileName.set("EmbedBot.jar")
37 | manifest {
38 | attributes(
39 | "Main-Class" to "me.jakejmattson.embedbot.MainAppKt"
40 | )
41 | }
42 | }
43 | }
44 |
45 | object Versions {
46 | const val BOT = "2.1.0"
47 | const val DISCORDKT = "0.19.1"
48 | }
--------------------------------------------------------------------------------
/commands.md:
--------------------------------------------------------------------------------
1 | # Commands
2 |
3 | ## Key
4 | | Symbol | Meaning |
5 | | ----------- | ------------------------------ |
6 | | (Argument) | Argument is not required. |
7 | | Argument... | Accepts many of this argument. |
8 |
9 | ## Core
10 | | Commands | Arguments | Description |
11 | | ------------ | ------------------------------ | ------------------------------------------------------- |
12 | | Copy | Embed Name, Message Link or ID | Copy an embed by its message ID. |
13 | | Create | Embed Name | Create a new embed with this name. |
14 | | Delete | (Embed...) | Delete the embed with this name. |
15 | | Duplicate | Embed Name, (Embed) | Create a new embed from an existing embed. |
16 | | ExecuteAll | Commands | Execute a batch of commands in sequence. |
17 | | Export | (Embed), (preferFile) | Export the currently loaded embed to JSON. |
18 | | Import | Embed Name, File \| String | Import a JSON file or string as an embed. |
19 | | Load | Embed | Load the embed with this name into memory. |
20 | | Send | (Channel), (saveLocation) | Send the currently loaded embed. |
21 | | Update | | Update the message embed |
22 | | UpdateTarget | Message Link or ID | Replace the target message embed with the loaded embed. |
23 |
24 | ## Edit
25 | | Commands | Arguments | Description |
26 | | -------------- | ----------------- | --------------------------------------------------- |
27 | | Clear | (Clear Target) | Clear a target field from the loaded embed. |
28 | | Rename | (Embed), New Name | Change the name of an existing embed. |
29 | | SetAuthor | User | Set the author for the currently loaded embed. |
30 | | SetColor | Hex Color | Set the color for the currently loaded embed. |
31 | | SetDescription | Text | Set the description for the currently loaded embed. |
32 | | SetFooter | Icon URL, Text | Set the footer for the currently loaded embed. |
33 | | SetImage | URL | Set the image for the currently loaded embed. |
34 | | SetThumbnail | URL | Set the thumbnail for the currently loaded embed. |
35 | | SetTimestamp | | Set the timestamp for the currently loaded embed. |
36 | | SetTitle | Text | Set the title for the currently loaded embed. |
37 |
38 | ## Field
39 | | Commands | Arguments | Description |
40 | | -------------- | ----------------------- | -------------------------------------------------------- |
41 | | AddBlankField | (isInline) | Add a blank field to the loaded embed. |
42 | | AddField | Field Data | Add a field in the following format: title\|body\|inline |
43 | | InsertField | Index, Field Data | Insert a field at an index to the loaded embed. |
44 | | RemoveField | Field Index | Remove a field from the loaded embed by its index. |
45 | | SetField | Field Index, Field Data | Edit a field at a given index with the given data. |
46 | | SetFieldInline | Field Index, Boolean | Get a field by its index and edit its inline value. |
47 | | SetFieldText | Field Index, Text | Get a field by its index and edit its text value. |
48 | | SetFieldTitle | Field Index, Text | Get a field by its index and edit its title value. |
49 |
50 | ## Group
51 | | Commands | Arguments | Description |
52 | | --------------- | ------------------------------- | ------------------------------------------------------ |
53 | | AddToGroup | Group, Embed... | Add an embed into a group. |
54 | | CloneGroup | Group Name, (Channel), Amount | Clone a group of embeds. |
55 | | CreateGroup | Group Name, (Embed...) | Create a group of embeds. |
56 | | DeleteGroup | Group | Delete a group and all of its embeds. |
57 | | Deploy | Group, (Channel), (saveLocation) | Deploy a group into a target channel. |
58 | | InsertIntoGroup | Group, Index, Embed | Insert an embed into a group at an index. |
59 | | RemoveFromGroup | Embed... | Remove embeds from their current group. |
60 | | RenameGroup | Group, New Name | Change the name of an existing group. |
61 | | UpdateGroup | Group | Update the original embeds this group was copied from. |
62 |
63 | ## GuildConfiguration
64 | | Commands | Arguments | Description |
65 | | --------- | --------- | ---------------------------------------------------------- |
66 | | DeleteAll | | Delete all embeds and groups in this guild. |
67 | | SetPrefix | Prefix | Set the prefix required for the bot to register a command. |
68 | | SetRole | Role | Set the role required to use this bot. |
69 |
70 | ## Information
71 | | Commands | Arguments | Description |
72 | | ---------- | --------- | --------------------------------------- |
73 | | Info | (Embed) | Get extended info for the target embed. |
74 | | Limits | | Display the discord embed limits. |
75 | | ListEmbeds | | List all embeds created in this guild. |
76 |
77 | ## Owner
78 | | Commands | Arguments | Description |
79 | | --------- | --------------------------------- | ------------------------------------------------------- |
80 | | Broadcast | Message | Send a direct message to all guild owners. |
81 | | Guilds | (Sort) | Get a complete list of guilds and info. |
82 | | Kill | | Kill the bot. It will remember this decision. |
83 | | Leave | (Guild) | Leave this guild and delete all associated information. |
84 | | Transfer | (Embed), Target Guild, (New Name) | Send an embed to another guild. |
85 |
86 | ## Utility
87 | | Commands | Arguments | Description |
88 | | -------------------- | --------- | ---------------------------------------- |
89 | | Help | (Command) | Display a help menu. |
90 | | Status, Ping, Uptime | | Display network status and total uptime. |
91 |
92 |
--------------------------------------------------------------------------------
/docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM gradle:6.7.0-jdk15 AS build
2 | COPY --chown=gradle:gradle . /embedbot
3 | WORKDIR /embedbot
4 | RUN gradle shadowJar --no-daemon
5 |
6 | FROM openjdk:8-jre-slim
7 | ENV BOT_TOKEN=UNSET
8 | RUN mkdir /config/
9 | COPY --from=build /embedbot/build/libs/*.jar /EmbedBot.jar
10 |
11 | ENTRYPOINT ["java", "-jar", "/EmbedBot.jar", "$BOT_TOKEN"]
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JakeJMattson/EmbedBot/5f49f5720f7be8d195ebce2cba93a8e9918e1d87/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto init
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto init
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :init
68 | @rem Get command-line arguments, handling Windows variants
69 |
70 | if not "%OS%" == "Windows_NT" goto win9xME_args
71 |
72 | :win9xME_args
73 | @rem Slurp the command line arguments.
74 | set CMD_LINE_ARGS=
75 | set _SKIP=2
76 |
77 | :win9xME_args_slurp
78 | if "x%~1" == "x" goto execute
79 |
80 | set CMD_LINE_ARGS=%*
81 |
82 | :execute
83 | @rem Setup the command line
84 |
85 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
86 |
87 |
88 | @rem Execute Gradle
89 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
90 |
91 | :end
92 | @rem End local scope for the variables with windows NT shell
93 | if "%ERRORLEVEL%"=="0" goto mainEnd
94 |
95 | :fail
96 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
97 | rem the _cmd.exe /c_ return code!
98 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
99 | exit /b 1
100 |
101 | :mainEnd
102 | if "%OS%"=="Windows_NT" endlocal
103 |
104 | :omega
105 |
--------------------------------------------------------------------------------
/guide.md:
--------------------------------------------------------------------------------
1 | # User Guide
2 |
3 | Guide style:
4 | * The assumed prefix will be `e!`.
5 | * Commands use a readable format, but case does not matter (`Help` vs `help`).
6 |
7 | ## The Basics
8 |
9 | Before we start working, we need to create a new embed. You can do this with the `Create` command.
10 | * `e!Create hello`
11 |
12 | This creates a new embed, but it's empty. Let's add some text.
13 | * `e!SetTitle Hello World`
14 |
15 | Now you can display it on discord by sending it.
16 | * `e!Send`
17 |
18 | You've just created your first embed!
19 |
20 | ## Commands
21 |
22 | To find information about commands, you can use the `Help` feature.
23 | * `e!Help` will list all available commands.
24 | * `e!Help [Command]` will give help for a specific command.
25 |
26 | ## Editing Embeds
27 |
28 | If your embed is more permanent, like something in a #rules channel, we want to have a way to update it.
29 |
30 | The easiest way is to keep track of your embed when you send it.
31 |
32 | `e!Send true`
33 |
34 | This saves the message information. Once you make all of your changes, you can update it with one command.
35 |
36 | `e!Update`
37 |
38 | If you didn't track your embed when you first sent it, you can also update a message's embed.
39 |
40 | `e!UpdateTarget`
41 |
42 |
43 | ## Updating Sent Embeds
44 |
45 | ## Creating Multiple Embeds
46 |
47 | This bot can store as many embeds as you want, but this means that the bot needs to know which embed you're talking about when you run a command. It does this by keeping a single embed loaded. This allows you to edit embeds without having to specify the name each time.
48 |
49 | * You can run `e!ListEmbeds` to see all the embeds you have.
50 | * You can run `e!Load [Embed Name]` to load a different embed.
51 |
52 | ## Managing Multiple Embeds
53 |
54 | ## Importing Embeds
55 |
56 | ## Other useful commands
--------------------------------------------------------------------------------
/setup.md:
--------------------------------------------------------------------------------
1 | ## Discord Setup
2 |
3 | Not interested in all the technical stuff? Just [invite](https://discordapp.com/oauth2/authorize?client_id=439163847618592782&scope=bot&permissions=101440) the bot directly.
4 |
5 | ### Bot Account
6 | Create a bot account in the [developers](https://discordapp.com/developers/applications/me) section of the Discord website.
7 | - Create an application
8 | - Under "General Information"
9 | - Enter an app icon and a name.
10 | - You will need the client ID when adding the bot to a server.
11 | - Under "Bot"
12 | - Create a bot.
13 | - Give it a username and app icon.
14 | - You will need the token when operating the bot.
15 | - This is a secret token, don't reveal it!
16 | - Save changes
17 |
18 | ### Add Bot
19 | - Visit the [permissions](https://discordapi.com/permissions.html) page.
20 | - Under "OAth URL Generator" enter the bot's client ID from the step above.
21 | - Click the link to add it to a server.
22 |
23 | ## Build Guide
24 |
25 | Choose one of the following build options.
26 |
27 |
28 | Source Code
29 |
30 | ### Prerequisites
31 | - [Download](https://github.com/JakeJMattson/EmbedBot/archive/master.zip) the code.
32 | - Install [Java](https://openjdk.java.net/) and [Gradle](https://gradle.org/install/).
33 |
34 | ### Building
35 | Once you have your prerequisites installed, Gradle will be doing the rest.
36 |
37 | * Navigate to the root of the project (`./EmbedBot`)
38 | * Run `gradle shadowJar` to build a JAR in `./build/libs/`
39 | * Proceed to the JAR guide below on how to run it.
40 |
41 |
42 |
43 |
44 | JAR/Release
45 |
46 | ### Prerequisites
47 | - Install [Java](https://openjdk.java.net/).
48 | - Download a JAR from [releases](https://github.com/JakeJMattson/EmbedBot/releases/), unless you built it yourself.
49 |
50 | ### Environment
51 | - To run the JAR, you will need to be able to access Java from the command line/terminal. Run `java -version` and make sure your operating system can recognize the command.
52 | - Place the JAR somewhere safe and out of the way. It will generate configuration files on its own.
53 |
54 | ### Running
55 | - Open the command prompt and navigate to the folder that the JAR is in.
56 | - Run the following command: `java -jar EmbedBot.jar `
57 | - `` should be replaced with your Discord bot token
58 |
59 | - The bot should respond that configuration files have been generated. This will be in the `config` folder within the folder you created for this project.
60 | - Open `config.json` with any text editor and fill out the fields. You can read more about this below.
61 | - Run the same command again: `java -jar EmbedBot.jar token`
62 |
63 | The JAR will now read in your provided configuration values and start the bot. Your bot account should now be online!
64 |
65 |
66 |
67 | Docker
68 |
69 | New containers for this project are built automatically. Pulling it with Docker will always give you the most recent commit.
70 |
71 | * Install [Docker Desktop](https://www.docker.com/get-started) onto your machine.
72 | * Run `docker pull jakejmattson/embedbot`
73 | * Run `docker run -e BOT_TOKEN= -v :/config embedbot:latest`
74 | * `` should be replaced with the bot token obtained from the steps above.
75 | * `` should be replaced with a local path where you want to store the configuration files.
76 |
77 | Your Docker container should now be running.
78 |
79 |
80 |
81 | ## Configuration
82 |
83 | ```json
84 | {
85 | "botOwner": "The discord user with owner permissions.",
86 | "guildConfigurations": {
87 | "244230771232079873": {
88 | "prefix": "The prefix typed before a command.",
89 | "requiredRoleId": "The ID of the role required to use the bot."
90 | }
91 | }
92 | }
93 | ```
94 |
95 | ### Sanity Check
96 | Once you have your bot account online, you can verify that it's working by mentioning the bot on Discord `@EmbedBot`. Make sure it has permissions to read and write in the place where you want it to respond. It is recommended that you give it a role.
--------------------------------------------------------------------------------
/src/main/kotlin/me/jakejmattson/embedbot/MainApp.kt:
--------------------------------------------------------------------------------
1 | package me.jakejmattson.embedbot
2 |
3 | import me.jakejmattson.discordkt.api.dsl.bot
4 | import me.jakejmattson.discordkt.api.extensions.jda.*
5 | import me.jakejmattson.embedbot.dataclasses.Configuration
6 | import me.jakejmattson.embedbot.extensions.requiredPermissionLevel
7 | import me.jakejmattson.embedbot.services.PermissionsService
8 | import java.awt.Color
9 |
10 | fun main(args: Array) {
11 | val token = args.firstOrNull()
12 | ?: throw IllegalArgumentException("No program arguments provided. Expected bot token.")
13 |
14 | bot(token) {
15 | configure {
16 | val (configuration, permissionsService)
17 | = it.getInjectionObjects(Configuration::class, PermissionsService::class)
18 |
19 | commandReaction = null
20 | allowMentionPrefix = true
21 |
22 | prefix {
23 | it.guild?.let { configuration[it.idLong]?.prefix } ?: ""
24 | }
25 |
26 | colors {
27 | infoColor = Color(0x00BFFF)
28 | }
29 |
30 | mentionEmbed {
31 | val guild = it.guild ?: return@mentionEmbed
32 | val jda = it.discord.jda
33 | val properties = it.discord.properties
34 | val prefix = it.relevantPrefix
35 | val role = configuration[guild.idLong]?.getLiveRole(jda)?.takeUnless { it == guild.publicRole }?.asMention
36 | ?: ""
37 |
38 | author {
39 | jda.retrieveUserById(254786431656919051).queue { user ->
40 | iconUrl = user.effectiveAvatarUrl
41 | name = user.fullName()
42 | url = user.profileLink
43 | }
44 | }
45 |
46 | simpleTitle = "EmbedBot"
47 | thumbnail = jda.selfUser.effectiveAvatarUrl
48 | color = infoColor
49 | description = (if (role.isNotBlank()) "You must have $role" else "") +
50 | "\nCurrent prefix is `$prefix`" +
51 | "\nUse `${prefix}help` to see commands."
52 |
53 | addInlineField("", "[[Invite Me]](https://discordapp.com/oauth2/authorize?client_id=439163847618592782&scope=bot&permissions=101440)")
54 | addInlineField("", "[[See Code]](https://github.com/JakeJMattson/EmbedBot)")
55 | addInlineField("", "[[User Guide]](https://github.com/JakeJMattson/EmbedBot/blob/master/guide.md)")
56 |
57 | footer {
58 | text = "2.1.0 - ${properties.libraryVersion} - ${properties.jdaVersion}"
59 | }
60 | }
61 |
62 | visibilityPredicate {
63 | val guild = it.guild ?: return@visibilityPredicate false
64 | val member = it.user.toMember(guild)!!
65 | val permission = it.command.requiredPermissionLevel
66 |
67 | permissionsService.hasClearance(member, permission)
68 | }
69 |
70 | it.jda.guilds.forEach {
71 | configuration.setup(it)
72 | }
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/src/main/kotlin/me/jakejmattson/embedbot/arguments/EmbedArg.kt:
--------------------------------------------------------------------------------
1 | package me.jakejmattson.embedbot.arguments
2 |
3 | import me.jakejmattson.discordkt.api.dsl.arguments.*
4 | import me.jakejmattson.discordkt.api.dsl.command.CommandEvent
5 | import me.jakejmattson.embedbot.dataclasses.Embed
6 | import me.jakejmattson.embedbot.extensions.*
7 | import me.jakejmattson.embedbot.utils.messages
8 |
9 | open class EmbedArg(override val name: String = "Embed") : ArgumentType