How to Automate Video Generation with Clipcat and Google APIs (Node.js Tutorial)

Learn how to automate video creation in Node.js using Clipcat and Google APIs. This step-by-step tutorial shows you how to turn data in Google Sheets into personalized videos.
by Josephine Loo ·

Contents

    If you're building something that requires generating videos with a consistent format, such as user testimonials, product highlights, weekly updates, or short explainer videos, this tutorial is for you. In this guide, you'll learn how to automate video generation using Clipcat (a video generation tool) and Google APIs in Node.js.

    Automating video generation not only saves you time on repetitive editing tasks but also helps you maintain brand consistency across large batches of videos by generating them from a reusable template. With a simple setup that connects Clipcat to your media assets and data stored in Google Sheets via Google APIs, you can streamline the whole editing process and generate videos automatically.

    To show you how the whole thing works, we’ll build a simple Node.js script that:

    • Reads user testimonials and photos from a Google Sheets (responses from a Google Form submission)
    • Inserts them into a Clipcat video template
    • Automates the video rendering and output

    …so in the end, you’ll be able to generate videos like these using the script:

    It’s a straightforward workflow, and by the end of it, you’ll have a working Node.js script that you can integrate into form submissions, scheduled scripts, backend services, or anything else you need!

    Prerequisites

    Before we begin, make sure you have the following:

    Preparing the Data

    Google Forms automatically saves all responses in a linked Google Sheet, and any uploaded photos will be stored in a folder in your Google Drive. You can access them using the Google APIs.

    🐱 Meow Memo: However, the images in Google Drive can’t be used directly in Clipcat. So, we’ll need to upload those images to Imgur first and use the Imgur URLs instead  (we’ll show you how to work around this).

    The Google Form collects the user’s name and testimonial, and lets them upload an avatar or profile photo along with an image related to their testimonial:

    a screenshot of a Google Form for collecting user testimonials.png

    You can view all the responses in the linked Google Sheet, which you can access from the “Responses” tab in your Google Form edit page:

    viewing the Google Forms responses in Google Sheets.png

    The image URLs are displayed in the Google Sheet, and the actual image files are stored in a folder in your Google Drive:

    screenshot of the folder where the images are saved in Google Drive.png

    This gives you everything you need to personalize each video with the user’s name, testimonial, and photo.

    Preparing the Clipcat Design Template

    First, sign up for a Clipcat account and create a new project in your account. Then, duplicate the template below to your project by clicking "Use This Template" :

    A Clipcat video template can include multiple graphic or video scenes, each one made up of different objects like text or shapes (rectangles or circles). You can update these scenes and objects directly through Clipcat’s API, and this lets you generate different videos dynamically without touching the editor.

    The template we're using in this tutorial has one video scene, with text objects like name, date, and testimonial, as well as shape objects like avatar, image, and background:

    🐱 Meow Memo: Read this guide to learn more about how to customize a video template in Clipcat.

    Setting Up API Access and Credentials

    Before you can start fetching data or generating videos, you'll need to set up API access and authentication for Google Sheets, Google Drive, Clipcat, and Imgur.

    1. Google Sheets API (via Google Service Account) and ID

    Go to the Google Cloud Console and create a new project (or use an existing one). Then, navigate to IAM & Admin → Service Accounts:

    Google Cloud Console - navigating to Service Account.png

    Click “Create service account” :

    Google Cloud Console - click "Create service account".png

    Fill in the information needed and click “Done” to continue:

    Google Cloud Console - creating a service account.png

    Then, go to the Keys tab and click “Add key” → “Create new key” :

    Google Cloud Console - creating a private key for the service account.png

    Select JSON as the key type and click “Create” to complete:

    Google Cloud Console - creating a private key for the service account - choosing JSON as the key type.png

    A JSON file will be downloaded automatically, and we will need it in our script later to access the Google API.

    Next, enable the Google Sheets API in the API Library:

    Google Cloud Console - enable Google Sheets API.png

    You’ll also need your Google Sheets ID, which you can find in the URL between d/ and /edit:

    a screenshot of how to get the ID of the Google Sheet.png

    Make sure to also:

    • Share your Google Sheet: Click “Share” , add your service account email, and grant Editor access
    • Set your Google Drive image folder’s sharing settings to “Anyone with the link” so the images can be accessed by the script.

    2. Clipcat API Key and Template ID

    To use the Clipcat API, you need the Clipcat API key and the template ID. For the API key, click on your profile icon on the top right corner, and click “API Keys” :

    How to Automate Video Generation with Clipcat and Google API - getting the Clipcat API key.png

    To get the template ID, click the three dots at the top right corner of your template:

    How to Automate Video Generation with Clipcat and Google API - getting the Clipcat template ID.png

    3. Imgur API (for Hosting Uploaded Images)

    Log in to your Imgur account and register a new application. Fill in the application name, email, select “OAuth 2 authorization without a callback URL” for the authorization type, and click “Submit” to proceed.

    Imgur - register an application.png

    You’ll get your Client ID and Client Secret, which you’ll use to authorize your API calls:

    Imgur - client ID and secret.png

    Writing the Node.js Script

    Now that everything’s in place, let’s write the automation script in Node.js.

    Step 1. Set Up Your Environment

    Open your terminal/command prompt and run the following commands to create a new folder and Node.js project:

    mkdir clipcat-video-generator
    cd clipcat-video-generator
    npm init
    

    Next, run the command below to install the required packages:

    npm install googleapis google-auth-library axios form-data dotenv
    

    Then, create a .js file (e.g., script.js) and import the packages like this:

    require('dotenv').config();
    const { google } = require('googleapis');
    const fs = require('fs');
    const axios = require('axios');
    const path = require('path');
    const FormData = require('form-data');
    

    Let’s set up the API keys and config. Create a .env file in your project folder and add your keys and IDs:

    GOOGLE_PRIVATE_KEY=your-json-file-name
    GOOGLE_SHEET_ID=your-google-sheets-id
    GOOGLE_SHEET_NAME=your-google-sheets-name
    CLIPCAT_API_KEY=your-clipcat-api-key
    CLIPCAT_TEMPLATE_ID=your-clipcat-template_id
    IMGUR_CLIENT_ID=your-imgur-client-id
    

    In your script.js file, set up authentication for Google Sheets using your private key file, and declare the Clipcat and Imgur API keys as constants:

    const sheets = google.sheets('v4');
    const auth = new google.auth.GoogleAuth({
      keyFile: process.env.GOOGLE_PRIVATE_KEY,
      scopes: ['https://www.googleapis.com/auth/spreadsheets.readonly'],
    });
    
    const IMGUR_CLIENT_ID = process.env.IMGUR_CLIENT_ID;
    const CLIPCAT_API_KEY = process.env.CLIPCAT_API_KEY;
    

    🐱 Meow Memo: Don’t forget to put your Google Cloud service account JSON file in the root folder of your project too.

    Step 2. Writing Helper Functions

    Before we jump into the main logic, let’s set up a few helper functions that’ll make our code cleaner and easier to manage later.

    Since each testimonial comes with two images (an avatar and a screenshot), we’ll need a consistent way to name and save the image files locally. Add this function to your script.js to generate the local .jpg file path based on the image’s file ID:

    function getLocalImagePath(fileId) {
      return path.join(__dirname, `${fileId}.jpg`);
    }
    

    We’ll be updating the Clipcat video template with responses from the Google Form. For the video’s background colour, instead of using a fixed colour, we can randomly generate one each time to keep things fresh:

    function getRandomHexColor() {
      const hex = Math.floor(Math.random() * 0xffffff).toString(16);
      return '#' + hex.padStart(6, '0');
    }
    

    Step 3. Read Form Responses from Google Sheets

    To read data from your Google Sheet, add the function below. This will fetch all the rows and return the results but excluding the first row, since that one contains the field names:

    async function readSheet() {
      const client = await auth.getClient();
      const spreadsheetId = process.env.GOOGLE_SHEET_ID;
      const range = process.env.GOOGLE_SHEET_NAME;
    
      const res = await sheets.spreadsheets.values.get({
        auth: client,
        spreadsheetId,
        range,
      });
    
      return res.data.values.slice(1); // skip first row
    }
    

    🐱 Meow Memo: Make sure the sheet is shared with the service account.

    Step 4. Download Image from Google Drive

    The image links in our sheet are stored in Google Drive, but to use them with the Clipcat API, we first need to download them and then upload them elsewhere. This function takes a Google Drive file ID, downloads it using a public link pattern, and saves it locally:

    async function downloadImage(fileId, localImagePath) {
      const driveUrl = `https://drive.google.com/uc?id=${fileId}`;
      console.log(`Downloading image from Google Drive ID: ${fileId}`);
      try {
        const res = await axios.get(driveUrl, {
          responseType: 'stream',
          headers: { 'User-Agent': 'Mozilla/5.0' },
        });
    
        const writer = fs.createWriteStream(localImagePath);
        res.data.pipe(writer);
    
        return new Promise((resolve, reject) => {
          writer.on('finish', () => {
            console.log('Image downloaded');
            resolve();
          });
          writer.on('error', reject);
        });
      } catch (err) {
        console.error('Failed to download image:', err.message);
        throw err;
      }
    }
    

    Step 5. Upload Image to Imgur

    Google Drive image links aren’t directly usable for embedding, so we upload each image to Imgur, which gives us a public image URL. This function uses Imgur’s API to upload a file and returns the image URL:

    async function uploadToImgur(localImagePath) {
      console.log('Uploading to Imgur...');
      const form = new FormData();
      form.append('image', fs.createReadStream(localImagePath));
    
      try {
        const res = await axios.post('https://api.imgur.com/3/image', form, {
          headers: {
            ...form.getHeaders(),
            Authorization: `Client-ID ${IMGUR_CLIENT_ID}`,
          },
        });
    
        const imgUrl = res.data.data.link;
        console.log('Uploaded to Imgur:', imgUrl);
        return imgUrl;
      } catch (err) {
        console.error('Failed to upload to Imgur:', err.response?.data || err.message);
        throw err;
      }
    }
    

    Step 6. Generate Video with Clipcat

    With the testimonial text and image URLs ready, we can call the Clipcat API to generate the video. This function takes the testimonial data and sends it to Clipcat’s rendering API, using the template you’ve set up beforehand:

    async function generateVideo(entry, avatarUrl, screenshotUrl) {
      const data = {
        template: process.env.CLIPCAT_TEMPLATE_ID,
        modifications: [
          {
            scene: 'Scene 1',
            text: entry[0].split(' ')[0],
            object: 'date',
          },
          {
            scene: 'Scene 1',
            text: entry[1],
            object: 'name',
          },
          {
            scene: 'Scene 1',
            object: 'testimonial',
            text: entry[2],
          },
          {
            scene: 'Scene 1',
            'background-image': avatarUrl,
            object: 'avatar',
          },
          {
            scene: 'Scene 1',
            'background-image': screenshotUrl,
            object: 'image',
          },
          {
            scene: 'Scene 1',
            object: 'background',
            'background-color': getRandomHexColor(),
          },
        ],
      };
    
      try {
        const res = await axios.post('https://api.clipcat.com/v1/renders', data, {
          headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${CLIPCAT_API_KEY}`,
          },
        });
    
        console.log('Video render started. Render ID:', res.data.id);
      } catch (err) {
        console.error('Failed to generate video:', err.response?.data || err.message);
      }
    }
    

    Step 7. Putting It All Together

    Here’s where everything comes together. We’ll read all rows from the sheet and for each row, extract the data, public image URLs (so Clipcat can access them), call the Clipcat API to generate the video, and finally, clean up the downloaded image files from our local folder once everything’s done:

    (async () => {
      try {
        const entries = await readSheet();
    
        for (const entry of entries) {
          const avatarFileId = entry[3].split('?id=')[1];
          const screenshotFileId = entry[4].split('?id=')[1];
          const localAvatarPath = getLocalImagePath(avatarFileId);
          const localScreenshotPath = getLocalImagePath(screenshotFileId);
          await downloadImage(avatarFileId, localAvatarPath);
          await downloadImage(screenshotFileId, localScreenshotPath);
    
          const avatarUrl = await uploadToImgur(localAvatarPath);
          const screenshotUrl = await uploadToImgur(localScreenshotPath);
          await generateVideo(entry, avatarUrl, screenshotUrl);
    
          fs.unlinkSync(getLocalImagePath(screenshotFileId));
          fs.unlinkSync(getLocalImagePath(avatarFileId));
        }
    
        console.log('All videos processed');
      } catch (err) {
        console.error('Process failed:', err.message);
      }
    })();
    

    Run the command below in your terminal/command prompt to execute the script:

    node index.js
    

    Each row in your spreadsheet will trigger a video render using the Clipcat template. You can check progress on your Clipcat dashboard:

    generating Clipcat video - checking the progess in the dashboard.png

    Here’s the result:

    🐱 Meow Memo: View the full code on GitHub.

    Conclusion

    With this setup and script, you can dynamically create personalized videos using data and media collected through a Google Form or any data stored in Google Sheets. The entire process, from data collection to video rendering, is handled automatically. It is flexible, scalable, and works for many other use cases, such as:

    • Marketing campaigns: Auto-generate promo videos based on campaign briefs or social media captions stored in Google Sheets.
    • Educational content: Turn key points into short animated summary videos.
    • Onboarding videos: Create personalised welcome videos for new hires using their submitted details.
    • Product updates: Use data from your Sheets to build short product highlight videos with pricing and features.
    • Newsletters & reports: Quickly turn weekly updates or performance summaries into bite-sized video digests.

    No matter what your goal is, automating video generation can save you hours of manual editing and make sure every video looks on brand. If you haven’t tried it yet, give it a go!

    🐱 Meow Memo: Sign up for a Clipcat account here. You’ll get 100 free API credits to kickstart your first project!

    About the authorJosephine Loo
    Josephine is an automation enthusiast. She loves automating stuff and helping people to increase productivity with automation.
    How to Automate Video Generation with Clipcat and Google APIs (Node.js Tutorial)
    How to Automate Video Generation with Clipcat and Google APIs (Node.js Tutorial)