Skip to content

Commit

Permalink
Merge pull request #7 from edward3h/configure
Browse files Browse the repository at this point in the history
multiple webhooks, configuration for message sending
  • Loading branch information
edward3h authored Jan 28, 2022
2 parents 0652b9a + ce75b86 commit 1fc011d
Show file tree
Hide file tree
Showing 19 changed files with 542 additions and 103 deletions.
37 changes: 37 additions & 0 deletions .github/workflows/publish_mr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Publish Docker image

on:
pull_request:
branches:
- main

env:
REGISTRY: ghcr.io
IMAGE_NAME: edward3h/mc-webhook

jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Log in to the Container registry
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up JDK 11
uses: ayltai/setup-graalvm@v1
with:
java-version: 11
graalvm-version: 21.3.0
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew dockerPush -Pgithub_ref=${GITHUB_SHA}
86 changes: 60 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,44 +33,78 @@ services:
stdin_open: true
tty: true

backup:
image: kaiede/minecraft-bedrock-backup
container_name: backup
restart: "unless-stopped"
depends_on:
- "minecraft1"
environment:
DEBUG: "true"
BACKUP_INTERVAL: "6h"
TZ: "America/New_York"
UID: 1000
GID: 998
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- "${MC_HOME}/backups:/backups"
- "${MC_HOME}/server:/minecraft1"

webhook:
image: ghcr.io/edward3h/mc-webhook:latest
image: ghcr.io/edward3h/mc-webhook:0.3
restart: "unless-stopped"
env_file: .env
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./config.yml:/config.yml
```
### Configuration File
Since 0.3, mc-webhook supports multiple webhooks defined in a config file. It should be mounted into docker as `config.yml`.

_config.yml_
```yaml
mc-webhook:
image-names: itzg/minecraft-bedrock-server
webhooks:
discord1:
type: discord
url: https://discordapp.com/api/webhooks/[ids from your discord server]
# if events: are not specified, defaults to all events, with default messages
json1:
type: json
url: http://your.server/webhook
# POSTs a JSON object to the given URL. See below.
discord_custom:
type: discord
url: https://discordapp.com/api/webhooks/[ids from your discord server]
events:
PLAYER_CONNECTED: Hello %playerName% with id %playerXuid%
SERVER_STARTED: The world %worldName% is starting on %containerName%
# only these events will send a message
# values in %% will be substituted
```
### Events
These are the current event types:
* PLAYER_CONNECTED
* PLAYER_DISCONNECTED
* SERVER_STARTED
* SERVER_STOPPED

### JSON message
Using the `json` type will send a message like:
```json
{
"type": "PLAYER_CONNECTED",
"containerId": "dd5f449daad5dbd0a3f659bbfabcde47605e1a69211e1f7a9d47b758cc54",
"containerName": "/minecraft1",
"worldName": "My Level",
"playerName": "Steve",
"playerXuid": "12345"
}
```

### Custom Message format
You can customize the message sent for each event by entering it after the event type (see above example).
Any of the following will be substituted into the text:
* %containerId%
* %containerName%
* %worldName%
* %playerName%
* %playerXuid%

### Legacy configuration
The previous environment variables are still supported, so you don't have to reconfigure from a previous version.

_.env_

```ini
MC_HOME=/path/to/store/minecraft/data
MC_WEBHOOK_WEBHOOK_URL=https://discordapp.com/api/webhooks/[ids from your discord server]
```

### Notes

* MC_WEBHOOK_WEBHOOK_URL environment variable is **required** and should be copied from your Discord Server Settings.
* The server defaults to looking for containers running 'itzg/minecraft-bedrock-server'. It should work for other images as long as the bedrock-server console output appears in the docker logs. To use a different image, specify it in `MC_WEBHOOK_IMAGE_NAME`.

## Links

* https://github.com/itzg/docker-minecraft-bedrock-server
* https://github.com/Kaiede/docker-minecraft-bedrock-backup
* https://github.com/itzg/docker-minecraft-bedrock-server
18 changes: 13 additions & 5 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ java {
}
}

version = "0.2"
version = "0.3"

repositories {
mavenCentral()
Expand All @@ -44,6 +44,7 @@ dependencies {
implementation 'jakarta.inject:jakarta.inject-api'

implementation 'org.apache.logging.log4j:log4j-api:2.17.1'
implementation 'org.apache.commons:commons-text:1.9'

runtimeOnly group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.17.1'
runtimeOnly 'org.apache.logging.log4j:log4j-core:2.17.1'
Expand Down Expand Up @@ -76,11 +77,18 @@ tasks.named('test') {

tasks.named("dockerfile") {
baseImage = "ghcr.io/graalvm/graalvm-ce:java11-21.3.0"
instruction """RUN touch /config.yml"""
}

tasks.named("dockerBuild") {
images = [
"ghcr.io/edward3h/mc-webhook:latest",
"ghcr.io/edward3h/mc-webhook:${project.version}"
]
if (project.hasProperty("github_ref")) {
images = [
"ghcr.io/edward3h/mc-webhook:${project.version}-SNAPSHOT-${project.property("github_ref")}"
]
} else {
images = [
"ghcr.io/edward3h/mc-webhook:latest",
"ghcr.io/edward3h/mc-webhook:${project.version}"
]
}
}
7 changes: 6 additions & 1 deletion app/src/main/java/org/ethelred/minecraft/webhook/App.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* (C) Edward Harman 2022 */
package org.ethelred.minecraft.webhook;

import io.micronaut.runtime.Micronaut;
Expand All @@ -7,9 +8,13 @@
public class App {

public static void main(String[] args) {
// tell Micronaut to look for config in known paths of the docker image
System.setProperty(
"micronaut.config.files",
"/config.yml" // in root of docker image
);
Micronaut
.build(args)
.eagerInitSingletons(true)
.mainClass(App.class)
.defaultEnvironments("dev")
.start();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* (C) Edward Harman 2022 */
package org.ethelred.minecraft.webhook;

import io.micronaut.context.BeanContext;
import io.micronaut.context.annotation.Context;
import io.micronaut.context.annotation.Property;
import io.micronaut.context.annotation.Requires;
import io.micronaut.core.convert.ConversionService;
import java.net.URL;

/**
* this bean maps the original webhook property into the updated system for backwards compatibility
*/
@Context
@Requires(property = "mc-webhook.webhook-url")
public class BackCompatUrlSetup extends MinecraftServerEventListener {

public BackCompatUrlSetup(
BeanContext context,
ConversionService<?> conversionService,
@Property(name = "mc-webhook.webhook-url") URL url
) {
super(context, conversionService, getConfiguration(url));
}

private static SenderConfiguration getConfiguration(URL url) {
var config = new SenderConfiguration();
config.setUrl(url); // defaults are ok for other properties
return config;
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* (C) Edward Harman 2022 */
package org.ethelred.minecraft.webhook;

import jakarta.inject.Qualifier;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* (C) Edward Harman 2022 */
package org.ethelred.minecraft.webhook;

import com.github.dockerjava.api.DockerClient;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
/* (C) Edward Harman 2022 */
package org.ethelred.minecraft.webhook;

import io.micronaut.context.annotation.Parameter;
import io.micronaut.context.annotation.Prototype;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import jakarta.inject.Named;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.http.*;
import java.net.http.HttpClient;
import java.util.Optional;
Expand All @@ -16,7 +20,8 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

@Singleton
@Prototype
@Named("discord")
public class DiscordWebhookSender implements Sender {

private static final long DEFAULT_DELAY = 3_000;
Expand All @@ -30,9 +35,9 @@ public class DiscordWebhookSender implements Sender {
private final BlockingQueue<String> waiting;

@Inject
public DiscordWebhookSender(Options options) {
public DiscordWebhookSender(@Parameter URL webhookUrl) {
try {
this.webhook = options.getWebhookUrl().toURI();
this.webhook = webhookUrl.toURI();
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e);
}
Expand All @@ -41,7 +46,7 @@ public DiscordWebhookSender(Options options) {
this.waiting = new ArrayBlockingQueue<>(64);
_scheduleNext(0L);
LOGGER.info(
"DiscordWebhookSender initalized with URL {}",
"DiscordWebhookSender initialized with URL {}",
this.webhook
);
}
Expand Down Expand Up @@ -114,8 +119,7 @@ private void _sendMessage(String message) {
}
} catch (IOException | InterruptedException e) {
// can't tell at this point whether the message was sent or not - just give up and log
System.err.println("Exception in _sendMessage");
e.printStackTrace(System.err);
LOGGER.error("Exception in _sendMessage", e);
delay = DEFAULT_DELAY;
} finally {
_scheduleNext(delay);
Expand All @@ -136,7 +140,7 @@ private long _delayFromHeaderValue(Optional<String> retryValue) {
}

@Override
public void sendMessage(String message) {
public void sendMessage(MinecraftServerEvent event, String message) {
LOGGER.debug("sendMessage({})", message.trim());
//noinspection ResultOfMethodCallIgnored
waiting.offer(message.trim());
Expand Down
38 changes: 38 additions & 0 deletions app/src/main/java/org/ethelred/minecraft/webhook/JsonSender.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* (C) Edward Harman 2022 */
package org.ethelred.minecraft.webhook;

import io.micronaut.context.annotation.Parameter;
import io.micronaut.context.annotation.Prototype;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.client.BlockingHttpClient;
import io.micronaut.http.client.HttpClient;
import jakarta.inject.Named;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

@Prototype
@Named("json")
public class JsonSender implements Sender {

private static final Logger LOGGER = LogManager.getLogger();

private final BlockingHttpClient client;
private final URI url;

public JsonSender(HttpClient client, @Parameter URL url)
throws URISyntaxException {
this.client = client.toBlocking();
this.url = url.toURI();
}

@Override
public void sendMessage(MinecraftServerEvent event, String message) {
LOGGER.debug("Send message {}", event);
var request = HttpRequest.POST(url, event);
var response = client.exchange(request);
LOGGER.debug(response);
}
}
Loading

0 comments on commit 1fc011d

Please sign in to comment.