How to Compress Airtable Attachments with TinyPNG
Here's a custom script/extension to compress Airtable attachments with TinyPNG.
I love Airtable. I love TinyPNG.
I also love not spending money unless I have to, ha!
So I wrote a lil script to compress Airtable attachments using TinyPNG.
This way, Airtable with work directly with TinyPNG to compress images – no middleman service needed!
How the Airtable TinyPNG Script Works
Real quick, here's how this will work once implemented.
- You have a column with attachments
- Either by clicking "Run" or through an automation, Airtable will send the images to TinyPNG
- TinyPNG does its thing and sends the image back
- The script replaces the existing image with the compressed one! Or you have it save to a different column.
What You Need to Connect Airtable to TinyPNG
- TinyPNG account to use the API (free tier comes with 500 compressions!)
- Airtable paid tier to use custom extensions
The Airtable TinyPNG Compression Script
This script now will compress fields that have multiple images in it.
// Modify these to your own values.
let tinyPngApiKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
let airtableAttachmentSource = 'My Image';
let airtableAttachmentDestination = 'My Image';
let airtableColumnToLog = 'Title';
// Don't change these unless you know what you're doing.
let table = base.getTable(cursor.activeTableId);
let view = table.getView(cursor.activeViewId);
let queryResult = await view.selectRecordsAsync();
for (let record of queryResult.records) {
let attachments = record.getCellValue(airtableAttachmentSource);
let compressedImageUrls = [];
if (attachments && attachments.length > 0) {
// Iterate through each attachment in the field.
for (let [i, attachment] of attachments.entries()) {
let recordAttachmentUrl = attachment['url'];
console.log(`Compressing ${record.getCellValue(airtableColumnToLog)} (Image ${i + 1})`);
let request = await remoteFetchAsync('https://api.tinify.com/shrink', {
body: JSON.stringify({'source': {'url': recordAttachmentUrl}}),
headers: {
Authorization: 'Basic ' + btoa('api:' + tinyPngApiKey),
'Content-Type': 'application/json'
},
method: 'POST'
})
const json = await request.json();
// Checks that the API didn't fail.
if (request.status == 201) {
let percentReduced = Math.round((1 - json.output.ratio) * 100);
let kbReduced = (json.input.size - json.output.size) / 1024;
console.log('Panda just saved you ' + percentReduced + '% (' + Math.round(kbReduced) + 'KB).');
// Add the compressed image URL to the array.
compressedImageUrls.push({ url: json['output']['url'] });
}
}
// Update the record with all the compressed image URLs.
await table.updateRecordAsync(record.id, {
[airtableAttachmentDestination]: compressedImageUrls,
});
}
}
How to Use the Script
Let's go over how to add the script to Airtable to start compressing images using TinyPNG.
Add it to Airtable
Go to the Airtable you want to use this on
Add a new extension.
Click "Scripting".
Paste in the script from above
Modify the Values
You need to modify the first several lines of the script.
For this line, replace the x's with the API key from your TinyPNG account.
let tinyPngApiKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
For this line, replace My Image with whatever your column is called that has the images you want compressed.
let airtableAttachmentSource = 'My Image';
And then in this line replace My Image with wherever you want the compressed image to go. It can be the same as where it got it from or a different field.
let airtableAttachmentDestination = 'My Image';
Lastly, the script will log whatever it's working on so you can see what it's up to. Replace Title with whatever column name you want it show in the log. It'll say "Compressing {field name}" in the log.
let airtableColumnToLog = 'Title';
Run
Once you're done editing the code you can click "Run". It'll work it's way through whatever records are visible in your current view.
This screenshot shows it compressing a record of mine. Notice the "Test Record" is the log field I was mentioning before. Just helpful to see what it's up to.
That's it! Now you can compress Airtable images with TinyPNG (without a middleman!).