透過Google表單+ App Script建立合約產生器
前言
家裡目前為太陽能工程開發產業
除了承包工程之外
有時候也會自購小型的電廠
也就是跟地主簽約
地主提供場地(可能是廢棄池塘、污染農地、畜舍屋頂、工廠屋頂)給我們建置太陽能電廠
我們則要每個月支付租金給地主
因此我們需要與地主簽訂合約
每一個案場的合約基本上都大同小異
除了甲方(屋主)基本資料換掉之外
再來就是依照每個案場與屋主協議結果會有不同的支付租金方式(年繳或月繳)
身為軟體工程師
這種重複性的東西看到之後第一個直覺
就是拆成變數抽出來換成其他方式填入就好
可以直接透過軟體手段偷懶
所以我在編好第一個份合約之後
就開始著手這個專案
專案需求
完整操作影片如下
前面有提到要把重複的東西抽成變數
簡單做的話其實就透過google表單填入這些不同的變數即可
至於合約的部份就用一個google文件來做範本樣板
最後就是透過google app script的trigger在收到表單提交的事件時
自動執行一些app script來更換google文件樣板的變數
然後自動輸出到指定google drive目錄即可
表單
首先我們把合約重複性資料抽出來做成表單
以下用簡單的幾個資料做範例
合約文件樣板
以下用簡化後的合約示範
將變數的部份使用雙花括號框起來
設定App Script並觀察收到的表單資料格式
建立App Script
首先
在表單的回覆google sheet中
選擇擴充功能>App Script開啟一個新的App Script專案
先設定log印出完整的資料
首先先定義一個createContract method
透過app script Logger將整個表單event資料印出來觀察格式
方便後續規劃
設定trigger
將trigger設定在收到表單call createContract method
提交一次表單觀察log
透過執行項目可以看到整個event的資料結構
大致如下
很清楚的可以看到透過namedValues屬性可以取得表單資料
{
"authMode":"FULL",
"namedValues":{
"甲方姓名":[
"板橋"
],
"時間戳記":[
"2022/3/13 下午 5:10:12"
],
"管轄法院":[
"台中"
],
"月租金":[
"18000"
]
},
"range":{
"columnEnd":4,
"columnStart":1,
"rowEnd":6,
"rowStart":6
},
"source":{
},
"triggerUid":"10561890",
"values":[
"2022/3/13 下午 5:10:12",
"板橋",
"18000",
"台中"
]
}
開始依照需求建立google文件合約
知道合約格式後
基本上再多透過幾個app script class即可建立google文件合約
必要資料
建立資料之前首先要取得兩個參數
- 合約樣板google文件的ID(在網址列可取得)
- 要輸出的google drive目錄ID(一樣在網址列可取得)
開始設定app script
透過以下app script可依照需求題換樣板的變數
建立完整合約
function createContract(event) {
this.googleDocId = 'your-google-doc-id' // google doc ID
this.outputFolderId = 'your-google-drive-folder-id' // google drive資料夾ID
this.googleFormEventData = event
this.createDoc()
this.renderDoc()
}
// 先從樣板合約中複製出一個全新的google doc(this.doc)
function createDoc() {
const file = DriveApp.getFileById(this.googleDocId)
this.outputFolder = DriveApp.getFolderById(this.outputFolderId)
const today = Utilities.formatDate(new Date(), 'GMT', 'yyyy_MM_dd')
this.docFilename = `${today}土地租賃契約`
const copy = file.makeCopy(this.docFilename, this.outputFolder)
this.doc = DocumentApp.openById(copy.getId())
}
// 將google doc中的變數替換為表單資料
function renderDoc() {
const body = this.doc.getBody()
body.replaceText(`{{name}}`, this.getFormData('甲方姓名'))
body.replaceText(`{{amount}}`, this.getFormData('月租金'))
body.replaceText(`{{city}}`, this.getFormData('管轄法院'))
this.doc.saveAndClose()
}
// 方便取得google表單內容的method
function getFormData(property, first = true) {
if(!this.googleFormEventData) return null
if(!this.googleFormEventData.namedValues) return null
if(!this.googleFormEventData.namedValues[property]) return null
if(first == true) return this.googleFormEventData.namedValues[property][0]
return this.googleFormEventData.namedValues[property]
}
前往trigger重新授權
因為上方的app script有用到新的權限(google doc/google drive讀寫)
因此需要前往trigger重新開啟編輯popup
並點擊儲存後重新授權給app script
否則執行後將會出現You do not have permission to call權限不足的錯誤訊息
完成! 提交表單測試
完成後
直接提交表單測試
就會看到輸出目錄自動產生一個google文件合約
開啟後就會看到變數被替換為表單資料
其他進階應用
自動產出PDF
如果需求上需要直接轉成PDF也很方便
透過document class的getAs method及folder class的createFile method
就可以直接輸出PDF在google drive目錄中
const pdfBlob = this.doc.getAs('application/pdf')
this.outputFolder.createFile(pdfBlob)