Embedding Files from Salesforce
Revision as of 05:06, 3 September 2024 by Admin (talk | contribs) (Created page with "== Intro == 3B Docs allows you to pull Salesforce files and then embed them on a document. This article shows a few examples of how to do this == Option 1 == Using sforce (globally available variable), you can create a value formatter as follows:<syntaxhighlight lang="javascript" line="1"> async (args) => { console.log('+++++', args, sforce) const getFile = function({versionId}){ return new Promise(async (resolve, reject) => { const results...")
Intro
3B Docs allows you to pull Salesforce files and then embed them on a document. This article shows a few examples of how to do this
Option 1
Using sforce (globally available variable), you can create a value formatter as follows:
async (args) => {
console.log('+++++', args, sforce)
const getFile = function({versionId}){
return new Promise(async (resolve, reject) => {
const results = sforce.connection.query(`SELECT Id, VersionData, FileType, PathOnClient FROM ContentVersion WHERE Id = '${versionId}' LIMIT 1`);
console.info('sforce res', results)
resolve(results?.records);
});
}
const b64DecodeUnicode = function(str) {
// Going backwards: from bytestream, to percent-encoding, to original string.
return decodeURIComponent(atob(str).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
}
const record = await getFile({versionId: args.value}).catch(err => {
console.error('value formatter error', err);
});
if(!record){
return 'Missing File';
}else if(!['jpg', 'png', 'jpeg'].includes(record.FileType.toLowerCase())){
return 'Unsupported file format: ' + record.FileType;
}
return `
<img src="data:image/png;base64,${record.VersionData}" width="100%" height="100%">
`
}
Assuming that the value formatter is called VersionDataToImage, here's an example on how to apply the formatter correctly:
#{ContentDocumentLink.Id:ContentDocument.LatestPublishedVersion.Id>VersionDataToImage}
The above assumes that the context record has a child ContentDocumentLink (all non-setup objects have that connection).
Option 2
Using rest API calls, you can include the sessionId from the window.globals.sessionId param like so
async (args) => {
const image = await fetch('/services/data/v46.0/sobjects/ContentVersion/0686e00000eQWhlAAG',{
headers: {
'Content-Type': 'application/octet-stream',
'Authorization': `Bearer ${globals.sessionId}`}
}
)
console.log('Img', image);
...
return '';
}
Option 3
Using args.callout to call ApexClass (e.g. using the built in Records Management controller)
await (args) => {
args.callout('b3d.RemoteRecordsManager', {
endp: "getRecords",
objectName: 'ContentVersion',
getAllFields: false,
additionalFields: ['VersionData'],
queryFilter: `Id = '${args.value}'`
}).then(response => {
console.log('RemoteRecordsManager getRecords resp', response)
}).catch(err => {
console.error('RemoteRecordsManager getRecords error', err)
})
////....
}