Embedding Files from Salesforce

Revision as of 06: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...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

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)
    })
    ////....
}