# Document Merge using Google Apps Script, Webhook Action & Google Docs

**URL:** https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782
**Category:** Project Showcase
**Created:** [March 26, 2021, 8:15pm UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782 "2021-03-26T20:15:49Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Purvang\_Joshi](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/purvang_joshi/32/12645_2.png) [@Purvang\_Joshi](https://community.glideapps.com/u/Purvang_Joshi)
#### Post date: [March 26, 2021, 8:15pm UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/1 "2021-03-26T20:15:49Z")

</div>

Hello, Gliders,  
Many of you have use-cases like,  
 → Sending certificates to your students  
 → Sending Auto-Generated Invoices, Quotes & Many more  
 → creating ID cards for the events  
 → Mail merge custom PDFs

Here I’ll show you how to implement it.

Demo: [https://milky-produce-8069.glideapp.io/](https://milky-produce-8069.glideapp.io/) [It’s in Personal Plan, Only 80 Webhook Actions Left]

Whenever the user fills and submits a button, it’ll trigger the script and send a pdf attached mail to the receiver.

The flow of the System

Glide App → Webhook Action → Google Apps Script → Google Docs → PDF Mail

# Implementation Steps
**Step: 1**   
Create a Google Doc Template (Source File) Make Copy from here for demo purpose [Make a Copy of Google Doc](https://docs.google.com/document/d/1l6WXZEPv9G5ivuhauyuuMbeNFlxxTEjR9tZph3_OzwI/copy)

Now, open copied document, copy the document id from the URL. (Will be used later) (Don’t include /d/)

 ![Screenshot 2021-03-27 at 1.07.14 AM](https://us1.discourse-cdn.com/flex002/uploads/glideapps/original/3X/b/2/b253eb38239a186df59a21b9a05ae478d4f844b8.png)  
  
  
**Step: 2**  
Make a Google Drive Folder (It’ll be used as temporary to store & delete files)

Copy Drive Folder ID (Will be used later)

  
**Step: 3**   
Copy following code to Google Apps Script   
Click here to make new script project script.new

```
function doPost(e) {

// Calling Parameters from GlideApp
const body = JSON.parse(e.postData.contents);
const ProjectName = body["params"]["ProjectName"]["value"];
const CompanyName = body["params"]["CompanyName"]["value"];
const YourName = body["params"]["YourName"]["value"];
const YourEmail = body["params"]["YourEmail"]["value"];
const Date = body["params"]["Date"]["value"];

// Copy IDs
const doc_id= "ENTER DOCUEMENT ID HERE";
const tempFolder_id = "ENTER DRIVE FOLDER ID HERE";

const template = DriveApp.getFileById(doc_id);

const tempFolder = DriveApp.getFolderById(tempFolder_id);
const doc_new = template.makeCopy(tempFolder).setName(ProjectName);
const doc_new_id = doc_new.getId();
const open_doc = DocumentApp.openById(doc_new_id);
const body_doc = open_doc.getBody();

// Replaces all values to new ones.

body_doc.replaceText("Project name", ProjectName);
body_doc.replaceText("Date", Date);
body_doc.replaceText("YOUR COMPANY NAME", CompanyName);
body_doc.replaceText("YOUR NAME", YourName);
body_doc.replaceText("YOUR EMAIL", YourEmail);

open_doc.saveAndClose();

const BLOBPDF = doc_new.getAs(MimeType.PDF);
//"Remove this to store pdf to temporary folder " tempFolder.createFile(BLOBPDF).setName(ProjectName);
tempFolder.removeFile(doc_new);

const senderName = "Project Proposal";
const subject = YourName + ", you're awesome!";
const body_mail = "Please find your proposal for "+ ProjectName + "attached";
GmailApp.sendEmail(YourEmail, subject, body_mail, {
  attachments: [BLOBPDF],
  name: senderName
});
SpreadsheetApp.flush();

```

}

  
**Step: 3**   
Assign an Existing [GCP](https://console.cloud.google.com/) Project to the settings of Apps Script or create a new GCP Project, Let me know if you're facing any difficulties.

**Step: 4**  
Deploy GAS Project as a web app.  
Copy Web App URL after deploying.  
Important: Whenever you make changes to your code, you’ve to redeploy that code and change the URL.

**Step: 5**  
Setup GlideApp Webhook Action to a button  
Important: Check Spell twice before running the script.

![Screenshot 2021-03-27 at 1.40.01 AM](https://us1.discourse-cdn.com/flex002/uploads/glideapps/original/3X/9/9/99de6295ced65d92e710e4be2d31efffa5f88477.png)

Done!

You can also send pdfs via google slides. Let me know if anyone wants a tutorial on it.

---

<div class="post-metadata">

### Author: ![Robert\_Petitto](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/robert_petitto/32/25193_2.png) [@Robert\_Petitto](https://community.glideapps.com/u/Robert_Petitto)
#### Post date: [March 26, 2021, 8:35pm UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/2 "2021-03-26T20:35:12Z")

</div>

Very cool! For those that aren’t savvy with Google Scripts, Google sheets has a free add on called autocrat that will let you send mail merge Google docs just like this. It’s a bit buggy like anything else, but it’s a nice solution.

[https://workspace.google.com/marketplace/app/autocrat/539341275670](https://workspace.google.com/marketplace/app/autocrat/539341275670)

---

<div class="post-metadata">

### Author: ![Purvang\_Joshi](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/purvang_joshi/32/12645_2.png) [@Purvang\_Joshi](https://community.glideapps.com/u/Purvang_Joshi)
#### Post date: [March 26, 2021, 8:45pm UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/3 "2021-03-26T20:45:44Z")

</div>

Yes. Indeed. Autocrat is a great solution for very long.  
This script will benefit to share of instant mail. It took 8 Seconds to receive a merged PDF as of now.

Also, Autocrat hasn’t instant trigger solution. This saves a lot of time for me.

---

<div class="post-metadata">

### Author: ![gvalero](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/gvalero/32/1037_2.png) [@gvalero](https://community.glideapps.com/u/gvalero)
#### Post date: [March 26, 2021, 9:12pm UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/4 "2021-03-26T21:12:22Z")

</div>

Hola @Purvang_Joshi

I wonder if your script can open the same doc to update it and later to be shown or sent instead of creating a new one?

I made some similar but using Integromat and Google Slices but Integromat always creates a new version of my template and I don’t want it.  
I want to have an only one file to this process. Could you test it for me please?

Thanks for this good tip.

Feliz día

---

<div class="post-metadata">

### Author: ![Purvang\_Joshi](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/purvang_joshi/32/12645_2.png) [@Purvang\_Joshi](https://community.glideapps.com/u/Purvang_Joshi)
#### Post date: [March 26, 2021, 9:28pm UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/5 "2021-03-26T21:28:11Z")

</div>

You can delete new generated file anyways. I’ve already added.

tempFolder.removeFile(doc\_new);

We shouldn’t do with single slide because this script uses replace text method. The new generated will replace template fileds. So, it’ll create an error to next operation. Template will be overwrites, thats why copying a new doc and deleting itself should ne a good choice.

---

<div class="post-metadata">

### Author: ![gvalero](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/gvalero/32/1037_2.png) [@gvalero](https://community.glideapps.com/u/gvalero)
#### Post date: [March 26, 2021, 9:57pm UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/6 "2021-03-26T21:57:15Z")

</div>

Yes, I know I can delete older files but in my case, I need to use the same file (Slide) due to a Display/TV will show the newest info from my APP (Order #, Customer Name, Total $) at a restaurant.

That data is sent by my APP dynamically to my Slide and works perfect but I am looking for a way to get it keeping the same Slice on Display without refreshing or opening a new file manually.

Thanks again!

Saludos

---

<div class="post-metadata">

### Author: ![Purvang\_Joshi](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/purvang_joshi/32/12645_2.png) [@Purvang\_Joshi](https://community.glideapps.com/u/Purvang_Joshi)
#### Post date: [March 26, 2021, 10:03pm UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/7 "2021-03-26T22:03:00Z")

</div>

Got it.  
I’ll try and let you know. Nice use case.

---

<div class="post-metadata">

### Author: ![gvalero](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/gvalero/32/1037_2.png) [@gvalero](https://community.glideapps.com/u/gvalero)
#### Post date: [March 26, 2021, 10:14pm UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/8 "2021-03-26T22:14:29Z")

</div>

Gracias!

You can see what I try to do watching my post

> [@A real notification using Glide and IoT](https://community.glideapps.com/t/a-real-notification-using-glide-and-iot/24163):
>
> Hi people! Here I bring another tool to make Glide APPs more useful and smarter. Many of us have asked and looked for a solution to have a notification when a form, order or event is sent/received from our APP and some workarounds can be used depending on use case. In my case, I wanted to have a real notification beyond a phone or PC and turn on/off a display, monitor, alarm siren, etc when an event on my APP is fired and I think I have the solution using IoT technology and Webhooks. Here is …

But now, I try to improve the message sent by my APP.

Saludos

---

<div class="post-metadata">

### Author: ![Robert\_Petitto](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/robert_petitto/32/25193_2.png) [@Robert\_Petitto](https://community.glideapps.com/u/Robert_Petitto)
#### Post date: [March 26, 2021, 10:50pm UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/9 "2021-03-26T22:50:27Z")

</div>

Exactly. Autocrat is nice if you don’t mind the wait …

---

<div class="post-metadata">

### Author: ![Pratik\_Shah](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/pratik_shah/32/12416_2.png) [@Pratik\_Shah](https://community.glideapps.com/u/Pratik_Shah)
#### Post date: [March 27, 2021, 4:35am UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/10 "2021-03-27T04:35:28Z")

</div>

That’s great @Purvang_Joshi Thank you so much for this.

In addition to PDF, can we a share Google Doc on email? I want to allow my user to edit the merged doc.

---

<div class="post-metadata">

### Author: ![Wiz.Wazeer](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/wiz.wazeer/32/72423_2.png) [@Wiz.Wazeer](https://community.glideapps.com/u/Wiz.Wazeer)
#### Post date: [March 27, 2021, 4:42am UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/11 "2021-03-27T04:42:50Z")

</div>

Great 👍 👍👍

---

<div class="post-metadata">

### Author: ![Purvang\_Joshi](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/purvang_joshi/32/12645_2.png) [@Purvang\_Joshi](https://community.glideapps.com/u/Purvang_Joshi)
#### Post date: [March 27, 2021, 6:24am UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/12 "2021-03-27T06:24:36Z")

</div>

Hey, You cannot send the doc as an attachment.

Alternatively, you can add access to the newly created google doc.  
doc\_new\_id.addEditor(“Mail ID”);

And don’t forget to remove this line “tempFolder.removeFile(doc\_new);”

---

<div class="post-metadata">

### Author: ![Pratik\_Shah](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/pratik_shah/32/12416_2.png) [@Pratik\_Shah](https://community.glideapps.com/u/Pratik_Shah)
#### Post date: [March 27, 2021, 6:51am UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/13 "2021-03-27T06:51:39Z")

</div>

Thank you

---

<div class="post-metadata">

### Author: ![Maryth\_R](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/maryth_r/32/13091_2.png) [@Maryth\_R](https://community.glideapps.com/u/Maryth_R)
#### Post date: [March 28, 2021, 2:16am UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/14 "2021-03-28T02:16:27Z")

</div>

Hi! Great work! Thanks for sharing! I am curious about sending pdfs via google slides too.

---

<div class="post-metadata">

### Author: ![Purvang\_Joshi](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/purvang_joshi/32/12645_2.png) [@Purvang\_Joshi](https://community.glideapps.com/u/Purvang_Joshi)
#### Post date: [March 30, 2021, 11:40am UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/15 "2021-03-30T11:40:59Z")

</div>

Hey @gvalero,  
I’ve used a simple method to override the existing component from the last value.

Here I’ll be showing you the script for one component.

Open any slide and create a textbox and add value Name.  
And in google sheet, set the cell header name the same as the textbox value name.

`
function TestFunction() {
var slideId = “SLIDE ID”;
var sheetId = “SHEET ID”;
var sheet = SpreadsheetApp.openById(sheetId).getSheetByName(“Sheet1”);
var values = sheet.getDataRange().getValues();
const length = values.length;
for (let i=0; i<length; i++) {
if(sheet.getRange(i+2, 1).getValue() != ‘’){
if(sheet.getRange(i+2, 7).getValue() == ‘’){
var name = sheet.getRange(i+2,1).getDisplayValue();
var f_name = sheet.getRange(i+1,1).getDisplayValue();
var empSlide = SlidesApp.openById(SlideId).getSlides()[0];
`

`empSlide.replaceAllText(f_name, name);
sheet.getRange(i+2,7).setValue(“Sent”);
}
}
}
}
`

---

<div class="post-metadata">

### Author: ![Purvang\_Joshi](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/purvang_joshi/32/12645_2.png) [@Purvang\_Joshi](https://community.glideapps.com/u/Purvang_Joshi)
#### Post date: [March 30, 2021, 11:59am UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/16 "2021-03-30T11:59:15Z")

</div>

This is the code for sending PDFs from Google Slides.

`
function doPost(e) {
```
// Calling Parameters from GlideApp
const body = JSON.parse(e.postData.contents);
const ProjectName = body["params"]["ProjectName"]["value"];
const CompanyName = body["params"]["CompanyName"]["value"];
const YourName = body["params"]["YourName"]["value"];
const YourEmail = body["params"]["YourEmail"]["value"];
const Date = body["params"]["Date"]["value"];

// Copy IDs
const tmp_slide_id = "SLIDE ID"; //Document ID
const tempFolder_id = "TempFolderID"; // Drive Folder ID

const template = DriveApp.getFileById(tmp_slide_id);

const tempFolder = DriveApp.getFolderById(tempFolder_id);
const new_slide = template.makeCopy(tempFolder).setName(ProjectName);
const new_slide_id = new_slide.getId();       
const OpenSlide = SlidesApp.openById(new_slide_id).getSlides()[0];

// Replaces all values to new ones.

OpenSlide.replaceAllText("Project name", ProjectName);
OpenSlide.replaceAllText("Date", Date);
OpenSlide.replaceAllText("YOUR COMPANY NAME", CompanyName);
OpenSlide.replaceAllText("YOUR NAME", YourName);
OpenSlide.replaceAllText("YOUR EMAIL", YourEmail);

const BLOBPDF = new_slide.getAs(MimeType.PDF);
//Remove this to store pdf to temporary folder// tempFolder.createFile(BLOBPDF).setName(ProjectName);
tempFolder.removeFile(new_slide);

const senderName = "Project Proposal";
const subject = YourName + ", you're awesome!";
const body_mail = "Please find your proposal for "+ ProjectName + "attached";
GmailApp.sendEmail(YourEmail, subject, body_mail, {
  attachments: [BLOBPDF],
  name: senderName
});
SpreadsheetApp.flush();

```
`

`}
`

---

<div class="post-metadata">

### Author: ![gvalero](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/gvalero/32/1037_2.png) [@gvalero](https://community.glideapps.com/u/gvalero)
#### Post date: [March 30, 2021, 1:37pm UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/17 "2021-03-30T13:37:38Z")

</div>

Fine, let me test and I will let you know.

Gracias Joshi

---

<div class="post-metadata">

### Author: ![gvalero](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/gvalero/32/1037_2.png) [@gvalero](https://community.glideapps.com/u/gvalero)
#### Post date: [March 31, 2021, 1:28am UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/18 "2021-03-31T01:28:38Z")

</div>

@Purvang_Joshi the solution is working!! 💪

I modified your original script, added some tricks along with a Chrome’s Add-On and now it’s working like I wished.

Tomorrow I will try to show a video to celebrate!

Thanks for your idea.

Feliz día!

---

<div class="post-metadata">

### Author: ![gvalero](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/gvalero/32/1037_2.png) [@gvalero](https://community.glideapps.com/u/gvalero)
#### Post date: [April 5, 2021, 10:55pm UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/19 "2021-04-05T22:55:10Z")

</div>

Hi @Purvang_Joshi @SantiagoPerez

Here is my newest video using the Joshi’s idea with Google Slides

Here you can see:

1. Every new order sent from my APP is shown on TV as a tool to help any personnel to receive and accept incoming orders (at a restaurant, call center, etc). On TV, I show some info about order but I might put more data and other things (orders in queue, stats) if the customer needs it.
2. I’m using Google Slides to show the Order info on TV and a script to send data from my GS to Slides as soon as a new order is registered.
3. When all received orders are accepted by administrator and there are no pending, the APP sends a command to my IoT device to turn TV off. Then, if a new order is received again, the APP will send a new command to turn TV ON as a visual notification to personnel (I could use a bell/siren but I liked the TV idea 🙂).

I hope it can help anyone in future and demonstrate that you can use Glide for this kind of things…

Saludos!

:

---

<div class="post-metadata">

### Author: ![Gregory](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/gregory/32/21180_2.png) [@Gregory](https://community.glideapps.com/u/Gregory)
#### Post date: [May 19, 2021, 12:52pm UTC](https://community.glideapps.com/t/document-merge-using-google-apps-script-webhook-action-google-docs/24782/20 "2021-05-19T12:52:58Z")

</div>

Thank you for this tutorial @Purvang_Joshi !

For complex automations I can recommend [zenphi](https://zenphi.com/).

best  
Gregor
