Handling HL7 Base64 Attachments¶
HL7 ORU messages sometimes carry binary reports (PDF, DOCX, JPG) Base64-encoded into OBX-5. Embedded attachments inflate message size, slow parsing, and bloat the message database. The recommended pattern is to offload the binary payload to external storage, replace OBX-5 with a lightweight reference, and only re-embed the content at the destination if the receiver requires it.
When OBX-2 is ED (Encapsulated Data), the Base64 blob lives in OBX-5.5; the surrounding subfields describe the source application, MIME type, and encoding. Adjust the node paths below if your sender uses a different layout.
If your binary payload is not in an HL7 OBX-5 segment (for example a PDF returned from a REST call or stashed in messageCache) see Writing Binary Files from a Script for the general pattern.
Extract a Base64 attachment from OBX-5 to disk¶
In a mapping node, walk every OBX segment whose OBX-2 is ED (Encapsulated Data). For each one, decode the Base64 payload in OBX-5.5 to bytes, write the bytes to a file, and rewrite OBX-5 so it carries the file path instead of the blob. Naming the file after the message control id makes it easy to match back to the message later.
Changing OBX-2 from ED to RP (Reference Pointer) signals to downstream systems that OBX-5 now contains a pointer rather than embedded data. If your receivers cannot interpret RP, leave OBX-2 set to TX (or whatever the receiver expects) and store any identifier you prefer, a UUID, URL, or document ID. The point is that the message database no longer carries the encoded payload.
var obxCount = source.getCount('OBX');
var msgId = source.getNode('MSH-10');
for (var i = 1; i <= obxCount; i++) {
var obxIndex = '[' + i + ']';
if (source.getNode('OBX' + obxIndex + '-2') == 'ED') {
var mimeType = source.getNode('OBX' + obxIndex + '-5.3');
var base64Data = source.getNode('OBX' + obxIndex + '-5.5');
if (StringUtils.isNotBlank(base64Data)) {
var ext = (mimeType == 'PDF') ? '.pdf' : (mimeType == 'DOCX' ? '.docx' : '.bin');
var path = '/qie-attachments/' + msgId + '-' + i + ext;
var bytes = qie.base64DecodeToBytes(base64Data);
qie.writeFile(path, bytes, true);
message.setNode('OBX' + obxIndex + '-2', 'RP');
message.setNode('OBX' + obxIndex + '-5', path);
}
}
}
Use qie.newNetFile() instead of a local path if attachments need to land on a network share that the QIE service account cannot reach directly.
Embed a file from disk into OBX-5 as Base64¶
Going the other direction (taking a binary file on disk and packaging it into an HL7 OBX segment) is a common requirement when a receiver expects the report content inline. The same pattern works whether the file was just extracted by the previous step or was produced by some other system entirely (a report generator, a network share drop, etc.).
In a mapping node, locate the segments that need to be embedded (here, any OBX already containing a reference path in OBX-5), read the file, Base64-encode the bytes, and rewrite OBX-5 with the encoded payload. Adjust the lookup logic to match how your channel identifies which file to embed: by message id, by node value, by table lookup, and so on.
var obxCount = message.getCount('OBX');
for (var i = 1; i <= obxCount; i++) {
var obxIndex = '[' + i + ']';
if (message.getNode('OBX' + obxIndex + '-2') == 'RP') {
var path = message.getNode('OBX' + obxIndex + '-5');
if (StringUtils.isNotBlank(path)) {
var bytes = qie.readFile(path);
var base64Data = qie.base64EncodeBytes(bytes);
message.setNode('OBX' + obxIndex + '-2', 'ED');
message.setNode('OBX' + obxIndex + '-5.3', 'PDF'); // set MIME type as needed
message.setNode('OBX' + obxIndex + '-5.4', 'Base64');
message.setNode('OBX' + obxIndex + '-5.5', base64Data);
}
}
}
If a destination is happy to receive the reference as-is (a path, URL, or document id), skip the embedding step, the lightweight reference is the final form.
Cleanup
Attachment files written to disk are not managed by QIE. Schedule a separate cleanup job (scheduled script, OS cron, or storage lifecycle policy) to delete or archive files once they are no longer needed by any destination.