A custom document attachment / retrieval service pair wraps the BPM document store (or ECM) so that every process app attaches and reads documents the same way. Two service flows in a toolkit:
// Service flow "Attach document" (BPM document store) - inputs fileName, mimeType, contentBase64; output docId
var doc = tw.system.createDocument(
tw.local.fileName, tw.local.mimeType, tw.local.contentBase64, true, // name, type, content, isBase64
tw.local.instanceId ? tw.local.instanceId : tw.system.currentProcessInstanceID);
tw.local.docId = doc.id;
// optional metadata: doc.properties / tags depending on the release (BAW 20+: document properties list)
// Service flow "Get document" - input docId; outputs fileName, mimeType, contentBase64
var d = tw.system.findDocumentByID(tw.local.docId); // TWDocument: name, type, size, id; content through the REST resource below
tw.local.fileName = d.name;
// Service flow "Get document" - REST-based retrieval works on every release: the document content URL
tw.local.contentUrl = tw.env.restBaseUrl + "/document/" + tw.local.docId + "/content"; // GET returns the bytes (browser or Java client)
// server-side bytes with BPMRESTRequest
var req = new BPMRESTRequest(); req.method = "GET"; req.resource = "/document/" + tw.local.docId + "/content";
var res = tw.system.invokeREST(req); tw.local.contentBase64 = res.content; // binary content is returned Base64-encoded by invokeREST on recent releases
Design points: keep the service interface neutral (name, type, Base64 content, metadata list) so that the implementation can move from the BPM document store to ECM (tw.system.ecm.createDocument, getDocument) without touching the apps; return ids, not content, wherever possible (claim check); for coaches use the OOB Document List / File Uploader controls, and call these services only for generated documents or system integrations; store metadata (document type, business key) as document properties so that retrieval can search (on ECM: a CMIS query on the property).
References