2021/02/23

Gg / Google Forms自動寄出確認信 版本2

在前一篇文章 Gg / Google Forms自動寄出確認信

利用了最簡單的方式讓表單寄出自動回覆信件

而信件的內容是引用一個固定的html內容

這個方式的缺點是無法客製化回應內容

例如:呈現填表人所填寫的內容

Google表單,提交後系統自動寄送回覆通知email

有提供一個透過表單連結的試算表作為資料來源

然後運用類似”資料套印”的方式結合html模板

達成客製化的效果

Telegram Bot學習筆記-6:Google表單提交時收到通知

雖然是用機器人發訊息的例子,但有提到不用試算表抓取資料的方式

綜合這兩篇,我嘗試只用表單的script,不套用html模板、不連結試算表的方式來呈現填寫內容

筆記一下要注意的點

1.Google Apps Script 不能在程式碼裡直接輸出Html程式碼

必須經過轉換,可以參考Google的說明

Due to security considerations, scripts cannot directly return HTML to a browser. Instead, they must sanitize it so that it cannot perform malicious actions. 

2.信件內容

最初的 變數 answer 是初始狀態,由於信件內容包含html程式碼,

中間的資料透過for迴圈進行累加,所以要拆成三個部分

在變數的初始狀態,包含表格前半部的程式碼

var answer = '<strong>您所填寫的表單內容:</strong><br><table align="left" border="1" cellpadding="0" cellspacing="0" width="60%"><tbody><tr><th width="20%">題目</th><th>回答內容</th></tr>';

迴圈內的 answer 除了串接資料之外,還加上對應的表格程式碼

而answer用了兩次資料累加

第一次是在 for迴圈內,由於一筆回應資料裡分別有不同的問題,跟對應的回應

所以要用累加方式來串接

answer= answer + ...

最後,第二次在迴圈外,接上表格後半部的程式碼

answer=answer + '</tbody></table>'

3.整體程式碼如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
function sendmail_4(e) {
  //取得表單資料
  var form = FormApp.openById('1fAPZGUfKf8v1DNkBVkcgWYNEeoD0KpUIgXzSOtirwMM');//編輯狀態的表單ID https://docs.google.com/forms/d/14d8Mf0bLKu8HoHK1qOSWWAL3gwDpagJkIfITdW-OQ2A/edit
  var formResponses = form.getResponses();
  
  //取得最後一筆資料
  var i = formResponses.length-1;
  var formResponse = formResponses[i];
  var itemResponses = formResponse.getItemResponses();
  
  //設定信件內容
  var answer = '<strong>您所填寫的表單內容:</strong><br><table align="left" border="1" cellpadding="0" cellspacing="0" width="60%"><tbody><tr><th width="20%">題目</th><th>回答內容</th></tr>';
  
  //取得最後一筆資料的個別問題與回應內容
  for (var j = 0; j < itemResponses.length; j++) {
    var itemResponse = itemResponses[j];
    //Logger.log('Response #%s to the question "%s" was "%s"', (i + 1).toString(), itemResponse.getItem().getTitle(), itemResponse.getResponse());
    
    //串接內容
    //var answer= answer + itemResponse.getItem().getTitle()+'--'+itemResponse.getResponse()+'<br>';
    answer= answer + '<tr><td>' + itemResponse.getItem().getTitle() + '</td><td>'+ itemResponse.getResponse() +'</td></tr>'

  }
    answer=answer + '</tbody></table>'
  //Logger.log(answer)
  
  //var output = HtmlService.createHtmlOutput(answer);
  //var htmlText = output.getContent();
  //將answer的內容轉成html  因為scripts無法直接輸出到瀏覽器
  var htmlText = HtmlService.createHtmlOutput(answer).getContent();
  
  //設定GmailApp.sendEmail()的參數
  var emailTo = e.response.getRespondentEmail(); 
  
  //表單必須設定取得電子郵件,如果用自己設計的題目來取得,就不能用這個方式 //並且是透過提交表單的觸發事件 所傳遞的
var subject ="謝謝填寫表單"; //主旨 var textBody = ""; //信件內容,因為引入html的內容,所以可以省略 var options = {htmlBody:htmlText ,name:"系統自動回覆信件",replyTo:"trico@ntnu.edu.tw" }; //除了Html內容之外,也可以設定附件、回覆地址等 if(emailTo !== undefined){ GmailApp.sendEmail(emailTo,subject,textBody,options); //GmailApp.sendEmail(emailTo,subject,textBody); } }

 

4.測試的結果

 

整理一下使用到的程式碼

1.google Apps script的物件、屬性與方法

FormApp.openById(Id)

FormApp-classs的Method

openById(Id)

Returns the Form with the specified ID.
idStringthe ID of the form to open

 

getResponses()

Form-class的Method

getResponses() 
Gets an array of all of the form's responses.

getItemResponses()

FormResponse-class的Method

getItemResponses()

Gets all item responses contained in a form response, in the same order that the items appear in the form.

GmailApp.sendEmail()

Gg / Google Forms自動寄出確認信有使用過

2.JavaScrip的共通使用方式

for 迴圈

if 判斷式

getResponses().length,length屬性

2021/02/22

Gg / Google Forms自動寄出確認信

一般網站填寫問卷通常都會有個自動回覆信件寄到填寫人的信箱

google forms 可以透過 Apps Script 的方式來達成

這是參考一個外國教學影片,基本上就是完全複製程式碼

要注意的是Apps Script的類別、屬性跟方法寫法的大小寫,以及該有( )的不能少

部分功能也因為介面的改版而有所差異

例如:影片中利用 log來除錯的方式,現在都要在Apps Script 資訊主頁查看記錄

→如果是用新版的編輯器,會在編輯欄下方有個即時視窗

跟之前利用google試算表寄信一樣,我的個人帳號都會封鎖使用Apps Script

但是用G-Suite的帳號就不會,不知道是不是有版本的差異,還是我的個人帳號安全設定有問題

→後來發現是我個人帳號的問題,一直都無法解決,所以改用其他帳號

程式的部份分為兩個部分

1. gs的Script;2.要顯示的html信件內容

1. gs的Script

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
function sendmail(e) {
  //抓取 email要呈現的Html內容
  var html = HtmlService.createTemplateFromFile("email.html");
  var htmlText = html.evaluate().getContent();
  
  //設定GmailApp.sendEmail()的參數
  var emailTo = e.response.getRespondentEmail(); 
  //表單必須設定取得電子郵件,如果用自己設計的題目來取得,就不能用這個方式 //並且是透過提交表單的觸發事件所傳遞的
  var subject ="謝謝填寫表單";
  //主旨
  var textBody ="請注意";
  //信件內容,因為使用Html來呈現,所以這邊的內容其實會看不到
  var options = {htmlBody:htmlText};
  //除了Html內容之外,也可以設定附件、回覆地址等

  if(emailTo !== undefined){
    GmailApp.sendEmail(emailTo,subject,textBody,options)
  }
}

 

2.要顯示的html信件內容

1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <P>謝謝填寫本表單</P>
  </body>
</html>

 

整理一下使用到的程式碼

HtmlService.createHtmlOutputFromFile(filename)

HtmlService-class的Methods

Creates a new HtmlOutput object from a file in the code editor.

e.response.getRespondentEmail()

e.response 是表單提交觸發事件所傳出的物件,跟表單回應的物件不一樣-Google Forms events的說明文件

A FormResponse object, representing the user's response to the form as a whole.

表單回應的物件在FormResponse可以查到getRespondentEmail()的用法

Gets the email address of the person who submitted a response, if the Form.setCollectEmail(collect) setting is enabled.

GmailApp.sendEmail(recipient, subject, body, options)

GmailApp-class的Methods

GmailApp

Provides access to Gmail threads, messages, and labels.

sendEmail(recipient, subject, body, options)

Sends an email message with optional arguments.
recipientStringthe addresses of the recipient
subjectStringthe subject line (250 characters maximum)
bodyStringthe body of the email
optionsObjecta JavaScript object that specifies advanced parameters

 

參考資料

Google-Apps Script FormResponse的說明
Google-Apps Script GmailApp的說明