/

Google Slides Creator - Automated Presentation Builder

Copy script

Copied

Copy script

Copied

Google Slides Creator - Automated Presentation Builder

Creates professional Google Slides presentations programmatically with customizable themes, multiple slides, and automatic sharing options. Perfect for automating presentation creation, generating reports, or building slide decks from templates. Supports various themes, bullet points, custom content, and can make presentations publicly accessible.

Created by

andrew van beek - Keyboard Team

Requirements

google.com logo

Script

Copy script

Copied

Copy script

Copied

const { google } = require('googleapis');

// Initialize Google APIs with user token
const oauth2Client = new google.auth.OAuth2();
oauth2Client.setCredentials({
  access_token: process.env.KEYBOARD_PROVIDER_USER_TOKEN_FOR_GOOGLE
});

const slides = google.slides({ version: 'v1', auth: oauth2Client });
const drive = google.drive({ version: 'v3', auth: oauth2Client });

async function createGoogleSlidesPresentation() {
  try {
    console.log('šŸŽØ Creating Google Slides presentation...');
    console.log(`šŸ“ Title: {{presentationTitle}}`);
    console.log(`šŸŽ­ Theme: {{theme}}`);
    
    // Parse slides data
    const slidesData = {{slides}};
    console.log(`šŸ“Š Number of slides: ${slidesData.length}`);
    
    // Create the presentation
    const presentation = await slides.presentations.create({
      resource: {
        title: '{{presentationTitle}}'
      }
    });
    
    const presentationId = presentation.data.presentationId;
    console.log(`āœ… Presentation created with ID: ${presentationId}`);
    console.log(`šŸ”— URL: https://docs.google.com/presentation/d/${presentationId}/edit`);
    
    // Get the presentation to work with existing slides
    const currentPresentation = await slides.presentations.get({
      presentationId: presentationId
    });
    
    const existingSlides = currentPresentation.data.slides;
    const requests = [];
    
    // Delete the default slide if we have custom slides
    if (slidesData.length > 0 && existingSlides.length > 0) {
      requests.push({
        deleteObject: {
          objectId: existingSlides[0].objectId
        }
      });
    }
    
    // Create slides first
    slidesData.forEach((slideData, index) => {
      const slideId = `slide_${index}`;
      
      // Create slide
      requests.push({
        createSlide: {
          objectId: slideId,
          slideLayoutReference: {
            predefinedLayout: 'TITLE_AND_BODY'
          }
        }
      });
    });
    
    // Execute slide creation first
    if (requests.length > 0) {
      console.log('šŸ”§ Creating slides...');
      await slides.presentations.batchUpdate({
        presentationId: presentationId,
        resource: {
          requests: requests
        }
      });
    }
    
    // Now get the updated presentation to find text boxes
    const updatedPresentation = await slides.presentations.get({
      presentationId: presentationId
    });
    
    // Add content to each slide
    for (let index = 0; index < slidesData.length; index++) {
      const slideData = slidesData[index];
      const slide = updatedPresentation.data.slides[index];
      const textRequests = [];
      
      // Find title and body text boxes
      let titleElementId = null;
      let bodyElementId = null;
      
      if (slide.pageElements) {
        slide.pageElements.forEach(element => {
          if (element.shape && element.shape.placeholder) {
            if (element.shape.placeholder.type === 'TITLE') {
              titleElementId = element.objectId;
            } else if (element.shape.placeholder.type === 'BODY') {
              bodyElementId = element.objectId;
            }
          }
        });
      }
      
      // Add title text
      if (slideData.title && titleElementId) {
        textRequests.push({
          insertText: {
            objectId: titleElementId,
            text: slideData.title,
            insertionIndex: 0
          }
        });
      }
      
      // Add body text
      if (slideData.content && bodyElementId) {
        let contentText = '';
        if (Array.isArray(slideData.content)) {
          // Handle bullet points
          contentText = slideData.content.map(item => `• ${item}`).join('\n');
        } else {
          contentText = slideData.content;
        }
        
        textRequests.push({
          insertText: {
            objectId: bodyElementId,
            text: contentText,
            insertionIndex: 0
          }
        });
      }
      
      // Execute text updates for this slide
      if (textRequests.length > 0) {
        console.log(`šŸ“ Adding content to slide ${index + 1}...`);
        await slides.presentations.batchUpdate({
          presentationId: presentationId,
          resource: {
            requests: textRequests
          }
        });
      }
    }
    
    // Share the presentation if requested
    if ({{shareWithAnyone}}) {
      console.log('🌐 Making presentation publicly viewable...');
      await drive.permissions.create({
        fileId: presentationId,
        resource: {
          role: 'reader',
          type: 'anyone'
        }
      });
      console.log('āœ… Presentation is now viewable by anyone with the link');
    }
    
    // Get final presentation details
    const finalPresentation = await slides.presentations.get({
      presentationId: presentationId
    });
    
    console.log('\nšŸ“‹ Presentation Summary:');
    console.log(`- Title: ${finalPresentation.data.title}`);
    console.log(`- Slides: ${finalPresentation.data.slides.length}`);
    console.log(`- ID: ${presentationId}`);
    console.log(`- Edit URL: https://docs.google.com/presentation/d/${presentationId}/edit`);
    console.log(`- View URL: https://docs.google.com/presentation/d/${presentationId}/preview`);
    
    if ({{shareWithAnyone}}) {
      console.log(`- Public URL: https://docs.google.com/presentation/d/${presentationId}/edit?usp=sharing`);
    }
    
    return {
      success: true,
      presentationId: presentationId,
      title: finalPresentation.data.title,
      slideCount: finalPresentation.data.slides.length,
      editUrl: `https://docs.google.com/presentation/d/${presentationId}/edit`,
      viewUrl: `https://docs.google.com/presentation/d/${presentationId}/preview`,
      publicUrl: {{shareWithAnyone}} ? `https://docs.google.com/presentation/d/${presentationId}/edit?usp=sharing` : null
    };
    
  } catch (error) {
    console.error('āŒ Error creating presentation:', error.message);
    
    if (error.message.includes('insufficient authentication')) {
      console.error('šŸ”‘ Authentication issue - please check your Google token permissions');
    } else if (error.message.includes('quota')) {
      console.error('šŸ“Š API quota exceeded - please try again later');
    }
    
    throw error;
  }
}

// Execute the function
console.log('šŸš€ Starting Google Slides creation process...\n');
createGoogleSlidesPresentation()
  .then(result => {
    console.log('\nšŸŽ‰ Google Slides presentation created successfully!');
    return result;
  })
  .catch(error => {
    console.error('\nšŸ’„ Failed to create presentation');
    throw error;
  });