Create Presentation Slides with AI

Automating Google Slides — infused with OpenAI and Midjourney

Ivan Campos
Sopmac AI
6 min readFeb 23, 2023

--

Designing and populating slides can take up a lot of time, but advances in Artificial Intelligence have made it possible to create visually stunning and effective presentations much faster.

In this article, we’ll explore how to automate Google Slides and enhance presentations using AI tools like Midjourney and the OpenAI API.

High Level Overview

  • Authenticating with Google APIs
  • Using a Google Slides Template
  • Replacing template text with OpenAI API and images with Midjourney

1. Authentication with Service Account’s Private Key

We begin by importing the googleapis library and the private key file of your service account, for authentication and authorization purposes to ensure secure communication between your code and Google services.

const {google} = require('googleapis');
const privatekey = require('./YOUR_SERVICE_ACCOUNT_PRIVATE_KEY.json');

The const {google} = require('googleapis') line is using destructuring to extract the google object from the googleapis library, which provides a convenient way to access and work with Google APIs.

const privatekey = require('./YOUR_SERVICE_ACCOUNT_PRIVATE_KEY.json') is importing the private key file of your service account.

A service account is a special type of Google account that is used for non-human processes and applications to access Google APIs.

Google Slides Authentication

const authSlides = new google.auth.JWT(
privatekey.client_email,
null,
privatekey.private_key,
"https://www.googleapis.com/auth/presentations",
null
);

This code is creating a JSON Web Token (JWT) object for authorization to access Google Slides API using the google-auth-library package. The privatekey object contains the private key of a service account, which is used to authenticate the request to access Google Slides API.

The new google.auth.JWT() constructor takes several parameters including the client email, private key, and scope. The client_email is the email address of the service account and the private_key is the private key of the service account. The https://www.googleapis.com/auth/presentations scope specifies that the authorization is for the Google Slides API.

Once the JWT object is created, it can be used to authenticate and authorize API requests to Google Slides on behalf of the service account.

Google Drive Authentication

Similarly, we can do this same for Google Drive, by changing the scope to https://www.googleapis.com/auth/drive

const authDrive = new google.auth.JWT(
privatekey.client_email,
null,
privatekey.private_key,
"https://www.googleapis.com/auth/drive",
null
);

2. Create a Google Slides Template

A Google Slides template is a pre-designed set of slides that can be used as a starting point for creating a new presentation. In your template, be sure to wrap any text that you expect to modify inside of mustache/handlebars syntax. For example, {{TITLE1}}

Sample Google Slides Template

Once your Google Slides template is saved, the presentation’s URL should look like https://docs.google.com/presentation/d/G1bb3r1$h/edit

Make note of the characters between /d/ and /edit as this will serve as the template’s presentationId.

Note: Inside the template, each image will be assigned an imageObjectId

3. Copy Template from Google Drive

In the following code, we are copying a Google Slides presentation file with the specified presentationId and creating a new copy with a different name, name. The drive object is likely an instance of the Google Drive API client, and the files.copy() method is being called to create the copy of the presentation file. The fields parameter specifies the response fields to include in the API response, and in this case, only the id field is being returned. The new copy of the presentation file is created with the specified name as its title. The await keyword is used to wait for the asynchronous operation to complete before moving on to the next line of code.

const drive = google.drive({version: "v3", "auth": authDrive});
const result = await drive.files.copy({
fileId: presentationId,
fields: 'id',
resource: {
name: name
}

4. Set Permissions

const drive = google.drive({version: "v3", "auth": authDrive});
const permissionIds = [];

const permissions = [
{
type: 'user',
role: 'writer',
emailAddress: 'USER_TO_GRANT_ACCESS_TO@gmail.com',
},
];

for (const permission of permissions) {
try {
const result = await drive.permissions.create({
resource: permission,
fileId: presentationId,
fields: 'id',
});
permissionIds.push(result.data.id);

} catch (err) {
console.error("Error: " + err);
}
}

This code is granting a user with the email address “USER_TO_GRANT_ACCESS_TO@gmail.com” the permission to write (edit) a Google Drive file with the ID “presentationId”. The code creates a new permission object with the given user email address and role, and then loops through each permission object to create a new permission for the file using the Google Drive API. The “permissionIds” array keeps track of the IDs of the newly created permissions.

5. ReplaceAllText with OpenAI API

We begin by importing the Configuration and OpenAIApi classes from the “openai” package and creating a new instance of the Configuration class with an API key stored in an environment variable. The API key is used for authentication when making requests to the OpenAI API.

const { Configuration, OpenAIApi } = require("openai");
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});

Next, we are using the OpenAI API to generate a short text prompt completion. The createCompletion() function is called to generate a completion based on the provided prompt, which is a string that serves as a starting point for the AI-generated text. The parameters passed to this function include the name of the OpenAI language model to be used (text-davinci-003), the temperature (which controls the level of randomness and creativity in the generated text), and the max_tokens (which limits the length of the generated text). Once the API call returns a response, the first choice is selected and any leading or trailing whitespace is trimmed before assigning the generated text to the inspiration variable.

const response = await openai.createCompletion({
model: "text-davinci-003",
prompt: "YOUR_PROMPT_GOES_HERE",
temperature: 0,
max_tokens: 10,
});

let inspiration = response.data.choices[0].text.trim();

Finally, we are creating a requests array which contains a replaceAllText object. The replaceAllText object specifies that the text in a document containing the string “{{PARAGRAPH}}” should be replaced with the string stored in the variable “inspiration”. The replaceText property of the replaceAllText object contains the new string to replace the old one, and the containsText property specifies the text to be replaced by using the text property containing the string “{{PARAGRAPH}}”.

This step can be repeatable multiple times for each text replacement and simply added to the requests collection.

const requests = [{
replaceAllText: {
replaceText: inspiration,
containsText: {
text: '{{INSPIRATIONAL QUOTE}}'
}
}
}];

6. ReplaceImage with Midjourney

Prerequisite: Create an image using Midjourney and save it to a publicly accessible URL, which will set toimgUrl.

This code is creating a list of requests to be sent to the Google Slides API to replace an image on a slide with a new image from a specified URL. The requests variable is an array that contains a single object representing the request. The replaceImage property of this object specifies the type of request (replacing an image) and includes several parameters: imageObjectId, which is the ID of the image to be replaced; imageReplaceMethod, which specifies how to fit the new image into the original image's space; and url, which is the URL of the new image.

This step can be repeatable multiple times for each image replacement and simply added to the requests collection.

const requests = [{
replaceImage: {
"imageObjectId": "g2015e0649b0_0_52",
"imageReplaceMethod": "CENTER_INSIDE",
"url": imgUrl
}
}];

7. Batch Updates

Using the Google Slides API we can send a batch update request to the specified presentation. The request is to modify the presentation with the contents of the specified resource, which includes a list of individual update requests to apply to the presentation. The updates in this case are defined by the requests array, which is passed as part of the resource object.

const presentation = await slides.presentations.batchUpdate({
presentationId: presentationId,
resource: { requests: requests }
});

Once completed, we can access the presentation URL:

presentationUrl: "https://docs.google.com/presentation/d/" + presentationId + "/edit"

Conclusion

Upon opening the slides, you should now see your OpenAI text, Midjourney images, and any other creative changes that you’ve applied to the template.

New presentation slides with modified template

--

--

Ivan Campos
Sopmac AI

Exploring the potential of AI to revolutionize the way we live and work. Join me in discovering the future of tech