TOOT_DAYS = List.of(0, 2, 7, 28);
+
+ @Location("invites/toot_invitation.txt")
+ Template tplToot;
+
+ void tootIfDue(InviteConfig config, EventDto event, int daysUntilEvent) {
+ if (!TOOT_DAYS.contains(daysUntilEvent)) {
+ return;
+ }
+ if (config.getMastoUrl() == null || config.getMastoToken() == null) {
+ return;
+ }
+
+ Log.infof("Preparing toot for event %s in %d days (tenant: %s)", event.uid, daysUntilEvent, config.getTenantId());
+
+ String day = daysUntilEvent == 0 ? "!!!HEUTE!!! " : event.startDate();
+ String statusText = tplToot
+ .data("event", event)
+ .data("day", day)
+ .render();
+
+ MastodonClient client = RestClientBuilder.newBuilder()
+ .baseUri(URI.create(config.getMastoUrl()))
+ .build(MastodonClient.class);
+
+ try (var response = client.createStatus("Bearer " + config.getMastoToken(), statusText.trim(), "public")) {
+ Log.infof("Tooted for event %s (status: %d)", event.uid, response.getStatus());
+ }
+ }
+}
diff --git a/src/main/java/eu/ijug/events/invitation/MastodonClient.java b/src/main/java/eu/ijug/events/invitation/MastodonClient.java
new file mode 100644
index 0000000..564d523
--- /dev/null
+++ b/src/main/java/eu/ijug/events/invitation/MastodonClient.java
@@ -0,0 +1,23 @@
+package eu.ijug.events.invitation;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.FormParam;
+import jakarta.ws.rs.HeaderParam;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
+
+@RegisterRestClient(configKey = "mastodon")
+@Path("/api/v1/statuses")
+public interface MastodonClient {
+
+ @POST
+ @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+ Response createStatus(
+ @HeaderParam("Authorization") String authorization,
+ @FormParam("status") String status,
+ @FormParam("visibility") String visibility
+ );
+}
diff --git a/src/main/resources/db/migration/V6__tenant_invite_config.sql b/src/main/resources/db/migration/V6__tenant_invite_config.sql
new file mode 100644
index 0000000..599f0ac
--- /dev/null
+++ b/src/main/resources/db/migration/V6__tenant_invite_config.sql
@@ -0,0 +1,8 @@
+CREATE TABLE invite_config
+(
+ tenant_id VARCHAR(255) NOT NULL,
+ mail_to VARCHAR(255),
+ masto_url VARCHAR(255),
+ masto_token VARCHAR(255),
+ CONSTRAINT pk_invite_config PRIMARY KEY (tenant_id)
+);
diff --git a/src/main/resources/templates/invites/mail_announcement.html b/src/main/resources/templates/invites/mail_announcement.html
new file mode 100644
index 0000000..6a9d271
--- /dev/null
+++ b/src/main/resources/templates/invites/mail_announcement.html
@@ -0,0 +1,24 @@
+Wir möchten Euch heute folgende Veranstaltung ankündigen:
+ {event.summary}
+
+ Wann: {event.startDate} ab {event.startTime} Uhr
+ Wo: {event.location}
+
+
+ Die Anmeldung ist jetzt ebenfalls geöffnet!
+
+
+ Alle weiteren Infos zum Talk, wie z.B. Abstract, Speaker-Info und Anmeldung, gibt's wie immer auf unserer Website:
+ {event.url}
+
+
+ Alle unsere Veranstaltungen bequem per iCal abonnieren: hier klicken
+
+
+ Wir freuen uns auf Euer zahlreiches Kommen!
+ Viele Grüße,
+ Euer JUG DA Orga-Team
+
+
+ Eine Veranstaltung des iJUG e.V., organisiert durch die JUG Darmstadt.
+
diff --git a/src/main/resources/templates/invites/mail_invitation.html b/src/main/resources/templates/invites/mail_invitation.html
new file mode 100644
index 0000000..ac6067b
--- /dev/null
+++ b/src/main/resources/templates/invites/mail_invitation.html
@@ -0,0 +1,18 @@
+Am kommenden {event.startDate} findet ab {event.startTime} Uhr unser nächster Talk statt:
+ {event.summary}
+Ort: {event.location}
+
+ Alle weiteren Infos zum Talk, wie z.B. Abstract, Speaker-Info und Anmeldung, gibt's wie immer auf unserer Website:
+ {event.url}
+
+
+ Alle unsere Veranstaltungen bequem per iCal abonnieren: hier klicken
+
+
+ Wir freuen uns auf Euer zahlreiches Kommen!
+ Viele Grüße,
+ Euer JUG DA Orga-Team
+
+
+ Eine Veranstaltung des iJUG e.V., organisiert durch die JUG Darmstadt.
+
diff --git a/src/main/resources/templates/invites/toot_invitation.txt b/src/main/resources/templates/invites/toot_invitation.txt
new file mode 100644
index 0000000..724f60f
--- /dev/null
+++ b/src/main/resources/templates/invites/toot_invitation.txt
@@ -0,0 +1 @@
+{day}: {event.title}{#if event.speaker} ({event.speaker}){/if} {event.url}