Automate changing the file name of an attachment

Hey Airtable Community.

I need help with automating the repetitive task of manually changing the name of a file after it’s been uploaded into my base. As of right now, we have a user filling out a form, and after it’s submitted, I want that to trigger the name changing. I have a field that is automatically created with a formula based on information captured in the form that I want the name changed too.

I’ve been looking at using the Airtable automation feature, but after trying a bunch of things, I can’t get it to work (perhaps I’m just too new at this) I also feel like maybe using a script might be the answer, but I don’t know how to do that, and if that’s the path to get this to work, I’ll need your help too :slight_smile: . Ultimately, I’m not sure and was hoping you (the community) might know.

Thanks in advance everyone!

My guess is that you might be able to update an attachment’s filename with a custom JavaScript, but I’m not 100% sure about this. One of the JavaScript experts would need to chime in on this one.

If not, you could likely use JavaScript to simply re-upload the same attachment into the same field — but with a new filename. Since I’m not a JavaScript expert yet (although I’m working on it!), I don’t have a definitive script on how to do this. I think it would be as easy as grabbing the URL of the original attachment and then simply updating the attachment field with that same exact URL + the brand new file name. I’m sure that one of the JavaScript experts here would be able to come up with a script to do this.

In the meantime, since I don’t know how to do this with a script, my personal way of doing this is using Integromat. I grab the attachment and simply re-upload it to the attachment field again with the new name.

Below is an example screenshot of how to set this up in Integromat. This scenario will work perfectly, regardless of whether you have a single attachment or multiple attachments.

I am an Airtable developer and a registered Integromat partner, so if you need to hire an expert to help you set this up, please feel free to send me a message or contact me through my website at scottworld.com.

(Note that the Integromat link above contains an affiliate link of mine, so I would make a referral fee if you start paying for Integromat.)

Welcome to the community, @Cameron_Goldberg! :smiley: While attachments can be manually renamed, Airtable’s scripting options—in the Scripting app, or in the scripting action in an automation—only allow you to set the filename when first adding an attachment with a script. There’s no option for changing the filename of an existing attachment.

That said, you could use a process similar to what @ScottWorld described: collect the current URL of the attachment, then submit that as a new attachment in the same field with the name you want to use. I just ran a test using an automation, and it works surprisingly well. (NOTE: this will only work for a single attachment, which sounds like it’ll work for your use case; if anyone needs multiple attachments renamed, the setup will require some more detailed tweaking which I don’t have time to explore at the moment.)

I made a new automation using the “When record matches conditions” trigger, with the condition being that the attachment field is not empty. The scripting action requires four input variables from the triggering record:

  • recordID - The record ID
  • filename - The filename property of the attachment field
  • fileURL - The URL property of the attachment field
  • newName - The new name that you wish to assign to the attachment

The code for the scripting action step is below. This finds the existing file extension for the attachment and uses that for the new name, so your new name formula should not include the extension. That way it doesn’t matter what file type someone attaches (.gif, .jpg, .pdf, etc) because the script just uses the current extension, and only changes the rest of the name.

// Setup
let config = input.config()
let table = base.getTable("Table Name")

// Get the extension and add it to the new name.
let parts = config.filename[0].split(".")
let ext = parts[parts.length - 1]
let newName = `${config.newName}.${ext}`

// Reattach the item with the new filename
await table.updateRecordAsync(config.recordID, {
    "Attachment Field Name": [{url: config.fileURL[0], filename: newName}]
})
1 Like

This is so unbelievably helpful, thank you!!

I’m kinda blown away with how great your response once, trying to implement it now, but still new to the world of scripts so it’s taking a bit of trial in error.

With that being said, In my use case, for 80% of what we do, it will be with only one file that would be uploaded via the form, but in some cases roughly 20% of the time, we would have multiple files that would be uploaded in at the same time… is adjusting this script to include 2+ uploaded files an easy (ish) addition?

Glad to help! Tweaking the script to work with multiple files should be fairly easy. The question becomes: how do you want to distinguish between the files? Let’s say that your formula creates the name “myName”. Two files are attached:

someFile.jpg
someOtherFile.jpg

Because they both have the same extension, giving them the same filename “myName.jpg” would cause some confusion. It would be easy enough to resolve this by appending a number to your generated name, which would create the following new names:

myName-01.jpg
myName-02.jpg

Would that work?

Yes, this would work!!

I’m directing my new name field to a formula, it’ll give me the flexibility to work around any future use cases I can currently think of.

Such a great solution!

Here’s the modified script. This one only needs a single input variable: recordID, which is the ID if the triggering record. Everything else is collected by the script. You’ll need to customize the names of the fields that are queried/updated, but that should be pretty straightforward.

// Setup
let config = input.config()
let table = base.getTable("Table Name")
let query = await table.selectRecordsAsync()
let record = query.getRecord(config.recordID)

// Collect record data
let newPrefix = record.getCellValue("Custom name")
let files = record.getCellValue("Attachment")

// Get the extension and add it to the new name
let newFiles = []
for (let file of files) {
    let parts = file.filename.split(".")
    let ext = parts[parts.length - 1]
    let fileNumber = "0" + (files.indexOf(file) + 1)
    let newName = `${newPrefix}-${fileNumber}.${ext}`
    newFiles.push({url: file.url, filename: newName})
}

// Reattach the item with the new filename
await table.updateRecordAsync(record, {
    "Attachment": newFiles
})

Thank you so much for this, might have a few questions/problems when implementing.

Firstly,

On the current script, I’m getting this error message. Do you know what I might be doing wrong? I spent a good 25 min before reaching back out trying different things as I suspect this is easy, but I’m completely missing it…

TypeError: Invalid arguments passed to recordQueryResult.getRecord(recordId):
• recordId should be a string, not undefined
    at main on line 5

Secondly, I’m actually using multiple attachment fields for each file. So, when it comes to naming it 1,2, etc… I’m presuming the current script only points to one attachment field, but I currently use 2 (that might increase in the future to more). I’m sorry I didn’t recognize that before, the scripting world is new to me, so it only really cued in once I was connecting the rest of it.

Did you create an input variable named “recordID” that pulls the ID from the trigger step?

Screen Shot 2020-10-13 at 4.55.26 PM

Not a problem. You can still use the most recent script. Just make one automation per attachment field, with each one triggering off a single field, and making sure to update each script to read and update the appropriate field.

1 Like

I got it working :slight_smile:

Your direction was unbelievably helpful, and allowed me to do something I didn’t think was initially possible.

Thank you so much for your help!!!

1 Like