import * as wmill from "windmill-client"
import { S3Object } from "windmill-client"
/**
* Upload File
* Upload a file from Windmill object storage to Salesforce as a ContentVersion (Salesforce Files), optionally linking it to a record.
*/
export async function main(
auth: RT.Salesforce,
file: S3Object,
title: string,
linked_record_id: string | undefined
) {
const apiVersion = auth.api_version || "v60.0"
// Load the file bytes from Windmill's object storage and base64-encode for VersionData.
const bytes = await wmill.loadS3File(file)
if (!bytes) {
throw new Error("Could not load the file from object storage")
}
const versionData = Buffer.from(bytes).toString("base64")
// 1. Create the ContentVersion (the uploaded file).
const cvResponse = await fetch(
`${auth.instance_url}/services/data/${apiVersion}/sobjects/ContentVersion`,
{
method: "POST",
headers: {
Authorization: `Bearer ${auth.token}`,
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({
Title: title,
PathOnClient: title,
VersionData: versionData,
}),
}
)
if (!cvResponse.ok) {
throw new Error(`${cvResponse.status} ${await cvResponse.text()}`)
}
const contentVersion = (await cvResponse.json()) as { id: string }
if (linked_record_id === undefined || linked_record_id === "") {
return contentVersion
}
// 2. Resolve the ContentDocumentId of the new version.
const queryUrl = new URL(
`${auth.instance_url}/services/data/${apiVersion}/query`
)
queryUrl.searchParams.append(
"q",
`SELECT ContentDocumentId FROM ContentVersion WHERE Id = '${contentVersion.id}'`
)
const queryResponse = await fetch(queryUrl, {
headers: {
Authorization: `Bearer ${auth.token}`,
Accept: "application/json",
},
})
if (!queryResponse.ok) {
throw new Error(`${queryResponse.status} ${await queryResponse.text()}`)
}
const contentDocumentId = (
(await queryResponse.json()) as {
records: { ContentDocumentId: string }[]
}
).records[0].ContentDocumentId
// 3. Link the file to the target record.
const linkResponse = await fetch(
`${auth.instance_url}/services/data/${apiVersion}/sobjects/ContentDocumentLink`,
{
method: "POST",
headers: {
Authorization: `Bearer ${auth.token}`,
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({
ContentDocumentId: contentDocumentId,
LinkedEntityId: linked_record_id,
ShareType: "V",
}),
}
)
if (!linkResponse.ok) {
throw new Error(`${linkResponse.status} ${await linkResponse.text()}`)
}
return {
contentVersionId: contentVersion.id,
contentDocumentId,
linkedEntityId: linked_record_id,
success: true,
}
}
Submitted by hugo989 9 days ago