Großes Update - Ehemalig VoiceChannelExtra Bot genannt
Neuer Name: ALcord-Bot
WICHTIG: Der Bot befindet sich weiterhin in Entwicklung, Features können sich verändern oder Bugs können auftreten. Ich bitte dies zu beachten!!
Folgende Funktionen wurden dem Bot hinzugefügt:
- Webinterface (Aktivität, Einstellungen, Lobbies)
- Aktivitätstracking (standard deaktiviert)
- API
- Updates der Bibliotheken
- Changelog in Discord und dem Webinterface
Discord Bot - Idee / Funktion
In einem Gespräch wurde der Wunsch nach einer Ping Möglichkeit, wie aus Teamspeak bekannt, angesprochen, welche so nicht in Discord existiert. Discord unterstützt zwar eine Funktion mit dem Namen “Mentions”, diese sind jedoch nicht vergleichbar mit einem Anstupsen oder einem Ping. In Zukunft soll eine Gruppe von Nutzern automatisch eine Ping Nachricht bekommen, sobald ein Nutzer einen bestimmten Voice Channel betritt.
Außerdem war in dem Zuge von einer Minimierung von Voice Channels die Rede, da normale Voice Channel nicht mit dem Bedarf skalieren und somit auch häufig zu viele oder zu wenige vorhanden sind. Da würde sich anbieten, dass automatisch neue Channels erzeugt werden, wenn die bestehenden gefüllt sind.
Die Lobby Funktion wurde bereits durch diverse andere Bots umgesetzt. Ich habe mich an folgender Umsetzung orientiert (Orientierung => Funktion ähnlich, Code ist vollständig unabhängig) Auto Voice Channels
Commands / Befehle
Optionales Flag: {removeFlag}
zum Entfernen von Rolle oder Channel. Der Wert sollte entweder true
oder false
sein.
Einen Text Kanal festlegen, um Nachrichten vom Bot zu erhalten. (z.B. Berechtigungen fehlen, Update News und mehr)/setup bot_channel {text_channel} [{removeFlag}]
Eine Admin Rolle festlegen, bestimmt welche Rolle Zugriff auf die Hauptfunktionen des Bots hat/setup admin_role {role} [{removeFlag}]
Aktiviert oder Deaktiviert das Tracken der Nutzeraktivität. Standard ist deaktiviert/setup toggle_tracking
Erstellen einer Zuweisung für die Ping Nachrichten beim Joinen des Channels/ping channel {name} [{removeFlag}]
Zuweisung der Benachrichtigungsrolle/ping role {name} [{removeFlag}]
Anzeigen der Informationen zu den Pings/ping info
Wichtige Information: Der Ping wird nur ausgeführt, wenn der Beitretende nicht von der Benachrichtigungsrolle stammt. Andernfalls würde auch eine Nachricht versendet werden, wenn du selbst dem Kanal beitrittst. Eine Option zum Umschalten könnte in späteren Updates noch folgen. Link zum Einladen des Bots anzeigen
/invite
Informationen zum Bot/info
Benachrichtigung stumm schalten/mute
Lobby erstellen, welche repliziert wird beim Joinen/lobby create {channel}
Lobby entfernen, Temporäre Channel werden anschließend entfernt/lobby remove {channel}
Informationen über aktuelle Lobbies/lobby info
Gibt eine Ausgabe in CSV Format von allen gespeicherten Aktivitätsinformationen/tracker activitycsv
Gibt eine Ausgabe der aktivsten Stunden des Tages/tracker activityhours
Gibt eine Ausgabe der aktivsten Tage der Woche/tracker activityweek
Gibt eine Ausgabe in Tabellen Format von allen gespeicherten Aktivitätsinformationen. Standard 10 Mitglieder, [{amount}]
Bestimmt die Anzahl, [{all}]
gibt alle aus./tracker lastactivemembers [{amount}] [{all}]
Fügt einem Mitglied eine Notiz hinzu/user addnote
Entfernt die Notiz von dem Mitglied/user removenote
Einige Funktionen sind auch als Rechtsklick auf ein Mitglied verfügbar!!
Umsetzung
Für die Umsetzung wurde die Sprache Java verwendet mit der Bibliothek JDA (Java Discord API). Außerdem wurde für die API Javelin verwendet. Das Webinterface wurde mit SolidJS, sowie Bootstrap umgesetzt.
Java Umsetzung
Nachfolgend werden einzelne Umsetzungen beschrieben und mit kleinen Code Ausschnitten angereichert. Der komplette Quellcode wird derzeit nicht geteilt.
Ping Funktion
Die Ping Funktion nimmt die eingetragenen Kanal-IDs und eine Empfänger-Rolle als Parameter auf. Die Funktion wird immer dann aufgerufen, wenn jemand einen Sprachkanal betritt. Beim Betreten wird ein Event ausgelöst, welches dann prüft, ob dieser Kanal registriert wurde. Anschließend werden die Rollen abgefragt und die entsprechenden Mitglieder über eine DM benachrichtigt.
if (guildConfig.getPingChannels().contains(channel.getId())) {
ResourceBundle locale = ResourceBundle.getBundle("language", Locale.forLanguageTag(event.getGuild().getLocale().getLanguageName()));
List<Member> userList = new ArrayList<>();
for (String roleID : guildConfig.getPingRoles()) {
Role role = event.getJDA().getRoleById(roleID);
userList.addAll(event.getGuild().getMembersWithRoles(role));
}
userList = userList.stream()
.filter(member -> !member.getUser().getId().equals(event.getMember().getUser().getId()))
.filter(member -> !guildConfig.getUserMuted().contains(member.getUser().getId()))
.filter(member -> member.getOnlineStatus().equals(OnlineStatus.ONLINE))
.filter(member -> !member.getUser().isBot())
.collect(Collectors.toList());
userList.forEach(member -> {
log.debug("Ping sending to {}", member.getEffectiveName());
member.getUser().openPrivateChannel().queue(privateChannel -> privateChannel.sendMessageEmbeds(new EmbedBuilder()
.setTitle(locale.getString("ping.message.title"))
.setDescription(String.format(locale.getString("ping.message.text"), member.getEffectiveName(), channel.getName()))
.build()).queue());
});
}
}
Lobby Funktion
Wie bei der Ping Funktion im Code bereits zu sehen, wird auch dort ein LobbyListener
initiiert. Dieser regelt das automatische Erstellen neuer Kanäle beim Betreten von dem Lobbykanal. Dabei wird der Name zunächst repliziert und anschließend an das grade am meisten gespielte Spiel der Teilenehmer angepasst.
Hier ist einmal die Funktion, welche die am meisten gespielte Aktivität im Sprachkanal ermittelt. Diese wird bei Betreten, Verlassen sowie einer Änderung der Aktivität aufgerufen.
Ich muss hierbei noch testen, ob diese Menge eventuell die Rate Limits von Discord sprengen.
private String getMaxActivity(VoiceChannel primary) {
Map<String, Long> groupedActivities = primary.getMembers()
.stream().flatMap(member -> member.getActivities().stream())
.collect(Collectors.groupingBy(Activity::getName, Collectors.counting()));
return groupedActivities.entrySet().stream()
.filter(stringLongEntry -> !stringLongEntry.getKey().equals("Custom Status"))
.peek(stringLongEntry -> log.info("Activity: {}/{}", stringLongEntry.getKey(), stringLongEntry.getValue()))
.sorted(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.findFirst().orElse(null);
}
Hosting mit Docker
Um das Hosten so einfach wie möglich zu machen und mir auch Arbeit beim Deployen zu sparen, habe ich mich für ein Docker Image entschieden. Dieses ist wie folgt aufgebaut:
FROM maven:3.9.0-eclipse-temurin-19 as builder
WORKDIR /usr/src/ALcordBot/
COPY . /usr/src/ALcordBot/
RUN mvn clean install
FROM openjdk:19 as runner
ENV VERSION="1.1.0"
COPY --from=builder /usr/src/ALcordBot/target/ALcordBot-${VERSION}.jar /usr/src/ALcordBot/ALcordBot-${VERSION}.jar
COPY --from=builder /usr/src/ALcordBot/target/libs /usr/src/ALcordBot/libs
WORKDIR /usr/src/ALcordBot/
VOLUME /usr/src/ALcordBot/config/
LABEL version="${VERSION}"
LABEL description="I am a Discord Bot, which is specially designed for the Watchpoint Community."
LABEL org.opencontainers.image.description="ALcordBot"
LABEL org.opencontainers.image.licenses=Private
LABEL authors="ModdyLP"
ENV BOT_TOKEN=""
CMD ["java","-jar", "ALcordBot-1.1.0.jar", "--config", "./config/config.json"]
Dabei basiert das Image auf dem OpenJDK 19 und kopiert als ersten Schritt die gebaute Botinstanz in das Arbeitsverzeichnis.
Anschließend wird das Workdir, ein Volume und Labels erstellt. Der Bot Token kann als einzige Konfigurationsvariable direkt als Environment variable übergeben werden. Der Rest muss im Volume in der Konfigurationsdatei angepasst werden.
Zuletzt wird der Start Befehl definiert.
Ausprobieren
Der Bot lässt sich über den unten aufgeführten Link ausprobieren. Ich behalte mir vor, die Nutzung des Bots zu blockieren, wenn die Funktionen nicht ordnungsgemäß genutzt oder ausgenutzt werden.
Ein eigenes Hosten ist möglich, jedoch nur auf Anfrage, um eine bessere Performance zu bekommen.
Eine Verbreitung, Vervielfältigung oder Veränderung des Bots, ist nicht gestattet. Das Urheberrecht findet hier entsprechend Anwendung. Beim Self-Hosting ist zwingend eine Referenz zu mir, als Autor in Form eines Links hinzuzufügen. Ein Verstoß hat entsprechende rechtliche Konsequenzen.
Eine Nutzung des Bots und ein Hosten ist unter Einhaltung der Regeln kostenlos.
Support
Support kann ich gerne auf Discord anbieten: Support
Feedback
ich freue mich über jedes Feedback, dazu gerne einen Kommentar schreiben oder mit mir Kontakt aufnehmen.
Bild von Arek Socha auf Pixabay