Merge data into a presentation

One useful application of the Google Slides API is to merge information from one or more data sources into a templated slide deck.

This page outlines how you can take data from an external source and insert it into an existing template presentation. The concept is similar to that of a mail merge using a word processor and spreadsheet.

There are several reasons why this approach is useful:

  • It's easy for designers to fine-tune a presentation's design using the Google Slides editor. This is much easier than tuning parameters in your app to set the rendered slide design.

  • Separating content from presentation is a well-known design principle with many benefits.

Conceptual diagram of a merge.

A basic recipe

Here's an example of how you can use the Slides API to merge data into a presentation:

  1. Create your presentation as you want it to appear using placeholder content to help you with the design.

  2. For each content element you'll be inserting, replace the placeholder content with a tag. Tags are text boxes or shapes with a unique string. Be sure to use strings that are unlikely to occur normally. For example, {{account-holder-name}} might be a good tag.

  3. In your code, use the Google Drive API to make a copy of the presentation.

  4. In your code, use the Slides API's batchUpdate method, with a set of replaceAllText requests, to perform all the text substitutions throughout the presentation. Use replaceAllShapesWithImage requests to perform image substitutions throughout the presentation.

Once you've created a deck with tags in it, be sure to make a copy and use the Slides API to manipulate the copy. Don't use the Slides API to manipulate your primary "template" copy!

The following sections include code snippets that illustrate some of this process. You can also view the above video to see a complete example (Python) combining several of the concepts from the individual sections below.

Merge text

You can use a replaceAllText request to replace all instances of a given text string in a presentation with new text. For merges, this is simpler than finding and replacing each instance of text individually. One reason this is the most sophisticated approach is that page element IDs are difficult to predict, especially as collaborators refine and maintain the template presentation.

Example

This example uses the Drive API to copy a template presentation, making a new instance of the presentation. Then it uses the Google Sheets API to read data from a Sheets spreadsheet, and finally uses the Slides API to update the new presentation.

The example takes data from 3 cells in one row of a named range in the spreadsheet. It then substitutes that data into the presentation wherever the strings {{customer-name}} , {{case-description}} , or {{total-portfolio}} occur.

Apps Script

slides/api/Snippets.gs
 /** 
 * Use the Sheets API to load data, one record per row. 
 * @param {string} templatePresentationId 
 * @param {string} dataSpreadsheetId 
 * @returns {*[]} 
 */ 
 function 
  
 textMerging 
 ( 
 templatePresentationId 
 , 
  
 dataSpreadsheetId 
 ) 
  
 { 
  
 let 
  
 responses 
  
 = 
  
 []; 
  
 const 
  
 dataRangeNotation 
  
 = 
  
 'Customers!A2:M6' 
 ; 
  
 try 
  
 { 
  
 let 
  
 values 
  
 = 
  
 SpreadsheetApp 
 . 
 openById 
 ( 
 dataSpreadsheetId 
 ). 
 getRange 
 ( 
 dataRangeNotation 
 ). 
 getValues 
 (); 
  
 // For each record, create a new merged presentation. 
  
 for 
  
 ( 
 let 
  
 i 
  
 = 
  
 0 
 ; 
  
 i 
 < 
 values 
 . 
 length 
 ; 
  
 ++ 
 i 
 ) 
  
 { 
  
 const 
  
 row 
  
 = 
  
 values 
 [ 
 i 
 ]; 
  
 const 
  
 customerName 
  
 = 
  
 row 
 [ 
 2 
 ]; 
  
 // name in column 3 
  
 const 
  
 caseDescription 
  
 = 
  
 row 
 [ 
 5 
 ]; 
  
 // case description in column 6 
  
 const 
  
 totalPortfolio 
  
 = 
  
 row 
 [ 
 11 
 ]; 
  
 // total portfolio in column 12 
  
 // Duplicate the template presentation using the Drive API. 
  
 const 
  
 copyTitle 
  
 = 
  
 customerName 
  
 + 
  
 ' presentation' 
 ; 
  
 let 
  
 copyFile 
  
 = 
  
 { 
  
 title 
 : 
  
 copyTitle 
 , 
  
 parents 
 : 
  
 [{ 
 id 
 : 
  
 'root' 
 }] 
  
 }; 
  
 copyFile 
  
 = 
  
 Drive 
 . 
 Files 
 . 
 copy 
 ( 
 copyFile 
 , 
  
 templatePresentationId 
 ); 
  
 const 
  
 presentationCopyId 
  
 = 
  
 copyFile 
 . 
 id 
 ; 
  
 // Create the text merge (replaceAllText) requests for this presentation. 
  
 const 
  
 requests 
  
 = 
  
 [{ 
  
 replaceAllText 
 : 
  
 { 
  
 containsText 
 : 
  
 { 
  
 text 
 : 
  
 '{{customer-name}}' 
 , 
  
 matchCase 
 : 
  
 true 
  
 }, 
  
 replaceText 
 : 
  
 customerName 
  
 } 
  
 }, 
  
 { 
  
 replaceAllText 
 : 
  
 { 
  
 containsText 
 : 
  
 { 
  
 text 
 : 
  
 '{{case-description}}' 
 , 
  
 matchCase 
 : 
  
 true 
  
 }, 
  
 replaceText 
 : 
  
 caseDescription 
  
 } 
  
 }, 
  
 { 
  
 replaceAllText 
 : 
  
 { 
  
 containsText 
 : 
  
 { 
  
 text 
 : 
  
 '{{total-portfolio}}' 
 , 
  
 matchCase 
 : 
  
 true 
  
 }, 
  
 replaceText 
 : 
  
 totalPortfolio 
  
 + 
  
 '' 
  
 } 
  
 }]; 
  
 // Execute the requests for this presentation. 
  
 const 
  
 result 
  
 = 
  
 Slides 
 . 
 Presentations 
 . 
 batchUpdate 
 ({ 
  
 requests 
 : 
  
 requests 
  
 }, 
  
 presentationCopyId 
 ); 
  
 // Count the total number of replacements made. 
  
 let 
  
 numReplacements 
  
 = 
  
 0 
 ; 
  
 result 
 . 
 replies 
 . 
 forEach 
 ( 
 function 
 ( 
 reply 
 ) 
  
 { 
  
 numReplacements 
  
 += 
  
 reply 
 . 
 replaceAllText 
 . 
 occurrencesChanged 
 ; 
  
 }); 
  
 console 
 . 
 log 
 ( 
 'Created presentation for %s with ID: %s' 
 , 
  
 customerName 
 , 
  
 presentationCopyId 
 ); 
  
 console 
 . 
 log 
 ( 
 'Replaced %s text instances' 
 , 
  
 numReplacements 
 ); 
  
 } 
  
 } 
  
 catch 
  
 ( 
 err 
 ) 
  
 { 
  
 // TODO (Developer) - Handle exception 
  
 console 
 . 
 log 
 ( 
 'Failed with error: %s' 
 , 
  
 err 
 . 
 error 
 ); 
  
 } 
 }; 

Go

slides/snippets/presentations.go
 // Use the Sheets API to load data, one record per row. 
 dataRangeNotation 
  
 := 
  
 "Customers!A2:M6" 
 sheetsResponse 
 , 
  
 _ 
  
 := 
  
 sheetsService 
 . 
 Spreadsheets 
 . 
 Values 
 . 
 Get 
 ( 
 dataSpreadsheetId 
 , 
  
 dataRangeNotation 
 ). 
 Do 
 () 
 values 
  
 := 
  
 sheetsResponse 
 . 
 Values 
 // For each record, create a new merged presentation. 
 for 
  
 _ 
 , 
  
 row 
  
 := 
  
 range 
  
 values 
  
 { 
  
 customerName 
  
 := 
  
 row 
 [ 
 2 
 ].( 
 string 
 ) 
  
 caseDescription 
  
 := 
  
 row 
 [ 
 5 
 ].( 
 string 
 ) 
  
 totalPortfolio 
  
 := 
  
 row 
 [ 
 11 
 ].( 
 string 
 ) 
  
 // Duplicate the template presentation using the Drive API. 
  
 copyTitle 
  
 := 
  
 customerName 
  
 + 
  
 " presentation" 
  
 file 
  
 := 
  
 drive 
 . 
 File 
 { 
  
 Title 
 : 
  
 copyTitle 
 , 
  
 } 
  
 presentationFile 
 , 
  
 _ 
  
 := 
  
 driveService 
 . 
 Files 
 . 
 Copy 
 ( 
 templatePresentationId 
 , 
  
& file 
 ). 
 Do 
 () 
  
 presentationId 
  
 := 
  
 presentationFile 
 . 
 Id 
  
 // Create the text merge (replaceAllText) requests for this presentation. 
  
 requests 
  
 := 
  
 [] 
 * 
 slides 
 . 
 Request 
{{
		ReplaceAllText: &slides.ReplaceAllTextRequest{
			ContainsText: &slides.SubstringMatchCriteria{
				Text:      "{{customer-name} } 
 ", 
 MatchCase: true, 
 }, 
 ReplaceText: customerName, 
 }, 
 }, { 
 ReplaceAllText: &slides.ReplaceAllTextRequest{ 
 ContainsText: &slides.SubstringMatchCriteria{ 
 Text:      " 
{{case-description} } 
 ", 
 MatchCase: true, 
 }, 
 ReplaceText: caseDescription, 
 }, 
 }, { 
 ReplaceAllText: &slides.ReplaceAllTextRequest{ 
 ContainsText: &slides.SubstringMatchCriteria{ 
 Text:      " 
{{total-portfolio} } 
 " 
 , 
  
 MatchCase 
 : 
  
 true 
 , 
  
 }, 
  
 ReplaceText 
 : 
  
 totalPortfolio 
 , 
  
 }, 
  
 }} 
  
 // Execute the requests for this presentation. 
  
 body 
  
 := 
  
& slides 
 . 
 BatchUpdatePresentationRequest 
 { 
  
 Requests 
 : 
  
 requests 
 , 
  
 } 
  
 response 
 , 
  
 _ 
  
 := 
  
 slidesService 
 . 
 Presentations 
 . 
 BatchUpdate 
 ( 
 presentationId 
 , 
  
 body 
 ). 
 Do 
 () 

Java

slides/snippets/src/main/java/TextMerging.java
 import 
  
 com.google.api.client.googleapis.json.GoogleJsonError 
 ; 
 import 
  
 com.google.api.client.googleapis.json.GoogleJsonResponseException 
 ; 
 import 
  
 com.google.api.client.http.HttpRequestInitializer 
 ; 
 import 
  
 com.google.api.client.http.javanet.NetHttpTransport 
 ; 
 import 
  
 com.google.api.client.json.gson.GsonFactory 
 ; 
 import 
  
 com.google.api.services.drive.Drive 
 ; 
 import 
  
 com.google.api.services.drive.model.File 
 ; 
 import 
  
 com.google.api.services.sheets.v4.Sheets 
 ; 
 import 
  
 com.google.api.services.sheets.v4.model.ValueRange 
 ; 
 import 
  
 com.google.api.services.slides.v1.Slides 
 ; 
 import 
  
 com.google.api.services.slides.v1.SlidesScopes 
 ; 
 import 
  
 com.google.api.services.slides.v1.model.BatchUpdatePresentationRequest 
 ; 
 import 
  
 com.google.api.services.slides.v1.model.BatchUpdatePresentationResponse 
 ; 
 import 
  
 com.google.api.services.slides.v1.model.ReplaceAllTextRequest 
 ; 
 import 
  
 com.google.api.services.slides.v1.model.Request 
 ; 
 import 
  
 com.google.api.services.slides.v1.model.Response 
 ; 
 import 
  
 com.google.api.services.slides.v1.model.SubstringMatchCriteria 
 ; 
 import 
  
 com.google.auth.http.HttpCredentialsAdapter 
 ; 
 import 
  
 com.google.auth.oauth2.GoogleCredentials 
 ; 
 import 
  
 java.io.IOException 
 ; 
 import 
  
 java.util.ArrayList 
 ; 
 import 
  
 java.util.Arrays 
 ; 
 import 
  
 java.util.List 
 ; 
 /* Class to demonstrate the use of Slides Text Merging API */ 
 public 
  
 class 
 TextMerging 
  
 { 
  
 /** 
 * Changes specified texts with data from spreadsheet. 
 * 
 * @param templatePresentationId - id of the presentation. 
 * @param dataSpreadsheetId      - id of the spreadsheet containing data. 
 * @return merged presentation id 
 * @throws IOException - if credentials file not found. 
 */ 
  
 public 
  
 static 
  
 List<BatchUpdatePresentationResponse> 
  
 textMerging 
 ( 
  
 String 
  
 templatePresentationId 
 , 
  
 String 
  
 dataSpreadsheetId 
 ) 
  
 throws 
  
 IOException 
  
 { 
  
 /* Load pre-authorized user credentials from the environment. 
 TODO(developer) - See https://developers.google.com/identity for 
 guides on implementing OAuth2 for your application. */ 
  
 GoogleCredentials 
  
 credentials 
  
 = 
  
 GoogleCredentials 
 . 
 getApplicationDefault 
 () 
  
 . 
 createScoped 
 ( 
 Arrays 
 . 
 asList 
 ( 
 SlidesScopes 
 . 
 PRESENTATIONS 
 , 
  
 SlidesScopes 
 . 
 DRIVE 
 , 
  
 SlidesScopes 
 . 
 SPREADSHEETS 
 )); 
  
 HttpRequestInitializer 
  
 requestInitializer 
  
 = 
  
 new 
  
 HttpCredentialsAdapter 
 ( 
  
 credentials 
 ); 
  
 // Create the slides API client 
  
 Slides 
  
 service 
  
 = 
  
 new 
  
 Slides 
 . 
 Builder 
 ( 
 new 
  
 NetHttpTransport 
 (), 
  
 GsonFactory 
 . 
 getDefaultInstance 
 (), 
  
 requestInitializer 
 ) 
  
 . 
 setApplicationName 
 ( 
 "Slides samples" 
 ) 
  
 . 
 build 
 (); 
  
 // Create the drive API client 
  
 Drive 
  
 driveService 
  
 = 
  
 new 
  
 Drive 
 . 
 Builder 
 ( 
 new 
  
 NetHttpTransport 
 (), 
  
 GsonFactory 
 . 
 getDefaultInstance 
 (), 
  
 requestInitializer 
 ) 
  
 . 
 setApplicationName 
 ( 
 "Slides samples" 
 ) 
  
 . 
 build 
 (); 
  
 // Create the sheets API client 
  
 Sheets 
  
 sheetsService 
  
 = 
  
 new 
  
 Sheets 
 . 
 Builder 
 ( 
 new 
  
 NetHttpTransport 
 (), 
  
 GsonFactory 
 . 
 getDefaultInstance 
 (), 
  
 requestInitializer 
 ) 
  
 . 
 setApplicationName 
 ( 
 "Slides samples" 
 ) 
  
 . 
 build 
 (); 
  
 List<BatchUpdatePresentationResponse> 
  
 responses 
  
 = 
  
 new 
  
 ArrayList 
<> ( 
 5 
 ); 
  
 // Use the Sheets API to load data, one record per row. 
  
 String 
  
 dataRangeNotation 
  
 = 
  
 "Customers!A2:M6" 
 ; 
  
 ValueRange 
  
 sheetsResponse 
  
 = 
  
 sheetsService 
 . 
 spreadsheets 
 (). 
 values 
 () 
  
 . 
 get 
 ( 
 dataSpreadsheetId 
 , 
  
 dataRangeNotation 
 ). 
 execute 
 (); 
  
 List<List<Object> 
>  
 values 
  
 = 
  
 sheetsResponse 
 . 
 getValues 
 (); 
  
 try 
  
 { 
  
 // For each record, create a new merged presentation. 
  
 for 
  
 ( 
 List<Object> 
  
 row 
  
 : 
  
 values 
 ) 
  
 { 
  
 String 
  
 customerName 
  
 = 
  
 row 
 . 
 get 
 ( 
 2 
 ). 
 toString 
 (); 
  
 // name in column 3 
  
 String 
  
 caseDescription 
  
 = 
  
 row 
 . 
 get 
 ( 
 5 
 ). 
 toString 
 (); 
  
 // case description in column 6 
  
 String 
  
 totalPortfolio 
  
 = 
  
 row 
 . 
 get 
 ( 
 11 
 ). 
 toString 
 (); 
  
 // total portfolio in column 12 
  
 // Duplicate the template presentation using the Drive API. 
  
 String 
  
 copyTitle 
  
 = 
  
 customerName 
  
 + 
  
 " presentation" 
 ; 
  
 File 
  
 content 
  
 = 
  
 new 
  
 File 
 (). 
 setName 
 ( 
 copyTitle 
 ); 
  
 File 
  
 presentationFile 
  
 = 
  
 driveService 
 . 
 files 
 (). 
 copy 
 ( 
 templatePresentationId 
 , 
  
 content 
 ). 
 execute 
 (); 
  
 String 
  
 presentationId 
  
 = 
  
 presentationFile 
 . 
 getId 
 (); 
  
 // Create the text merge (replaceAllText) requests for this presentation. 
  
 List<Request> 
  
 requests 
  
 = 
  
 new 
  
 ArrayList 
<> (); 
  
 requests 
 . 
 add 
 ( 
 new 
  
 Request 
 () 
  
 . 
 setReplaceAllText 
 ( 
 new 
  
 ReplaceAllTextRequest 
 () 
  
 . 
 setContainsText 
 ( 
 new 
  
 SubstringMatchCriteria 
 () 
  
 . 
 setText 
 ( 
 "{{customer-name}}" 
 ) 
  
 . 
 setMatchCase 
 ( 
 true 
 )) 
  
 . 
 setReplaceText 
 ( 
 customerName 
 ))); 
  
 requests 
 . 
 add 
 ( 
 new 
  
 Request 
 () 
  
 . 
 setReplaceAllText 
 ( 
 new 
  
 ReplaceAllTextRequest 
 () 
  
 . 
 setContainsText 
 ( 
 new 
  
 SubstringMatchCriteria 
 () 
  
 . 
 setText 
 ( 
 "{{case-description}}" 
 ) 
  
 . 
 setMatchCase 
 ( 
 true 
 )) 
  
 . 
 setReplaceText 
 ( 
 caseDescription 
 ))); 
  
 requests 
 . 
 add 
 ( 
 new 
  
 Request 
 () 
  
 . 
 setReplaceAllText 
 ( 
 new 
  
 ReplaceAllTextRequest 
 () 
  
 . 
 setContainsText 
 ( 
 new 
  
 SubstringMatchCriteria 
 () 
  
 . 
 setText 
 ( 
 "{{total-portfolio}}" 
 ) 
  
 . 
 setMatchCase 
 ( 
 true 
 )) 
  
 . 
 setReplaceText 
 ( 
 totalPortfolio 
 ))); 
  
 // Execute the requests for this presentation. 
  
 BatchUpdatePresentationRequest 
  
 body 
  
 = 
  
 new 
  
 BatchUpdatePresentationRequest 
 (). 
 setRequests 
 ( 
 requests 
 ); 
  
 BatchUpdatePresentationResponse 
  
 response 
  
 = 
  
 service 
 . 
 presentations 
 (). 
 batchUpdate 
 ( 
 presentationId 
 , 
  
 body 
 ). 
 execute 
 (); 
  
 // Count total number of replacements made. 
  
 int 
  
 numReplacements 
  
 = 
  
 0 
 ; 
  
 for 
  
 ( 
 Response 
  
 resp 
  
 : 
  
 response 
 . 
 getReplies 
 ()) 
  
 { 
  
 numReplacements 
  
 += 
  
 resp 
 . 
 getReplaceAllText 
 (). 
 getOccurrencesChanged 
 (); 
  
 } 
  
 // Prints the merged presentation id and count of replacements. 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Created merged presentation for " 
  
 + 
  
 customerName 
  
 + 
  
 " with ID: " 
  
 + 
  
 presentationId 
 ); 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Replaced " 
  
 + 
  
 numReplacements 
  
 + 
  
 " text instances." 
 ); 
  
 } 
  
 } 
  
 catch 
  
 ( 
 NullPointerException 
  
 ne 
 ) 
  
 { 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Text not found to replace with image." 
 ); 
  
 } 
  
 catch 
  
 ( 
 GoogleJsonResponseException 
  
 e 
 ) 
  
 { 
  
 // TODO(developer) - handle error appropriately 
  
 GoogleJsonError 
  
 error 
  
 = 
  
 e 
 . 
 getDetails 
 (); 
  
 if 
  
 ( 
 error 
 . 
 getCode 
 () 
  
 == 
  
 404 
 ) 
  
 { 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
 "Presentation not found with id '%s'.\n" 
 , 
  
 templatePresentationId 
 ); 
  
 } 
  
 else 
  
 { 
  
 throw 
  
 e 
 ; 
  
 } 
  
 } 
  
 return 
  
 responses 
 ; 
  
 } 
 } 

JavaScript

slides/snippets/slides_text_merging.js
 function 
  
 textMerging 
 ( 
 templatePresentationId 
 , 
  
 dataSpreadsheetId 
 , 
  
 callback 
 ) 
  
 { 
  
 // Use the Sheets API to load data, one record per row. 
  
 const 
  
 responses 
  
 = 
  
 []; 
  
 const 
  
 dataRangeNotation 
  
 = 
  
 'Customers!A2:M6' 
 ; 
  
 try 
  
 { 
  
 gapi 
 . 
 client 
 . 
 sheets 
 . 
 spreadsheets 
 . 
 values 
 . 
 get 
 ({ 
  
 spreadsheetId 
 : 
  
 dataSpreadsheetId 
 , 
  
 range 
 : 
  
 dataRangeNotation 
 , 
  
 }). 
 then 
 (( 
 sheetsResponse 
 ) 
  
 = 
>  
 { 
  
 const 
  
 values 
  
 = 
  
 sheetsResponse 
 . 
 result 
 . 
 values 
 ; 
  
 // For each record, create a new merged presentation. 
  
 for 
  
 ( 
 let 
  
 i 
  
 = 
  
 0 
 ; 
  
 i 
 < 
 values 
 . 
 length 
 ; 
  
 ++ 
 i 
 ) 
  
 { 
  
 const 
  
 row 
  
 = 
  
 values 
 [ 
 i 
 ]; 
  
 const 
  
 customerName 
  
 = 
  
 row 
 [ 
 2 
 ]; 
  
 // name in column 3 
  
 const 
  
 caseDescription 
  
 = 
  
 row 
 [ 
 5 
 ]; 
  
 // case description in column 6 
  
 const 
  
 totalPortfolio 
  
 = 
  
 row 
 [ 
 11 
 ]; 
  
 // total portfolio in column 12 
  
 // Duplicate the template presentation using the Drive API. 
  
 const 
  
 copyTitle 
  
 = 
  
 customerName 
  
 + 
  
 ' presentation' 
 ; 
  
 const 
  
 request 
  
 = 
  
 { 
  
 name 
 : 
  
 copyTitle 
 , 
  
 }; 
  
 gapi 
 . 
 client 
 . 
 drive 
 . 
 files 
 . 
 copy 
 ({ 
  
 fileId 
 : 
  
 templatePresentationId 
 , 
  
 requests 
 : 
  
 request 
 , 
  
 }). 
 then 
 (( 
 driveResponse 
 ) 
  
 = 
>  
 { 
  
 const 
  
 presentationCopyId 
  
 = 
  
 driveResponse 
 . 
 result 
 . 
 id 
 ; 
  
 // Create the text merge (replaceAllText) requests for this presentation. 
  
 const 
  
 requests 
  
 = 
  
 [{ 
  
 replaceAllText 
 : 
  
 { 
  
 containsText 
 : 
  
 { 
  
 text 
 : 
  
 '{{customer-name}}' 
 , 
  
 matchCase 
 : 
  
 true 
 , 
  
 }, 
  
 replaceText 
 : 
  
 customerName 
 , 
  
 }, 
  
 }, 
  
 { 
  
 replaceAllText 
 : 
  
 { 
  
 containsText 
 : 
  
 { 
  
 text 
 : 
  
 '{{case-description}}' 
 , 
  
 matchCase 
 : 
  
 true 
 , 
  
 }, 
  
 replaceText 
 : 
  
 caseDescription 
 , 
  
 }, 
  
 }, 
  
 { 
  
 replaceAllText 
 : 
  
 { 
  
 containsText 
 : 
  
 { 
  
 text 
 : 
  
 '{{total-portfolio}}' 
 , 
  
 matchCase 
 : 
  
 true 
 , 
  
 }, 
  
 replaceText 
 : 
  
 totalPortfolio 
 , 
  
 }, 
  
 }]; 
  
 // Execute the requests for this presentation. 
  
 gapi 
 . 
 client 
 . 
 slides 
 . 
 presentations 
 . 
 batchUpdate 
 ({ 
  
 presentationId 
 : 
  
 presentationCopyId 
 , 
  
 requests 
 : 
  
 requests 
 , 
  
 }). 
 then 
 (( 
 batchUpdateResponse 
 ) 
  
 = 
>  
 { 
  
 const 
  
 result 
  
 = 
  
 batchUpdateResponse 
 . 
 result 
 ; 
  
 responses 
 . 
 push 
 ( 
 result 
 . 
 replies 
 ); 
  
 // Count the total number of replacements made. 
  
 let 
  
 numReplacements 
  
 = 
  
 0 
 ; 
  
 for 
  
 ( 
 let 
  
 i 
  
 = 
  
 0 
 ; 
  
 i 
 < 
 result 
 . 
 replies 
 . 
 length 
 ; 
  
 ++ 
 i 
 ) 
  
 { 
  
 numReplacements 
  
 += 
  
 result 
 . 
 replies 
 [ 
 i 
 ]. 
 replaceAllText 
 . 
 occurrencesChanged 
 ; 
  
 } 
  
 console 
 . 
 log 
 ( 
 `Created presentation for 
 ${ 
 customerName 
 } 
 with ID: 
 ${ 
 presentationCopyId 
 } 
 ` 
 ); 
  
 console 
 . 
 log 
 ( 
 `Replaced 
 ${ 
 numReplacements 
 } 
 text instances` 
 ); 
  
 if 
  
 ( 
 responses 
 . 
 length 
  
 === 
  
 values 
 . 
 length 
 ) 
  
 { 
  
 // callback for the last value 
  
 if 
  
 ( 
 callback 
 ) 
  
 callback 
 ( 
 responses 
 ); 
  
 } 
  
 }); 
  
 }); 
  
 } 
  
 }); 
  
 } 
  
 catch 
  
 ( 
 err 
 ) 
  
 { 
  
 document 
 . 
 getElementById 
 ( 
 'content' 
 ). 
 innerText 
  
 = 
  
 err 
 . 
 message 
 ; 
  
 return 
 ; 
  
 } 
 } 

Node.js

slides/snippets/slides_text_merging.js
 /** 
 * Adds data from a spreadsheet to a template presentation. 
 * @param {string} templatePresentationId The template presentation ID. 
 * @param {string} dataSpreadsheetId  The data spreadsheet ID. 
 */ 
 async 
  
 function 
  
 textMerging 
 ( 
 templatePresentationId 
 , 
  
 dataSpreadsheetId 
 ) 
  
 { 
  
 const 
  
 { 
 GoogleAuth 
 } 
  
 = 
  
 require 
 ( 
 'google-auth-library' 
 ); 
  
 const 
  
 { 
 google 
 } 
  
 = 
  
 require 
 ( 
 'googleapis' 
 ); 
  
 const 
  
 auth 
  
 = 
  
 new 
  
 GoogleAuth 
 ({ 
  
 scopes 
 : 
  
 [ 
  
 'https://www.googleapis.com/auth/presentations' 
 , 
  
 'https://www.googleapis.com/auth/drive' 
 , 
  
 'https://www.googleapis.com/auth/spreadsheets' 
 , 
  
 ], 
  
 }); 
  
 const 
  
 slidesService 
  
 = 
  
 google 
 . 
 slides 
 ({ 
 version 
 : 
  
 'v1' 
 , 
  
 auth 
 }); 
  
 const 
  
 sheetsService 
  
 = 
  
 google 
 . 
 sheets 
 ({ 
 version 
 : 
  
 'v4' 
 , 
  
 auth 
 }); 
  
 const 
  
 driveService 
  
 = 
  
 google 
 . 
 drive 
 ({ 
 version 
 : 
  
 'v2' 
 , 
  
 auth 
 }); 
  
 // Use the Sheets API to load data, one record per row. 
  
 const 
  
 responses 
  
 = 
  
 []; 
  
 const 
  
 dataRangeNotation 
  
 = 
  
 'A2:M6' 
 ; 
  
 try 
  
 { 
  
 const 
  
 sheetsResponse 
  
 = 
  
 await 
  
 sheetsService 
 . 
 spreadsheets 
 . 
 values 
 . 
 get 
 ({ 
  
 spreadsheetId 
 : 
  
 dataSpreadsheetId 
 , 
  
 range 
 : 
  
 dataRangeNotation 
 , 
  
 }); 
  
 const 
  
 values 
  
 = 
  
 sheetsResponse 
 . 
 data 
 . 
 values 
 ; 
  
 // For each record, create a new merged presentation. 
  
 for 
  
 ( 
 let 
  
 i 
  
 = 
  
 0 
 ; 
  
 i 
 < 
 values 
 . 
 length 
 ; 
  
 ++ 
 i 
 ) 
  
 { 
  
 const 
  
 row 
  
 = 
  
 values 
 [ 
 i 
 ]; 
  
 const 
  
 customerName 
  
 = 
  
 row 
 [ 
 2 
 ]; 
  
 // name in column 3 
  
 const 
  
 caseDescription 
  
 = 
  
 row 
 [ 
 5 
 ]; 
  
 // case description in column 6 
  
 const 
  
 totalPortfolio 
  
 = 
  
 row 
 [ 
 11 
 ]; 
  
 // total portfolio in column 12 
  
 // Duplicate the template presentation using the Drive API. 
  
 const 
  
 copyTitle 
  
 = 
  
 customerName 
  
 + 
  
 ' presentation' 
 ; 
  
 let 
  
 requests 
  
 = 
  
 { 
  
 name 
 : 
  
 copyTitle 
 , 
  
 }; 
  
 const 
  
 driveResponse 
  
 = 
  
 await 
  
 driveService 
 . 
 files 
 . 
 copy 
 ({ 
  
 fileId 
 : 
  
 templatePresentationId 
 , 
  
 requests 
 , 
  
 }); 
  
 const 
  
 presentationCopyId 
  
 = 
  
 driveResponse 
 . 
 data 
 . 
 id 
 ; 
  
 // Create the text merge (replaceAllText) requests for this presentation. 
  
 requests 
  
 = 
  
 [ 
  
 { 
  
 replaceAllText 
 : 
  
 { 
  
 containsText 
 : 
  
 { 
  
 text 
 : 
  
 '{{customer-name}}' 
 , 
  
 matchCase 
 : 
  
 true 
 , 
  
 }, 
  
 replaceText 
 : 
  
 customerName 
 , 
  
 }, 
  
 }, 
  
 { 
  
 replaceAllText 
 : 
  
 { 
  
 containsText 
 : 
  
 { 
  
 text 
 : 
  
 '{{case-description}}' 
 , 
  
 matchCase 
 : 
  
 true 
 , 
  
 }, 
  
 replaceText 
 : 
  
 caseDescription 
 , 
  
 }, 
  
 }, 
  
 { 
  
 replaceAllText 
 : 
  
 { 
  
 containsText 
 : 
  
 { 
  
 text 
 : 
  
 '{{total-portfolio}}' 
 , 
  
 matchCase 
 : 
  
 true 
 , 
  
 }, 
  
 replaceText 
 : 
  
 totalPortfolio 
 , 
  
 }, 
  
 }, 
  
 ]; 
  
 // Execute the requests for this presentation. 
  
 const 
  
 batchUpdateResponse 
  
 = 
  
 await 
  
 slidesService 
 . 
 presentations 
 . 
 batchUpdate 
 ( 
  
 { 
  
 presentationId 
 : 
  
 presentationCopyId 
 , 
  
 resource 
 : 
  
 { 
  
 requests 
 , 
  
 }, 
  
 }, 
  
 ); 
  
 const 
  
 result 
  
 = 
  
 batchUpdateResponse 
 . 
 data 
 ; 
  
 // Count the total number of replacements made. 
  
 let 
  
 numReplacements 
  
 = 
  
 0 
 ; 
  
 for 
  
 ( 
 let 
  
 i 
  
 = 
  
 0 
 ; 
  
 i 
 < 
 result 
 . 
 replies 
 . 
 length 
 ; 
  
 ++ 
 i 
 ) 
  
 { 
  
 numReplacements 
  
 += 
  
 result 
 . 
 replies 
 [ 
 i 
 ]. 
 replaceAllText 
 . 
 occurrencesChanged 
 ; 
  
 } 
  
 console 
 . 
 log 
 ( 
  
 `Created presentation for 
 ${ 
 customerName 
 } 
 with ID: ` 
  
 + 
  
 presentationCopyId 
 , 
  
 ); 
  
 console 
 . 
 log 
 ( 
 `Replaced 
 ${ 
 numReplacements 
 } 
 text instances` 
 ); 
  
 return 
  
 result 
 ; 
  
 } 
  
 } 
  
 catch 
  
 ( 
 err 
 ) 
  
 { 
  
 // TODO (developer) - Handle exception 
  
 throw 
  
 err 
 ; 
  
 } 
 } 

PHP

slides/snippets/src/SlidesTextMerging.php
< ?php 
 use Google\Client; 
 use Google\Service\Drive; 
 use Google\Service\Slides; 
 use Google\Service\Slides\Request; 
 function textMerging($templatePresentationId, $dataSpreadsheetId) 
 { 
 /* Load pre-authorized user credentials from the environment. 
 TODO(developer) - See https://developers.google.com/identity for 
 guides on implementing OAuth2 for your application. */ 
 $client = new Google\Client(); 
 $client->useApplicationDefaultCredentials(); 
 $client->addScope(Google\Service\Drive::DRIVE); 
 $slidesService = new Google_Service_Slides($client); 
 $driveService = new Google_Service_Drive($client); 
 $sheetsService = new Google_Service_Sheets($client); 
 try { 
 $responses = array(); 
 // Use the Sheets API to load data, one record per row. 
 $dataRangeNotation = 'Customers!A2:M6'; 
 $sheetsResponse = 
 $sheetsService->spreadsheets_values->get($dataSpreadsheetId, $dataRangeNotation); 
 $values = $sheetsResponse['values']; 
 // For each record, create a new merged presentation. 
 foreach ($values as $row) { 
 $customerName = $row[2];     // name in column 3 
 $caseDescription = $row[5];  // case description in column 6 
 $totalPortfolio = $row[11];  // total portfolio in column 12 
 // Duplicate the template presentation using the Drive API. 
 $copy = new Google_Service_Drive_DriveFile(array( 
 'name' => $customerName . ' presentation' 
 )); 
 $driveResponse = $driveService->files->copy($templatePresentationId, $copy); 
 $presentationCopyId = $driveResponse->id; 
 // Create the text merge (replaceAllText) requests for this presentation. 
 $requests = array(); 
 $requests[] = new Google_Service_Slides_Request(array( 
 'replaceAllText' => array( 
 'containsText' => array( 
 'text' => '{{customer-name}}', 
 'matchCase' => true 
 ), 
 'replaceText' => $customerName 
 ) 
 )); 
 $requests[] = new Google_Service_Slides_Request(array( 
 'replaceAllText' => array( 
 'containsText' => array( 
 'text' => '{{case-description}}', 
 'matchCase' => true 
 ), 
 'replaceText' => $caseDescription 
 ) 
 )); 
 $requests[] = new Google_Service_Slides_Request(array( 
 'replaceAllText' => array( 
 'containsText' => array( 
 'text' => '{{total-portfolio}}', 
 'matchCase' => true 
 ), 
 'replaceText' => $totalPortfolio 
 ) 
 )); 
 // Execute the requests for this presentation. 
 $batchUpdateRequest = new Google_Service_Slides_BatchUpdatePresentationRequest(array( 
 'requests' => $requests 
 )); 
 $response = 
 $slidesService->presentations->batchUpdate($presentationCopyId, $batchUpdateRequest); 
 $responses[] = $response; 
 // Count the total number of replacements made. 
 $numReplacements = 0; 
 foreach ($response->getReplies() as $reply) { 
 $numReplacements += $reply->getReplaceAllText()->getOccurrencesChanged(); 
 } 
 printf("Created presentation for %s with ID: %s\n", $customerName, $presentationCopyId); 
 printf("Replaced %d text instances.\n", $numReplacements); 
 } 
 return $responses; 
 } catch (Exception $e) { 
 echo 'Message: ' . $e->getMessage(); 
 } 
 } 

Python

slides/snippets/slides_text_merging.py
 import 
  
 google.auth 
 from 
  
 googleapiclient.discovery 
  
 import 
 build 
 from 
  
 googleapiclient.errors 
  
 import 
 HttpError 
 def 
  
 text_merging 
 ( 
 template_presentation_id 
 , 
 data_spreadsheet_id 
 ): 
  
 """ 
 Run Text merging the user has access to. 
 Load pre-authorized user credentials from the environment. 
 TODO(developer) - See https://developers.google.com/identity 
 for guides on implementing OAuth2 for the application. 
 """ 
 creds 
 , 
 _ 
 = 
 google 
 . 
 auth 
 . 
 default 
 () 
 # pylint: disable=maybe-no-member 
 try 
 : 
 service 
 = 
 build 
 ( 
 "slides" 
 , 
 "v1" 
 , 
 credentials 
 = 
 creds 
 ) 
 sheets_service 
 = 
 build 
 ( 
 "sheets" 
 , 
 "v4" 
 , 
 credentials 
 = 
 creds 
 ) 
 drive_service 
 = 
 build 
 ( 
 "drive" 
 , 
 "v3" 
 , 
 credentials 
 = 
 creds 
 ) 
 # Use the Sheets API to load data, one record per row. 
 data_range_notation 
 = 
 "Customers!A2:M6" 
 sheets_response 
 = 
 ( 
 sheets_service 
 . 
 spreadsheets 
 () 
 . 
 values 
 () 
 . 
 get 
 ( 
 spreadsheetId 
 = 
 data_spreadsheet_id 
 , 
 range 
 = 
 data_range_notation 
 ) 
 . 
 execute 
 () 
 ) 
 values 
 = 
 sheets_response 
 . 
 get 
 ( 
 "values" 
 ) 
 # For each record, create a new merged presentation. 
 for 
 row 
 in 
 values 
 : 
 customer_name 
 = 
 row 
 [ 
 2 
 ] 
 # name in column 3 
 case_description 
 = 
 row 
 [ 
 5 
 ] 
 # case description in column 6 
 total_portfolio 
 = 
 row 
 [ 
 11 
 ] 
 # total portfolio in column 12 
 # Duplicate the template presentation using the Drive API. 
 copy_title 
 = 
 customer_name 
 + 
 " presentation" 
 body 
 = 
 { 
 "name" 
 : 
 copy_title 
 } 
 drive_response 
 = 
 ( 
 drive_service 
 . 
 files 
 () 
 . 
 copy 
 ( 
 fileId 
 = 
 template_presentation_id 
 , 
 body 
 = 
 body 
 ) 
 . 
 execute 
 () 
 ) 
 presentation_copy_id 
 = 
 drive_response 
 . 
 get 
 ( 
 "id" 
 ) 
 # Create the text merge (replaceAllText) requests 
 # for this presentation. 
 requests 
 = 
 [ 
 { 
 "replaceAllText" 
 : 
 { 
 "containsText" 
 : 
 { 
 "text" 
 : 
 "{{customer-name}}" 
 , 
 "matchCase" 
 : 
 True 
 , 
 }, 
 "replaceText" 
 : 
 customer_name 
 , 
 } 
 }, 
 { 
 "replaceAllText" 
 : 
 { 
 "containsText" 
 : 
 { 
 "text" 
 : 
 "{{case-description}}" 
 , 
 "matchCase" 
 : 
 True 
 , 
 }, 
 "replaceText" 
 : 
 case_description 
 , 
 } 
 }, 
 { 
 "replaceAllText" 
 : 
 { 
 "containsText" 
 : 
 { 
 "text" 
 : 
 "{{total-portfolio}}" 
 , 
 "matchCase" 
 : 
 True 
 , 
 }, 
 "replaceText" 
 : 
 total_portfolio 
 , 
 } 
 }, 
 ] 
 # Execute the requests for this presentation. 
 body 
 = 
 { 
 "requests" 
 : 
 requests 
 } 
 response 
 = 
 ( 
 service 
 . 
 presentations 
 () 
 . 
 batchUpdate 
 ( 
 presentationId 
 = 
 presentation_copy_id 
 , 
 body 
 = 
 body 
 ) 
 . 
 execute 
 () 
 ) 
 # Count the total number of replacements made. 
 num_replacements 
 = 
 0 
 for 
 reply 
 in 
 response 
 . 
 get 
 ( 
 "replies" 
 ): 
 if 
 reply 
 . 
 get 
 ( 
 "occurrencesChanged" 
 ) 
 is 
 not 
 None 
 : 
 num_replacements 
 += 
 reply 
 . 
 get 
 ( 
 "replaceAllText" 
 ) 
 . 
 get 
 ( 
 "occurrencesChanged" 
 ) 
 print 
 ( 
 "Created presentation for " 
 f 
 " 
 { 
 customer_name 
 } 
 with ID: 
 { 
 presentation_copy_id 
 } 
 " 
 ) 
 print 
 ( 
 f 
 "Replaced 
 { 
 num_replacements 
 } 
 text instances" 
 ) 
 except 
 HttpError 
 as 
 error 
 : 
 print 
 ( 
 f 
 "An error occurred: 
 { 
 error 
 } 
 " 
 ) 
 return 
 error 
 if 
 __name__ 
 == 
 "__main__" 
 : 
 # Put the template_presentation_id, data_spreadsheet_id 
 # of slides 
 text_merging 
 ( 
 "10QnVUx1X2qHsL17WUidGpPh_SQhXYx40CgIxaKk8jU4" 
 , 
 "17eqFZl_WK4WVixX8PjvjfLD77DraoFwMDXeiHB3dvuM" 
 , 
 ) 

Ruby

slides/snippets/lib/file_snippets.rb
 # Use the Sheets API to load data, one record per row. 
 data_range_notation 
  
 = 
  
 'Customers!A2:M6' 
 sheets_response 
  
 = 
  
 sheets_service 
 . 
 get_spreadsheet_values 
 ( 
  
 data_spreadsheet_id 
 , 
  
 data_range_notation 
 ) 
 values 
  
 = 
  
 sheets_response 
 . 
 values 
 # For each record, create a new merged presentation. 
 values 
 . 
 each 
  
 do 
  
 | 
 row 
 | 
  
 customer_name 
  
 = 
  
 row 
 [ 
 2 
 ] 
  
 # name in column 3 
  
 case_description 
  
 = 
  
 row 
 [ 
 5 
 ] 
  
 # case description in column 6 
  
 total_portfolio 
  
 = 
  
 row 
 [ 
 11 
 ] 
  
 # total portfolio in column 12 
  
 # Duplicate the template presentation using the Drive API. 
  
 copy_title 
  
 = 
  
 customer_name 
  
 + 
  
 ' presentation' 
  
 body 
  
 = 
  
 Google 
 :: 
 Apis 
 :: 
 SlidesV1 
 :: 
 Presentation 
 . 
 new 
  
 body 
 . 
 title 
  
 = 
  
 copy_title 
  
 drive_response 
  
 = 
  
 drive_service 
 . 
 copy_file 
 ( 
 template_presentation_id 
 , 
  
 body 
 ) 
  
 presentation_copy_id 
  
 = 
  
 drive_response 
 . 
 id 
  
 # Create the text merge (replace_all_text) requests for this presentation. 
  
 requests 
  
 = 
  
 [] 
 << 
 { 
  
 replace_all_text 
 : 
  
 { 
  
 contains_text 
 : 
  
 { 
  
 text 
 : 
  
 '{{customer-name}}' 
 , 
  
 match_case 
 : 
  
 true 
  
 }, 
  
 replace_text 
 : 
  
 customer_name 
  
 } 
  
 } 
 << 
 { 
  
 replace_all_text 
 : 
  
 { 
  
 contains_text 
 : 
  
 { 
  
 text 
 : 
  
 '{{case-description}}' 
 , 
  
 match_case 
 : 
  
 true 
  
 }, 
  
 replace_text 
 : 
  
 case_description 
  
 } 
  
 } 
 << 
 { 
  
 replace_all_text 
 : 
  
 { 
  
 contains_text 
 : 
  
 { 
  
 text 
 : 
  
 '{{total-portfolio}}' 
 , 
  
 match_case 
 : 
  
 true 
  
 }, 
  
 replace_text 
 : 
  
 total_portfolio 
  
 } 
  
 } 
  
 # Execute the requests for this presentation. 
  
 req 
  
 = 
  
 Google 
 :: 
 Apis 
 :: 
 SlidesV1 
 :: 
 BatchUpdatePresentationRequest 
 . 
 new 
 ( 
 requests 
 : 
  
 requests 
 ) 
  
 response 
  
 = 
  
 slides_service 
 . 
 batch_update_presentation 
 ( 
  
 presentation_copy_id 
 , 
  
 req 
  
 ) 

Merge images

You can also merge images into your presentation using a replaceAllShapesWithImage request. This request replaces all instances of shapes containing the provided text string with the provided image. The request automatically positions and scales the image to fit within the tag shape's bounds while preserving the image's aspect ratio.

Example

This example uses the Google Drive API to copy a template presentation, making a new instance of the presentation. Then it uses the Slides API to find any shape with the text {{company-logo}} and replace it with a company logo image. The request also replaces any shape with the text {{customer-graphic}} with a different image.

Apps Script

slides/api/Snippets.gs
 /** 
 * Duplicate the template presentation using the Drive API. 
 * @param {string} templatePresentationId 
 * @param {string} imageUrl 
 * @param {string} customerName 
 * @returns {*} 
 */ 
 function 
  
 imageMerging 
 ( 
 templatePresentationId 
 , 
  
 imageUrl 
 , 
  
 customerName 
 ) 
  
 { 
  
 const 
  
 logoUrl 
  
 = 
  
 imageUrl 
 ; 
  
 const 
  
 customerGraphicUrl 
  
 = 
  
 imageUrl 
 ; 
  
 const 
  
 copyTitle 
  
 = 
  
 customerName 
  
 + 
  
 ' presentation' 
 ; 
  
 let 
  
 copyFile 
  
 = 
  
 { 
  
 title 
 : 
  
 copyTitle 
 , 
  
 parents 
 : 
  
 [{ 
 id 
 : 
  
 'root' 
 }] 
  
 }; 
  
 try 
  
 { 
  
 copyFile 
  
 = 
  
 Drive 
 . 
 Files 
 . 
 copy 
 ( 
 copyFile 
 , 
  
 templatePresentationId 
 ); 
  
 const 
  
 presentationCopyId 
  
 = 
  
 copyFile 
 . 
 id 
 ; 
  
 // Create the image merge (replaceAllShapesWithImage) requests. 
  
 const 
  
 requests 
  
 = 
  
 [{ 
  
 replaceAllShapesWithImage 
 : 
  
 { 
  
 imageUrl 
 : 
  
 logoUrl 
 , 
  
 imageReplaceMethod 
 : 
  
 'CENTER_INSIDE' 
 , 
  
 containsText 
 : 
  
 { 
  
 text 
 : 
  
 '{{company-logo}}' 
 , 
  
 matchCase 
 : 
  
 true 
  
 } 
  
 } 
  
 }, 
  
 { 
  
 replaceAllShapesWithImage 
 : 
  
 { 
  
 imageUrl 
 : 
  
 customerGraphicUrl 
 , 
  
 imageReplaceMethod 
 : 
  
 'CENTER_INSIDE' 
 , 
  
 containsText 
 : 
  
 { 
  
 text 
 : 
  
 '{{customer-graphic}}' 
 , 
  
 matchCase 
 : 
  
 true 
  
 } 
  
 } 
  
 }]; 
  
 // Execute the requests for this presentation. 
  
 let 
  
 batchUpdateResponse 
  
 = 
  
 Slides 
 . 
 Presentations 
 . 
 batchUpdate 
 ({ 
  
 requests 
 : 
  
 requests 
  
 }, 
  
 presentationCopyId 
 ); 
  
 let 
  
 numReplacements 
  
 = 
  
 0 
 ; 
  
 batchUpdateResponse 
 . 
 replies 
 . 
 forEach 
 ( 
 function 
 ( 
 reply 
 ) 
  
 { 
  
 numReplacements 
  
 += 
  
 reply 
 . 
 replaceAllShapesWithImage 
 . 
 occurrencesChanged 
 ; 
  
 }); 
  
 console 
 . 
 log 
 ( 
 'Created merged presentation with ID: %s' 
 , 
  
 presentationCopyId 
 ); 
  
 console 
 . 
 log 
 ( 
 'Replaced %s shapes with images.' 
 , 
  
 numReplacements 
 ); 
  
 return 
  
 batchUpdateResponse 
 ; 
  
 } 
  
 catch 
  
 ( 
 err 
 ) 
  
 { 
  
 // TODO (Developer) - Handle exception 
  
 console 
 . 
 log 
 ( 
 'Failed with error: %s' 
 , 
  
 err 
 . 
 error 
 ); 
  
 } 
 }; 

Go

slides/snippets/presentations.go
 // Duplicate the template presentation using the Drive API. 
 copyTitle 
  
 := 
  
 customerName 
  
 + 
  
 " presentation" 
 file 
  
 := 
  
 drive 
 . 
 File 
 { 
  
 Title 
 : 
  
 copyTitle 
 , 
 } 
 presentationFile 
 , 
  
 _ 
  
 := 
  
 driveService 
 . 
 Files 
 . 
 Copy 
 ( 
 templatePresentationId 
 , 
  
& file 
 ). 
 Do 
 () 
 presentationId 
  
 := 
  
 presentationFile 
 . 
 Id 
 // Create the image merge (replaceAllShapesWithImage) requests. 
 requests 
  
 := 
  
 [] 
 * 
 slides 
 . 
 Request 
{{
	ReplaceAllShapesWithImage: &slides.ReplaceAllShapesWithImageRequest{
		ImageUrl:      logoURL,
		ReplaceMethod: "CENTER_INSIDE",
		ContainsText: &slides.SubstringMatchCriteria{
			Text:      "{{company-logo} } 
 ", 
 MatchCase: true, 
 }, 
 }, 
 }, { 
 ReplaceAllShapesWithImage: &slides.ReplaceAllShapesWithImageRequest{ 
 ImageUrl:      customerGraphicURL, 
 ReplaceMethod: " 
 CENTER_INSIDE 
 ", 
 ContainsText: &slides.SubstringMatchCriteria{ 
 Text:      " 
{{customer-graphic} } 
 ", 
 MatchCase: true, 
 }, 
 }, 
 }} 
 // Execute the requests for this presentation. 
 body := &slides.BatchUpdatePresentationRequest{Requests: requests} 
 response, _ := slidesService.Presentations.BatchUpdate(presentationId, body).Do() 
 // Count total number of replacements made. 
 var numReplacements int64 = 0 
 for _, resp := range response.Replies { 
 numReplacements += resp.ReplaceAllShapesWithImage.OccurrencesChanged 
 } 
 fmt.Printf(" 
 Created 
  
 merged 
  
 presentation 
  
 with 
  
 ID 
  
 % 
 s 
 \ 
 n 
 ", presentationId) 
 fmt.Printf(" 
 Replaced 
  
 % 
 d 
  
 shapes 
  
 instances 
  
 with 
  
 images 
 . 
 \ 
 n 
 " 
 , 
  
 numReplacements 
 ) 

Java

slides/snippets/src/main/java/ImageMerging.java
 import 
  
 com.google.api.client.http.HttpRequestInitializer 
 ; 
 import 
  
 com.google.api.client.http.javanet.NetHttpTransport 
 ; 
 import 
  
 com.google.api.client.json.gson.GsonFactory 
 ; 
 import 
  
 com.google.api.services.drive.Drive 
 ; 
 import 
  
 com.google.api.services.drive.model.File 
 ; 
 import 
  
 com.google.api.services.slides.v1.Slides 
 ; 
 import 
  
 com.google.api.services.slides.v1.SlidesScopes 
 ; 
 import 
  
 com.google.api.services.slides.v1.model.BatchUpdatePresentationRequest 
 ; 
 import 
  
 com.google.api.services.slides.v1.model.BatchUpdatePresentationResponse 
 ; 
 import 
  
 com.google.api.services.slides.v1.model.Request 
 ; 
 import 
  
 com.google.api.services.slides.v1.model.Response 
 ; 
 import 
  
 com.google.api.services.slides.v1.model.ReplaceAllShapesWithImageRequest 
 ; 
 import 
  
 com.google.api.services.slides.v1.model.SubstringMatchCriteria 
 ; 
 import 
  
 com.google.auth.http.HttpCredentialsAdapter 
 ; 
 import 
  
 com.google.auth.oauth2.GoogleCredentials 
 ; 
 import 
  
 java.io.IOException 
 ; 
 import 
  
 java.util.ArrayList 
 ; 
 import 
  
 java.util.Arrays 
 ; 
 import 
  
 java.util.List 
 ; 
 /* Class to demonstrate the use of Slides Image Merging API */ 
 public 
  
 class 
 ImageMerging 
  
 { 
  
 /** 
 * Changes specified texts into images. 
 * 
 * @param templatePresentationId - id of the presentation. 
 * @param imageUrl               - Url of the image. 
 * @param customerName           - Name of the customer. 
 * @return merged presentation id 
 * @throws IOException - if credentials file not found. 
 */ 
  
 public 
  
 static 
  
 BatchUpdatePresentationResponse 
  
 imageMerging 
 ( 
 String 
  
 templatePresentationId 
 , 
  
 String 
  
 imageUrl 
 , 
  
 String 
  
 customerName 
 ) 
  
 throws 
  
 IOException 
  
 { 
  
 /* Load pre-authorized user credentials from the environment. 
 TODO(developer) - See https://developers.google.com/identity for 
 guides on implementing OAuth2 for your application. */ 
  
 GoogleCredentials 
  
 credentials 
  
 = 
  
 GoogleCredentials 
 . 
 getApplicationDefault 
 () 
  
 . 
 createScoped 
 ( 
 Arrays 
 . 
 asList 
 ( 
 SlidesScopes 
 . 
 PRESENTATIONS 
 , 
  
 SlidesScopes 
 . 
 DRIVE 
 )); 
  
 HttpRequestInitializer 
  
 requestInitializer 
  
 = 
  
 new 
  
 HttpCredentialsAdapter 
 ( 
  
 credentials 
 ); 
  
 // Create the slides API client 
  
 Slides 
  
 service 
  
 = 
  
 new 
  
 Slides 
 . 
 Builder 
 ( 
 new 
  
 NetHttpTransport 
 (), 
  
 GsonFactory 
 . 
 getDefaultInstance 
 (), 
  
 requestInitializer 
 ) 
  
 . 
 setApplicationName 
 ( 
 "Slides samples" 
 ) 
  
 . 
 build 
 (); 
  
 // Create the drive API client 
  
 Drive 
  
 driveService 
  
 = 
  
 new 
  
 Drive 
 . 
 Builder 
 ( 
 new 
  
 NetHttpTransport 
 (), 
  
 GsonFactory 
 . 
 getDefaultInstance 
 (), 
  
 requestInitializer 
 ) 
  
 . 
 setApplicationName 
 ( 
 "Slides samples" 
 ) 
  
 . 
 build 
 (); 
  
 // Duplicate the template presentation using the Drive API. 
  
 String 
  
 copyTitle 
  
 = 
  
 customerName 
  
 + 
  
 " presentation" 
 ; 
  
 File 
  
 content 
  
 = 
  
 new 
  
 File 
 (). 
 setName 
 ( 
 copyTitle 
 ); 
  
 File 
  
 presentationFile 
  
 = 
  
 driveService 
 . 
 files 
 (). 
 copy 
 ( 
 templatePresentationId 
 , 
  
 content 
 ). 
 execute 
 (); 
  
 String 
  
 presentationId 
  
 = 
  
 presentationFile 
 . 
 getId 
 (); 
  
 // Create the image merge (replaceAllShapesWithImage) requests. 
  
 List<Request> 
  
 requests 
  
 = 
  
 new 
  
 ArrayList 
<> (); 
  
 requests 
 . 
 add 
 ( 
 new 
  
 Request 
 () 
  
 . 
 setReplaceAllShapesWithImage 
 ( 
 new 
  
 ReplaceAllShapesWithImageRequest 
 () 
  
 . 
 setImageUrl 
 ( 
 imageUrl 
 ) 
  
 . 
 setImageReplaceMethod 
 ( 
 "CENTER_INSIDE" 
 ) 
  
 . 
 setContainsText 
 ( 
 new 
  
 SubstringMatchCriteria 
 () 
  
 . 
 setText 
 ( 
 "{{company-logo}}" 
 ) 
  
 . 
 setMatchCase 
 ( 
 true 
 )))); 
  
 // Execute the requests. 
  
 BatchUpdatePresentationRequest 
  
 body 
  
 = 
  
 new 
  
 BatchUpdatePresentationRequest 
 (). 
 setRequests 
 ( 
 requests 
 ); 
  
 BatchUpdatePresentationResponse 
  
 response 
  
 = 
  
 service 
 . 
 presentations 
 (). 
 batchUpdate 
 ( 
 presentationId 
 , 
  
 body 
 ). 
 execute 
 (); 
  
 int 
  
 numReplacements 
  
 = 
  
 0 
 ; 
  
 try 
  
 { 
  
 // Count total number of replacements made. 
  
 for 
  
 ( 
 Response 
  
 resp 
  
 : 
  
 response 
 . 
 getReplies 
 ()) 
  
 { 
  
 numReplacements 
  
 += 
  
 resp 
 . 
 getReplaceAllShapesWithImage 
 (). 
 getOccurrencesChanged 
 (); 
  
 } 
  
 // Prints the merged presentation id and count of replacements. 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Created merged presentation with ID: " 
  
 + 
  
 presentationId 
 ); 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Replaced " 
  
 + 
  
 numReplacements 
  
 + 
  
 " shapes instances with images." 
 ); 
  
 } 
  
 catch 
  
 ( 
 NullPointerException 
  
 ne 
 ) 
  
 { 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Text not found to replace with image." 
 ); 
  
 } 
  
 return 
  
 response 
 ; 
  
 } 
 } 

JavaScript

slides/snippets/slides_image_merging.js
 function 
  
 imageMerging 
 ( 
  
 templatePresentationId 
 , 
  
 imageUrl 
 , 
  
 customerName 
 , 
  
 callback 
 , 
 ) 
  
 { 
  
 const 
  
 logoUrl 
  
 = 
  
 imageUrl 
 ; 
  
 const 
  
 customerGraphicUrl 
  
 = 
  
 imageUrl 
 ; 
  
 // Duplicate the template presentation using the Drive API. 
  
 const 
  
 copyTitle 
  
 = 
  
 customerName 
  
 + 
  
 ' presentation' 
 ; 
  
 try 
  
 { 
  
 gapi 
 . 
 client 
 . 
 drive 
 . 
 files 
  
 . 
 copy 
 ({ 
  
 fileId 
 : 
  
 templatePresentationId 
 , 
  
 resource 
 : 
  
 { 
  
 name 
 : 
  
 copyTitle 
 , 
  
 }, 
  
 }) 
  
 . 
 then 
 (( 
 driveResponse 
 ) 
  
 = 
>  
 { 
  
 const 
  
 presentationCopyId 
  
 = 
  
 driveResponse 
 . 
 result 
 . 
 id 
 ; 
  
 // Create the image merge (replaceAllShapesWithImage) requests. 
  
 const 
  
 requests 
  
 = 
  
 [ 
  
 { 
  
 replaceAllShapesWithImage 
 : 
  
 { 
  
 imageUrl 
 : 
  
 logoUrl 
 , 
  
 replaceMethod 
 : 
  
 'CENTER_INSIDE' 
 , 
  
 containsText 
 : 
  
 { 
  
 text 
 : 
  
 '{{company-logo}}' 
 , 
  
 matchCase 
 : 
  
 true 
 , 
  
 }, 
  
 }, 
  
 }, 
  
 { 
  
 replaceAllShapesWithImage 
 : 
  
 { 
  
 imageUrl 
 : 
  
 customerGraphicUrl 
 , 
  
 replaceMethod 
 : 
  
 'CENTER_INSIDE' 
 , 
  
 containsText 
 : 
  
 { 
  
 text 
 : 
  
 '{{customer-graphic}}' 
 , 
  
 matchCase 
 : 
  
 true 
 , 
  
 }, 
  
 }, 
  
 }, 
  
 ]; 
  
 // Execute the requests for this presentation. 
  
 gapi 
 . 
 client 
 . 
 slides 
 . 
 presentations 
  
 . 
 batchUpdate 
 ({ 
  
 presentationId 
 : 
  
 presentationCopyId 
 , 
  
 requests 
 : 
  
 requests 
 , 
  
 }) 
  
 . 
 then 
 (( 
 batchUpdateResponse 
 ) 
  
 = 
>  
 { 
  
 let 
  
 numReplacements 
  
 = 
  
 0 
 ; 
  
 for 
  
 ( 
  
 let 
  
 i 
  
 = 
  
 0 
 ; 
  
 i 
 < 
 batchUpdateResponse 
 . 
 result 
 . 
 replies 
 . 
 length 
 ; 
  
 ++ 
 i 
  
 ) 
  
 { 
  
 numReplacements 
  
 += 
  
 batchUpdateResponse 
 . 
 result 
 . 
 replies 
 [ 
 i 
 ]. 
 replaceAllShapesWithImage 
  
 . 
 occurrencesChanged 
 ; 
  
 } 
  
 console 
 . 
 log 
 ( 
  
 `Created merged presentation with ID: 
 ${ 
 presentationCopyId 
 } 
 ` 
 , 
  
 ); 
  
 console 
 . 
 log 
 ( 
 `Replaced 
 ${ 
 numReplacements 
 } 
 shapes with images.` 
 ); 
  
 if 
  
 ( 
 callback 
 ) 
  
 callback 
 ( 
 batchUpdateResponse 
 . 
 result 
 ); 
  
 }); 
  
 }); 
  
 } 
  
 catch 
  
 ( 
 err 
 ) 
  
 { 
  
 document 
 . 
 getElementById 
 ( 
 'content' 
 ). 
 innerText 
  
 = 
  
 err 
 . 
 message 
 ; 
  
 return 
 ; 
  
 } 
 } 

Node.js

slides/snippets/slides_image_merging.js
 /** 
 * Add an image to a template presentation. 
 * @param {string} templatePresentationId The template presentation ID. 
 * @param {string} imageUrl The image URL 
 * @param {string} customerName A customer name used for the title 
 */ 
 async 
  
 function 
  
 imageMerging 
 ( 
 templatePresentationId 
 , 
  
 imageUrl 
 , 
  
 customerName 
 ) 
  
 { 
  
 const 
  
 { 
 GoogleAuth 
 } 
  
 = 
  
 require 
 ( 
 'google-auth-library' 
 ); 
  
 const 
  
 { 
 google 
 } 
  
 = 
  
 require 
 ( 
 'googleapis' 
 ); 
  
 const 
  
 auth 
  
 = 
  
 new 
  
 GoogleAuth 
 ({ 
  
 scopes 
 : 
  
 [ 
  
 'https://www.googleapis.com/auth/presentations' 
 , 
  
 'https://www.googleapis.com/auth/drive' 
 , 
  
 ], 
  
 }); 
  
 const 
  
 slidesService 
  
 = 
  
 google 
 . 
 slides 
 ({ 
 version 
 : 
  
 'v1' 
 , 
  
 auth 
 }); 
  
 const 
  
 driveService 
  
 = 
  
 google 
 . 
 drive 
 ({ 
 version 
 : 
  
 'v2' 
 , 
  
 auth 
 }); 
  
 const 
  
 logoUrl 
  
 = 
  
 imageUrl 
 ; 
  
 const 
  
 customerGraphicUrl 
  
 = 
  
 imageUrl 
 ; 
  
 // Duplicate the template presentation using the Drive API. 
  
 const 
  
 copyTitle 
  
 = 
  
 customerName 
  
 + 
  
 ' presentation' 
 ; 
  
 try 
  
 { 
  
 const 
  
 driveResponse 
  
 = 
  
 await 
  
 driveService 
 . 
 files 
 . 
 copy 
 ({ 
  
 fileId 
 : 
  
 templatePresentationId 
 , 
  
 resource 
 : 
  
 { 
  
 name 
 : 
  
 copyTitle 
 , 
  
 }, 
  
 }); 
  
 const 
  
 presentationCopyId 
  
 = 
  
 driveResponse 
 . 
 data 
 . 
 id 
 ; 
  
 // Create the image merge (replaceAllShapesWithImage) requests. 
  
 const 
  
 requests 
  
 = 
  
 [ 
  
 { 
  
 replaceAllShapesWithImage 
 : 
  
 { 
  
 imageUrl 
 : 
  
 logoUrl 
 , 
  
 replaceMethod 
 : 
  
 'CENTER_INSIDE' 
 , 
  
 containsText 
 : 
  
 { 
  
 text 
 : 
  
 '{{company-logo}}' 
 , 
  
 matchCase 
 : 
  
 true 
 , 
  
 }, 
  
 }, 
  
 }, 
  
 { 
  
 replaceAllShapesWithImage 
 : 
  
 { 
  
 imageUrl 
 : 
  
 customerGraphicUrl 
 , 
  
 replaceMethod 
 : 
  
 'CENTER_INSIDE' 
 , 
  
 containsText 
 : 
  
 { 
  
 text 
 : 
  
 '{{customer-graphic}}' 
 , 
  
 matchCase 
 : 
  
 true 
 , 
  
 }, 
  
 }, 
  
 }, 
  
 ]; 
  
 // Execute the requests for this presentation. 
  
 const 
  
 batchUpdateResponse 
  
 = 
  
 await 
  
 slidesService 
 . 
 presentations 
 . 
 batchUpdate 
 ({ 
  
 presentationId 
 : 
  
 presentationCopyId 
 , 
  
 resource 
 : 
  
 { 
  
 requests 
 , 
  
 }, 
  
 }); 
  
 let 
  
 numReplacements 
  
 = 
  
 0 
 ; 
  
 for 
  
 ( 
 let 
  
 i 
  
 = 
  
 0 
 ; 
  
 i 
 < 
 batchUpdateResponse 
 . 
 data 
 . 
 replies 
 . 
 length 
 ; 
  
 ++ 
 i 
 ) 
  
 { 
  
 numReplacements 
  
 += 
  
 batchUpdateResponse 
 . 
 data 
 . 
 replies 
 [ 
 i 
 ]. 
 replaceAllShapesWithImage 
  
 . 
 occurrencesChanged 
 ; 
  
 } 
  
 console 
 . 
 log 
 ( 
 `Created merged presentation with ID: 
 ${ 
 presentationCopyId 
 } 
 ` 
 ); 
  
 console 
 . 
 log 
 ( 
 `Replaced 
 ${ 
 numReplacements 
 } 
 shapes with images.` 
 ); 
  
 return 
  
 batchUpdateResponse 
 . 
 data 
 ; 
  
 } 
  
 catch 
  
 ( 
 err 
 ) 
  
 { 
  
 // TODO (developer) - Handle exception 
  
 throw 
  
 err 
 ; 
  
 } 
 } 

PHP

slides/snippets/src/SlidesImageMerging.php
< ?php 
 use Google\Client; 
 use Google\Service\Drive; 
 use Google\Service\Slides; 
 use Google\Service\DriveFile; 
 use Google\Service\Slides\Request; 
 function imageMerging($templatePresentationId, $imageUrl, $customerName) 
 { 
 /* Load pre-authorized user credentials from the environment. 
 TODO(developer) - See https://developers.google.com/identity for 
 guides on implementing OAuth2 for your application. */ 
 $client = new Google\Client(); 
 $client->useApplicationDefaultCredentials(); 
 $client->addScope(Google\Service\Drive::DRIVE); 
 $slidesService = new Google_Service_Slides($client); 
 $driveService = new Google_Service_Drive($client); 
 // Duplicate the template presentation using the Drive API. 
 $copy = new Google_Service_Drive_DriveFile([ 
 'name' => $customerName . ' presentation' 
 ]); 
 $driveResponse = $driveService->files->copy($templatePresentationId, $copy); 
 $presentationCopyId = $driveResponse->id; 
 // Create the image merge (replaceAllShapesWithImage) requests. 
 $requests[] = new Google_Service_Slides_Request([ 
 'replaceAllShapesWithImage' => [ 
 'imageUrl' => $imageUrl, 
 'replaceMethod' => 'CENTER_INSIDE', 
 'containsText' => [ 
 'text' => '{{company-logo}}', 
 'matchCase' => true 
 ] 
 ] 
 ]); 
 $requests[] = new Google_Service_Slides_Request([ 
 'replaceAllShapesWithImage' => [ 
 'imageUrl' => $imageUrl, 
 'replaceMethod' => 'CENTER_INSIDE', 
 'containsText' => [ 
 'text' => '{{customer-graphic}}', 
 'matchCase' => true 
 ] 
 ] 
 ]); 
 // Execute the requests. 
 $batchUpdateRequest = new Google_Service_Slides_BatchUpdatePresentationRequest([ 
 'requests' => $requests 
 ]); 
 $response = 
 $slidesService->presentations->batchUpdate($presentationCopyId, $batchUpdateRequest); 
 // Count the total number of replacements made. 
 $numReplacements = 0; 
 foreach ($response->getReplies() as $reply) { 
 $numReplacements += $reply->getReplaceAllShapesWithImage()->getOccurrencesChanged(); 
 } 
 printf("Created presentation for %s with ID: %s\n", $customerName, $presentationCopyId); 
 printf("Replaced %d shapes with images.\n", $numReplacements); 
 return $response; 
 } 

Python

slides/snippets/slides_image_merging.py
 import 
  
 google.auth 
 from 
  
 googleapiclient.discovery 
  
 import 
 build 
 from 
  
 googleapiclient.errors 
  
 import 
 HttpError 
 def 
  
 image_merging 
 ( 
 template_presentation_id 
 , 
 image_url 
 , 
 customer_name 
 ): 
  
 """image_merging require template_presentation_id, 
 image_url and customer_name 
 Load pre-authorized user credentials from the environment. 
 TODO(developer) - See https://developers.google.com/identity 
 for guides on implementing OAuth2 for the application. 
 """ 
 creds 
 , 
 _ 
 = 
 google 
 . 
 auth 
 . 
 default 
 () 
 # pylint: disable=maybe-no-member 
 try 
 : 
 slides_service 
 = 
 build 
 ( 
 "slides" 
 , 
 "v1" 
 , 
 credentials 
 = 
 creds 
 ) 
 drive_service 
 = 
 build 
 ( 
 "drive" 
 , 
 "v3" 
 , 
 credentials 
 = 
 creds 
 ) 
 logo_url 
 = 
 image_url 
 customer_graphic_url 
 = 
 image_url 
 # Duplicate the template presentation using the Drive API. 
 copy_title 
 = 
 customer_name 
 + 
 " presentation" 
 drive_response 
 = 
 ( 
 drive_service 
 . 
 files 
 () 
 . 
 copy 
 ( 
 fileId 
 = 
 template_presentation_id 
 , 
 body 
 = 
 { 
 "name" 
 : 
 copy_title 
 }) 
 . 
 execute 
 () 
 ) 
 presentation_copy_id 
 = 
 drive_response 
 . 
 get 
 ( 
 "id" 
 ) 
 # Create the image merge (replaceAllShapesWithImage) requests. 
 requests 
 = 
 [] 
 requests 
 . 
 append 
 ( 
 { 
 "replaceAllShapesWithImage" 
 : 
 { 
 "imageUrl" 
 : 
 logo_url 
 , 
 "replaceMethod" 
 : 
 "CENTER_INSIDE" 
 , 
 "containsText" 
 : 
 { 
 "text" 
 : 
 "{{company-logo}}" 
 , 
 "matchCase" 
 : 
 True 
 , 
 }, 
 } 
 } 
 ) 
 requests 
 . 
 append 
 ( 
 { 
 "replaceAllShapesWithImage" 
 : 
 { 
 "imageUrl" 
 : 
 customer_graphic_url 
 , 
 "replaceMethod" 
 : 
 "CENTER_INSIDE" 
 , 
 "containsText" 
 : 
 { 
 "text" 
 : 
 "{{customer-graphic}}" 
 , 
 "matchCase" 
 : 
 True 
 , 
 }, 
 } 
 } 
 ) 
 # Execute the requests. 
 body 
 = 
 { 
 "requests" 
 : 
 requests 
 } 
 response 
 = 
 ( 
 slides_service 
 . 
 presentations 
 () 
 . 
 batchUpdate 
 ( 
 presentationId 
 = 
 presentation_copy_id 
 , 
 body 
 = 
 body 
 ) 
 . 
 execute 
 () 
 ) 
 # Count the number of replacements made. 
 num_replacements 
 = 
 0 
 for 
 reply 
 in 
 response 
 . 
 get 
 ( 
 "replies" 
 ): 
 # add below line 
 if 
 reply 
 . 
 get 
 ( 
 "occurrencesChanged" 
 ) 
 is 
 not 
 None 
 : 
 # end tag 
 num_replacements 
 += 
 reply 
 . 
 get 
 ( 
 "replaceAllShapesWithImage" 
 ) 
 . 
 get 
 ( 
 "occurrencesChanged" 
 ) 
 print 
 ( 
 f 
 "Created merged presentation with ID: 
 { 
 presentation_copy_id 
 } 
 " 
 ) 
 print 
 ( 
 f 
 "Replaced 
 { 
 num_replacements 
 } 
 shapes with images" 
 ) 
 except 
 HttpError 
 as 
 error 
 : 
 print 
 ( 
 f 
 "An error occurred: 
 { 
 error 
 } 
 " 
 ) 
 print 
 ( 
 "Images is not merged" 
 ) 
 return 
 error 
 return 
 response 
 if 
 __name__ 
 == 
 "__main__" 
 : 
 # Put the template_presentation_id, image_url and customer_name 
 image_merging 
 ( 
 "10QnVUx1X2qHsL17WUidGpPh_SQhXYx40CgIxaKk8jU4" 
 , 
 "https://www.google.com/images/branding/" 
 "googlelogo/2x/googlelogo_color_272x92dp.png" 
 , 
 "Fake Customer" 
 , 
 ) 

Ruby

slides/snippets/lib/file_snippets.rb
 # Duplicate the template presentation using the Drive API. 
 copy_title 
  
 = 
  
 customer_name 
  
 + 
  
 ' presentation' 
 body 
  
 = 
  
 Google 
 :: 
 Apis 
 :: 
 SlidesV1 
 :: 
 Presentation 
 . 
 new 
 body 
 . 
 title 
  
 = 
  
 copy_title 
 drive_response 
  
 = 
  
 drive_service 
 . 
 copy_file 
 ( 
 template_presentation_id 
 , 
  
 body 
 ) 
 presentation_copy_id 
  
 = 
  
 drive_response 
 . 
 id 
 # Create the image merge (replace_all_shapes_with_image) requests. 
 requests 
  
 = 
  
 [] 
 << 
 { 
  
 replace_all_shapes_with_image 
 : 
  
 { 
  
 image_url 
 : 
  
 logo_url 
 , 
  
 replace_method 
 : 
  
 'CENTER_INSIDE' 
 , 
  
 contains_text 
 : 
  
 { 
  
 text 
 : 
  
 '{{company-logo}}' 
 , 
  
 match_case 
 : 
  
 true 
  
 } 
  
 } 
 } 
 << 
 { 
  
 replace_all_shapes_with_image 
 : 
  
 { 
  
 image_url 
 : 
  
 customer_graphic_url 
 , 
  
 replace_method 
 : 
  
 'CENTER_INSIDE' 
 , 
  
 contains_text 
 : 
  
 { 
  
 text 
 : 
  
 '{{customer-graphic}}' 
 , 
  
 match_case 
 : 
  
 true 
  
 } 
  
 } 
 } 
 # Execute the requests. 
 req 
  
 = 
  
 Google 
 :: 
 Apis 
 :: 
 SlidesV1 
 :: 
 BatchUpdatePresentationRequest 
 . 
 new 
 ( 
 requests 
 : 
  
 requests 
 ) 
 response 
  
 = 
  
 slides_service 
 . 
 batch_update_presentation 
 ( 
  
 presentation_copy_id 
 , 
  
 req 
 ) 
 # Count the number of replacements made. 
 num_replacements 
  
 = 
  
 0 
 response 
 . 
 replies 
 . 
 each 
  
 do 
  
 | 
 reply 
 | 
  
 num_replacements 
  
 += 
  
 reply 
 . 
 replace_all_shapes_with_image 
 . 
 occurrences_changed 
 end 
 puts 
  
 "Created presentation for 
 #{ 
 customer_name 
 } 
 with ID: 
 #{ 
 presentation_copy_id 
 } 
 " 
 puts 
  
 "Replaced 
 #{ 
 num_replacements 
 } 
 shapes with images" 

Replace specific text box or image instances

The replaceAllText and replaceAllShapesWithImage requests are useful for replacing tags throughout a presentation, but sometimes you only need to replace elements according to another criteria, such as being located on a specific slide.

In these cases, you must retrieve the IDs of the tag shapes you want to replace. For text replacements, you delete the existing text in those shapes and then insert the new text (see the sample Edit text in a specified shape ).

Image replacements are more complex. To merge in an image, you need to:

  1. Get the tag shape's ID.
  2. Copy the size and transform information from the tag.
  3. Add your image to the page, using the size and transform information.
  4. Delete the tag shape.

Preserving the image's aspect ratio while scaling it to the desired size might require some care, as described in the following section. Also see this sample: Replace a shape tag with an image .

Preserve aspect ratio

When you create images using the Slides API, aspect fits are based only on the image size, not on the size and transform data. The size data you provide in the createImage request is considered to be the desired size of the image. The API fits the image's aspect ratio to this desired size, then applies the provided transform.

When replacing a tag with an image, you preserve the image's aspect ratio by setting the image's size and scaling as follows:

  • width: set to the product of the tag's width and scaleX
  • height: set to the product of the tag's height and scaleY
  • scale_x: set to 1
  • scale_y: set to 1

This causes the Slides API to aspect fit the image according to the tag's visual size, rather than its non-scaled size (see Replace a shape tag with an image ). Setting the scaling parameters to 1 prevents the image from being scaled twice.

This arrangement ensures the image's aspect ratio is preserved, and prevents the image from exceeding the size of the tag shape. The image has the same center point as the tag shape.

Manage templates

For template presentations the application defines and owns, create the template using a dedicated account representing the application. Service accounts are a good choice and avoid complications with Google Workspace policies that restrict sharing.

When you create instances of presentations from templates, always use end-user credentials. This gives users full control over the resulting presentation and prevents scaling issues related to per-user limits in Google Drive.

To create a template using a service account, perform the following steps with the application credentials:

  1. Create a presentation using presentations.create in the Slides API.
  2. Update the permissions to allow the presentation recipients to read it using permissions.create in the Drive API.
  3. Update the permissions to allow template authors to write to it using permissions.create in the Drive API.
  4. Edit the template as required.

To create an instance of the presentation, perform the following steps with the user credentials:

  1. Create a copy of the template using files.copy in the Drive API.
  2. Replace values using presentation.batchUpdate in the Slides API.
Create a Mobile Website
View Site in Mobile | Classic
Share by: