Liz Fedak • Jan 20, 2022New Paragraph
In a quest to make a custom widget using 12k-15k records in an Airtable collection as fast as possible and as easy to use as possible, I wrote out a script that uploads images to Duda and sends the Duda image URL back to the base, so it can be used directly in the collection on your website without dealing with the process of uploading the image to Duda yourself and manually grabbing the URL. Please note this ONLY works for image files with the content upload API endpoint.
Here's some code you can use if you're tech savvy.
In your Airtable base, add a new column and use the 'button' field type. Connect it to the scripting app and create a new dashboard for your code. Add this script below. On line 3, replace the word Attachments with the name of your image column where you're uploading images to Airtable. The rest of the code is getting the current base, getting the details for the record in the particular row where you click the button, and grabbing the URL of the image itself and not extra details, like the name of the image.
Then it calls a serverless function that handles the calls to Duda and sends the response back to Airtable. I recommend using Google Cloud Functions for your serverless function because you can up the timeout time if you need to. The upload resource endpoint takes a while because it is making a bunch of versions of the image over at Duda and doesn't send the final image URL back until it's done.
let table = base.getTable("Table 1");
let record = await input.recordAsync('',table).catch()
const imgUrl = record.getCellValue("Attachments")[0].url;
const obj = {}
obj.imgUrl = imgUrl;
obj.id = record.id;
let data = JSON.stringify(obj);
const options = {
method: 'POST',
body: data,
headers: {
'Content-Type': 'application/json'
}
}
let response = await remoteFetchAsync('{YOUR SERVERLESS FUNCTION ENDPOINT}', options);
/**
* Responds to any HTTP request.
*
* @param {!express:Request} req HTTP request context.
* @param {!express:Response} res HTTP response context.
*/
const fetch = require('node-fetch');
exports.uploadToDuda = (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
res.set('Content-Type', 'application/json');
res.set('Access-Control-Allow-Methods', 'GET, POST');
res.set('Access-Control-Allow-Headers', 'Content-Type');
if (req.method === 'OPTIONS') {
// Send response to OPTIONS requests
res.set('Access-Control-Allow-Origin', '*');
res.set('Access-Control-Allow-Methods', 'GET, POST');
res.set('Access-Control-Allow-Headers', 'Content-Type');
res.set('Content-Type', 'application/json');
res.set('Access-Control-Max-Age', '3600');
res.status(204).send('');
} else {
let id = req.body.id;
let img = req.body.imgUrl;
let obj = {resource_type: 'IMAGE', src: ''}
obj.src = img;
let arr = [];
arr.push(obj);
fetch('https://api.duda.co/api/sites/multiscreen/resources/{YOUR SITE ID}/upload', {
method: 'POST',
body: JSON.stringify(arr),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': process.env.DUDA_AUTH
},
})
.then(res => res.json())
.then(function(data) {
let newImgURL = data.uploaded_resources[0].new_url;
let responseObj = {
records: [
{
"id": "",
"fields": {
"dudaImg": ""
}
}
]
}
responseObj.records[0].id = id;
responseObj.records[0].fields.dudaImg = newImgURL;
let responseJson = JSON.stringify(responseObj);
let airtableOptions = {
method: 'PATCH',
headers: {
'Authorization': process.env.AIRTABLE_AUTH,
'Content-Type': 'application/json'
},
body: responseJson
}
fetch("{YOUR AIRTABLE BASE URL}", airtableOptions)
})
.catch(err => console.log(err))
.then(res.status(200).send("Complete"))
}
};
This code is going to read the request object from Airtable, get the image URL, upload it to Duda, wait for the NEW URL, then send that back to Duda.
In the GCP function, be sure to set the
allUsers permission with the
Cloud Function Invoker permission and to set HTTP as the trigger. That's about it! Once the new URL is added to your Airtable base, you can delete that old image in the base to save storage space, or simply leave both there.
Can I use this to upload many images at once? Yes, you will need to write new code that generates the array for multiple images though and gets all of the source URLs. Duda can take up to 10 images at a time with this endpoint. You'll need to make an array of arrays of images and go through each one if there are more than 10 images in a record to be uploaded with a script.
My image didn't upload. Make sure you're using an image with a .jpeg or .png ending. If it's something you added via an Airtable search, it works like 5% of the time. The Duda documentation specifies that you are required to use a valid image URL, so don't use the .attachment Airtable format unless you want to have frequent failure of the function call. Import a real image file.
Can you set this up for me? Yep! Reach out for rates/availability. Widget Pro is also able to host your Airtable base in our Airtable Pro account and can configure your GCP function and manage it for a nominal monthly fee, or we can do a training session to get your GCP account setup if you're new to Google Cloud. Your Airtable workspace will need to be a paid Pro plan.
Can another developer set this up for me? Yep! You can find more
Duda Experts in the
Duda Community on the Duda Experts page. Widget Pro is a
certified Duda Expert, but there are a growing number of other experts available in the directory. Just send them this tutorial and they should be able to make it work to your base and with their preferred serverless function platform.
Let's get the ball rolling.
Send us a message and we'll be in touch very soon. Let's build something awesome together!