[✅ Solution] Uploading a File VIA Automation - Execute Script - File uploads but deletes my existing files

Hi :slightly_smiling_face: I’m trying to upload a PDF without deleting existing files, each time I upload the pdf to my files it deletes my existing files in my app.

The following is my code. What am I doing wrong?

// upload file from url
// 1) download the PDF as raw binary
const url = “https://www.test.com/signed/gqQgCDB3053.pdf”;
const { data: fileContent } = await http.get(url, { responseEncoding: “binary” });

// 2) upload to Tape’s File API
const buffer = Buffer.from(fileContent, “binary”);
const { data: uploaded } = await tape.File.upload({
filename: “tester.pdf”,
source: buffer
});

// 3) attach that file to record
await tape.Record.update(
collected_offer_id,
{
fields: {
files: uploaded.file_id
}
},
{
silent: false,
hook: true,
workflow: true
}
);

I am not at my desk but I am fairly sure you are over writing the field when you do a record.update so you will need to get the file_id’s of the current files then push the new one into an array with the current and then add that array of id’s to your field.

  1. Get current file_id’s
  2. Buid an array with current and new id’s
  3. Update record with the array of new and old ID’s

This would be the same if you you were doing a multi-select field as well.

Hope that helps

3 Likes

Thanks Jason, you’re the best :slightly_smiling_face:

This is the code I wrote to get it working.


// Download PDF
const { data: fileContent } = await http.get("https://www.test.com/signed/gqQgCDB3053.pdf", 
{ responseEncoding: "binary" });

// Upload to Tape’s File API
const { data: uploaded } = await tape.File.upload({
  filename: "tester12.pdf",
  source: Buffer.from(fileContent, "binary")
});

// Get record
const record = await tape.Record.get(collected_offer_id);

// Get existing file IDs from "Files" field
const fileField = record?.data?.fields?.find(f => f.field_id === 594726 || f.external_id === "files");
const currentFileIds = fileField?.values?.map(v => v.value?.file_id).filter(id => id) || [];

// Update record with new and existing file IDs
await tape.Record.update(collected_offer_id, {
  fields: {
    files: [...currentFileIds, uploaded.file_id]
  }
}, {
  silent: false,
  hook: true,
  workflow: true
});

Now that it’s working. I’m wondering if this is the most efficient way to go about?

Thanks

this uses a multi select field as the example but the principle is the same:

const newItem = 'three'

const { data: currentRecord } = await tape.Record.get(current_record_id);
const selection = jsonata(`fields[external_id="multiple_select"].values.value.text[]`).evaluate(currentRecord);
console.info(`Original Selection: ${selection}`);

selection.push(newItem);
console.info(`New Selection: ${selection}`);

const { data: newRecordData } = await tape.Record.update(current_record_id, {
    fields: {
        multiple_select: selection
    }
});

Technically you should be able to merge the new file_id into the current array and extract into a new variable ready for the record update all in one JSONata evaluate but I didn’t think to do it that way when I wrote the above and I am not sure it is worth the brain power to work it out for one line.

Note the [] at the end of the evaluate string this forces JSONata to deliver an array even if there is only one item if you don’t have this in an there is a single file attachment the push will fail as it won’t be an array.

1 Like

Thanks Jason, I appreciate it :+1: