Elements version 3.8+
EmailService is a first-class platform service for sending transactional email via SMTP. It is available to platform code through normal Guice injection and to plugin developers through the built-in email-element ELM.
Interface #
package dev.getelements.elements.sdk.service.email;
public interface EmailService {
void send(String from, String to, String subject, String body, boolean html);
}
| Parameter | Description |
|---|---|
from | Sender address. Pass null or blank to use the configured DEFAULT_FROM. |
to | Recipient address. |
subject | Subject line. |
body | Message body – plain text or HTML depending on the html flag. |
html | true -> text/html false -> text/plain |
Throws InvalidDataException if SMTP is not configured (i.e. SMTP_HOST is blank).
Platform configuration #
Configure the platform-level SMTP connection via system defines (JVM properties or environment variables). These apply to the entire server and to any code running outside an element context.
| Constant key | Default | Description |
|---|---|---|
dev.getelements.elements.email.smtp.host | (blank – disabled) | SMTP hostname. Leave blank to disable email at the platform level. |
dev.getelements.elements.email.smtp.port | 587 | SMTP port. |
dev.getelements.elements.email.smtp.starttls | true | Enable STARTTLS. |
dev.getelements.elements.email.smtp.user | (blank) | SMTP username. |
dev.getelements.elements.email.smtp.password | (blank) | SMTP password. |
dev.getelements.elements.email.default.from | (blank) | Default sender address used when from is null. |
Example (passing as JVM system properties on startup):
-Ddev.getelements.elements.email.smtp.host=smtp.sendgrid.net
-Ddev.getelements.elements.email.smtp.port=587
-Ddev.getelements.elements.email.smtp.starttls=true
-Ddev.getelements.elements.email.smtp.user=apikey
-Ddev.getelements.elements.email.smtp.password=SG.xxxxx
-Ddev.getelements.elements.email.default.from=noreply@mygame.com
Using EmailService in platform code #
Once SMTP is configured, inject EmailService anywhere in the platform service layer:
import dev.getelements.elements.sdk.service.email.EmailService;
import jakarta.inject.Inject;
public class MyPlatformService {
private EmailService emailService;
public void notifyUser(String userEmail, String message) {
emailService.send(null, userEmail, "Notification", message, false);
}
@Inject
public void setEmailService(EmailService emailService) {
this.emailService = emailService;
}
}
For UNSCOPED platform code inject with @Named(Constants.UNSCOPED):
@Inject @Named(Constants.UNSCOPED)
public void setEmailService(EmailService emailService) { ... }
Using EmailService inside a custom Element #
Elements access EmailService through the email-element built-in ELM. It provides an element-scoped SMTP connection configured independently from the platform, so different game Elements can each use a different mail provider or sender identity.
Step 1 – declare email-element as a dependency #
In your Element deployment’s Additional Elements configuration, add email-element (using the deployed artifact ID). When the platform loads your element, email-element is loaded first as a dependency and its EmailService binding is available to your element’s Guice child injector.
Alternatively, if you manage deployments via the API:
{
"elements": [
{ "groupId": "dev.getelements.elements", "artifactId": "email-element" }
]
}
Step 2 – configure SMTP attributes on the deployment #
Set the SMTP attributes on your element’s deployment record. These are resolved from the element’s Attributes at load time and override the platform defaults.
| Attribute key | Required |
|---|---|
dev.getelements.elements.email.smtp.host | Yes (leave blank to disable) |
dev.getelements.elements.email.smtp.port | No (default: 587) |
dev.getelements.elements.email.smtp.starttls | No (default: true) |
dev.getelements.elements.email.smtp.user | Yes (for authenticated SMTP) |
dev.getelements.elements.email.smtp.password | Yes (for authenticated SMTP) |
dev.getelements.elements.email.default.from | Recommended |
Via the REST API:
PUT /api/rest/element/deployment/{id}
Content-Type: application/json
{
"pathAttributes": {
"dev.getelements.elements.email.smtp.host": "smtp.mailgun.org",
"dev.getelements.elements.email.smtp.port": "587",
"dev.getelements.elements.email.smtp.starttls": "true",
"dev.getelements.elements.email.smtp.user": "postmaster@mg.mygame.com",
"dev.getelements.elements.email.smtp.password": "key-xxxxx",
"dev.getelements.elements.email.default.from": "noreply@mygame.com"
}
}
Step 3 – inject and use EmailService in your element #
import dev.getelements.elements.sdk.service.email.EmailService;
import jakarta.inject.Inject;
public class WelcomeEmailService {
private EmailService emailService;
public void sendWelcome(String toAddress, String displayName) {
final var body = "<h2>Welcome, " + displayName + "!</h2>"
+ "<p>Thanks for joining. Good luck out there.</p>";
emailService.send(null, toAddress, "Welcome to the game!", body, true);
}
@Inject
public void setEmailService(EmailService emailService) {
this.emailService = emailService;
}
}
Register this service in your element’s @GuiceElementModule:
public class MyGameElementModule extends AbstractModule {
@Override
protected void configure() {
bind(WelcomeEmailService.class);
// EmailService and MailSessionProvider are provided by email-element
}
}
Graceful degradation #
If SMTP_HOST is blank the MailSessionProvider logs a warning and returns null. Any call to EmailService.send() then throws InvalidDataException with the message "Email service is not configured (SMTP_HOST is blank)." – no NPE, no silent failure.
This means you can deploy your element and configure SMTP later without crashing the server on startup.
Overriding the mail transport (advanced) #
To use a custom transport (e.g. a cloud-native SDK instead of SMTP), rebind MailSessionProvider in your element module:
public class MyGameElementModule extends AbstractModule {
@Override
protected void configure() {
bind(MailSessionProvider.class).to(MyCustomMailSessionProvider.class);
bind(EmailService.class).to(DefaultEmailService.class);
}
}
MailSessionProvider extends jakarta.inject.Provider<jakarta.mail.Session>. Return a Session configured with a custom Transport implementation registered via the standard Jakarta Mail Provider SPI.

