Joget DX provides a standard Email Tool plugin for basic email dispatch. However, when enterprise applications need to convert form file attachments (PDFs, images) into Base64 payloads and dispatch responsive HTML email templates through a custom REST API endpoint, a BeanShell script provides full programmatic control.
In this guide, we'll write a Java/BeanShell script that validates file types, reads form attachments using Joget's FileUtil service, converts them to Base64, and dispatches a JSON POST payload to a custom email service API.
How It Works
-
Attachment Discovery: Using
FileUtil.getFile(fileName, formId, recordId), the script locates uploaded files on the Joget server storage path. -
File Validation & Base64 Encoding: The script checks allowed file extensions (
.pdf,.png,.jpg), reads the file bytes, and converts them to Base64 strings. -
HTML Email Formatting: A responsive HTML string is built using
StringBuilderwith embedded CSS styling. -
REST API Dispatch: An
HttpURLConnectiondispatches the JSON payload (recipients, subject, HTML body, Base64 attachments) to the target email API endpoint (#appVariable.send_email_api_url#).
The BeanShell Script
Place this code inside a BeanShell Tool workflow step:
import org.joget.apps.app.service.AppUtil;
import org.joget.commons.util.LogUtil;
import org.joget.apps.app.model.AppDefinition;
import org.joget.apps.form.service.FileUtil;
import java.io.File;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Base64;
import org.json.JSONObject;
import org.json.JSONArray;
// 1. Helper: Validate allowed attachment file types
public boolean isSupportedFileType(String fileName) {
if (fileName == null) return false;
String[] allowedExts = {".pdf", ".png", ".jpg", ".jpeg", ".docx"};
String lower = fileName.toLowerCase();
for (String ext : allowedExts) {
if (lower.endsWith(ext)) return true;
}
return false;
}
// 2. Helper: Encode form attachment into Base64 JSON object
public void appendFileAttachment(JSONArray attachmentArray, String fileName, String formId, String recordId) {
try {
if (!isSupportedFileType(fileName)) {
LogUtil.warn("Email Service", "Skipped unsupported file attachment: " + fileName);
return;
}
File fileObj = FileUtil.getFile(fileName, formId, recordId);
if (fileObj != null && fileObj.exists()) {
byte[] fileBytes = Files.readAllBytes(fileObj.toPath());
String base64Data = Base64.getEncoder().encodeToString(fileBytes);
JSONObject item = new JSONObject();
item.put("name", fileName);
item.put("bytes", base64Data);
attachmentArray.put(item);
LogUtil.info("Email Service", "Successfully encoded attachment: " + fileName);
}
} catch (Exception e) {
LogUtil.error("Email Service", e, "Error encoding file attachment: " + fileName);
}
}
// 3. Prepare Email Payload
JSONArray attachments = new JSONArray();
String formId = "purchase_request";
String recordId = "#form.purchase_request.id#";
String attachmentFileName = "#form.purchase_request.attachment#";
// Add attachment if present
if (attachmentFileName != null && !attachmentFileName.trim().isEmpty()) {
appendFileAttachment(attachments, attachmentFileName, formId, recordId);
}
// 4. Construct Styled HTML Email Body
StringBuilder htmlBody = new StringBuilder();
htmlBody.append("<!DOCTYPE html><html><head><meta charset='UTF-8'>");
htmlBody.append("<style>");
htmlBody.append("body { font-family: Arial, sans-serif; background-color: #f4f6f8; margin: 0; padding: 20px; }");
htmlBody.append(".card { max-width: 600px; background: #ffffff; padding: 30px; border-radius: 8px; border: 1px solid #e1e4e8; margin: auto; }");
htmlBody.append(".header { background: #0056b3; color: #ffffff; padding: 15px 20px; border-radius: 6px 6px 0 0; font-size: 20px; font-weight: bold; }");
htmlBody.append(".content { padding: 20px 0; color: #333333; line-height: 1.6; }");
htmlBody.append(".btn { display: inline-block; background: #0056b3; color: #ffffff; padding: 10px 20px; text-decoration: none; border-radius: 4px; font-weight: bold; margin-top: 15px; }");
htmlBody.append("</style></head><body>");
htmlBody.append("<div class='card'>");
htmlBody.append("<div class='header'>Request Approval Notice</div>");
htmlBody.append("<div class='content'>");
htmlBody.append("<p>Dear Approver,</p>");
htmlBody.append("<p>A new purchase request (<strong>#form.purchase_request.ref_no#</strong>) requires your review.</p>");
htmlBody.append("<p><strong>Requested Amount:</strong> $#form.purchase_request.amount#</p>");
htmlBody.append("<p><strong>Department:</strong> #form.purchase_request.department#</p>");
htmlBody.append("<a href='#appVariable.userview_approval_url#' class='btn'>Open Approval View</a>");
htmlBody.append("</div>");
htmlBody.append("</div></body></html>");
// 5. Dispatch JSON Payload via REST API
String apiUrl = "#appVariable.send_email_api_url#"; // e.g. https://api.your-domain.com/v1/send-email
JSONObject requestJson = new JSONObject();
requestJson.put("to", "#form.purchase_request.approver_email#");
requestJson.put("subject", "Action Required: Request #form.purchase_request.ref_no#");
requestJson.put("htmlBody", htmlBody.toString());
requestJson.put("attachments", attachments);
try {
URL url = new URL(apiUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
conn.setDoOutput(true);
conn.setConnectTimeout(8000);
OutputStream os = conn.getOutputStream();
os.write(requestJson.toString().getBytes(StandardCharsets.UTF_8));
os.flush();
os.close();
int responseCode = conn.getResponseCode();
LogUtil.info("Email Service", "Dispatched email REST request. Response Code: " + responseCode);
} catch (Exception e) {
LogUtil.error("Email Service", e, "Failed to dispatch REST email API request");
}
Key Benefits
-
File Attachment Support: Automatically converts server-stored form files (
FileUtil.getFile()) into Base64 strings for external API delivery. - Custom HTML Email Branding: Delivers clean inline CSS styling across desktop and mobile email clients.
Top comments (0)