2013年9月15日 星期日

Google表單自動寄信給填表人

2013/09/15 updated: 由於sheet的API呼叫跟Form的呼叫API不同,這邊加入Google表單的範例。
2015/02/27 updated: Google Docs的API改版了,筆者已經發布新版的寫法,請移駕至此

現在網路上教的Google Docs問卷,都只有填表格功能,難道沒有讓使用者填寫完資料後,寄一份資料到使用者信箱的功能嗎?因為我們有時候需要製作收據系統之類的

答案是有的!我們只要動幾根手指頭,依照下列步驟,就可以輕易開發出這個功能喔!請依照以下步驟一步一步跟著我做即可。
請注意,如果是直接用Google表單的話,請注意第三步驟有些不同。

開發步驟
Step 1. 先開啟Google試算表。
Step 2. 假設我的表單只有兩個欄位:姓名Mail。按上方工具列,選擇工具表單編輯表格,先建立表單內容,然後按下存檔。

Step 3. 回到Google表格編輯頁,這次請選擇工具指令碼編輯器,出現程式碼視窗後,輸入下列程式碼,如 2 (標題與內容請自行修改),這邊有Google試算表跟表單兩種不同API實現方式,請注意一開始是使用Google表單還是試算表製作

(Google試算表版本)

(Google表單版本)


Step 4. 接著在工具列上面,選擇觸發器”→現有指令碼的觸發程序

Step 5. 由於現在都沒有加入任何觸發器,因此我們可加入一個新的。
(1) 請點選”Add a new trigger”連結
(2) 設定執行的函式sendMailsEvents 來源為From spreadsheet,動作為On form submit,然後儲存關閉

這樣子就大功告成了!

實際測試
Step 1. 先進入即時表格,輸入內容,按下送出。

Step 2. 系統會提醒你回應訊息。
(
回應訊息可在編輯表單時,右上方功能列更多動作編輯確認訊息 自訂)

Step 3. 請到您的信箱確認!沒錯,訊息已經收到囉。


:沒想到這篇Post完沒多久,才發現已經有人寫好App可以安裝了。
         http://disp.cc/b/3-2oPJ

        沒關係!多學會一點,就多一項技能!


參考資料

1. Google試算表與Google App Script的自動化應用 http://www.cc.ntu.edu.tw/chinese/epaper/0019/20111220_1906.html
2. Google Apps Script: Running Scripts in Response to an Event

61 則留言:

  1. 謝謝分享,雖然已經有 FormEmailer,但這篇文章還是有其價值、可運用的地方,因為 FormEmailer 無法及時觸發,要每分鐘觸發一次,而用您提供的 script 就可以及時觸發了。

    回覆刪除
  2. 不客氣!教學相長,大家多多交流交流!

    回覆刪除
  3. 您好:最近在試學這個功能,想請問若想在信件內文換行應該加上什麼符號呢?
    看了您文末的連結仍不得其解,也不想太依賴前人種樹、想試著看點程式,
    便提出問題了,多有打擾煩請見諒!

    回覆刪除
  4. 您好,信件內的換行,請使用"<BR>"

    回覆刪除
  5. 但我加入
    後居然就無法寄信了!貼上程式碼:
    function sendMails(e) {
    var timestamp = e.values[0];
    var name = e.values[1];
    var mail = e.values[2];
    var day = e.values[4];
    var course = e.values[6];
    var meal = e.values[5];

    MailApp.sendEmail(mail, "報名結果:"+name,
    " 姓名: " + name + " 報名場次: "+day

    +" 負責:"+ course

    +" 餐點:"+ meal

    +" 如有錯誤,請mail至"

    +" 或直接重填表單,並於備註中註明「重填」,謝謝!");

    }

    懇請解惑,謝謝。

    回覆刪除
    回覆
    1. 問過朋友後,發現應該是我把
      加到變數了>"<
      提供給需要的朋友參考:
      或\n應該要加到" "裡面,
      其後的文字就能換行了!

      謝謝版主!

      刪除
  6. 請問高手,有辦法將信件「寄件人」的email address改成其他的嗎?因為有些人無法收google.com發的信件。感謝!

    回覆刪除
    回覆
    1. 這個似乎沒辦法耶。因為還是要透過Google的Mail Server發出去。

      刪除
  7. 請問此方式是否不適用於使用Yahoo信箱的作答者呢?
    我自己就是,卻在自行測試時在E-amil處填進@yahoo.com.tw,
    爾後進入信箱卻得不到來信。後來改為@gmail.com時便可行。
    不知是否有辦法能改進此問題呢?因Yahoo信箱使用者實屬不計少數。

    回覆刪除
    回覆
    1. 不好意思,近幾天出差,晚回覆了。
      關於這個問題,是不是要換成:
      myemail = "寄件人的gmail";
      MailApp.sendEmail(mail, "表單測試:"+name,"姓名:" + name + " submitted by Allen.", {replyTo:myemail});
      這樣子呢?

      刪除
  8. 您好,想請教若自動回信的資料中想取得同試算表不同工作表的欄位資料,是否可以做到?
    ex:


    var name = e.values[0];
    var mail = e.values[1];

    以上為工作表1的資料

    var num ==>為工作表2的資料

    回覆刪除
    回覆
    1. 你可以試試看這一篇提到的SpreadsheetApp.
      http://stackoverflow.com/questions/14991030/get-value-in-one-column-in-spreadsheet-using-google-apps-script

      然後,搭配openById() 這個method試試看。理當可以解。
      不過前提是這個解法需要spreadsheet有存在這個form UI中(也就是一開始開表單時,就要開兩張出來...)。
      所以,根據http://tinyurl.com/k5j6jq9 的解釋,有兩個方法可解:
      1. 要查的spreadsheet不在你填的表單中,使用spreadsheet.setActiveSheet(liveSheet); spreadsheet.deleteActiveSheet();
      應是可以解掉。

      2. 使用不同表格工作區(sheet),把要處理的資料放在不同的sheet。搭配getSheets()取得工作區列表後,再取出指定的工作區某個cell。

      刪除
    2. 您好,請問~
      如果我把資料從sheet1 indirect 到sheet2(第二個分頁)去做計算處理,在寫自動回信的時候,直接把sheet2設定為資料來源,然後按照原來的程式碼寫,這樣收到回信的時候能夠得到sheet2計算過的資料嗎?

      刪除
  9. 請問一下~
    我出現TypeError: 無法讀取 undefined 的「values」屬性。 (第 3 行,檔案名稱:程式碼)

    請問有人跟我一樣出現此錯誤嗎
    要如何修正

    回覆刪除
    回覆
    1. Bryan你好!感謝你的提醒,我已經修正程式碼了,你可以看一下我修正的程式碼。

      刪除
  10. 請問「 收件人mail 」 可以在程式中指定嗎?

    回覆刪除
    回覆
    1. "收件人mail"可以在程式中指定。只要代換一下就OK了。
      但是"送件人mail"就不行囉,一定要你的Google帳號才可以送信。

      刪除
  11. 你好
    想請問有辦法在回復的信件內容中在崁入另外一個表單嗎?

    回覆刪除
  12. 如果只是內建iframe ,可以試試看這個。
    http://www.blogjer.com/2009/04/20/how-to-embed-google-docs-into-html-pages-or-blog-post/

    回覆刪除
  13. 回覆
    1. 不好意思,後來在後面再複製一段程式碼就可以了:
      MailApp.sendEmail(myemail, "表單測試2:"+name,
      "姓名:" + name + " submitted by Allen.");

      前面宣告了myemail的值。

      刪除
    2. 您說的沒錯,感謝補完。:)

      刪除
    3. 我好像按錯了,真是抱歉,想再問一個問題,寄件人的email地址不能改,但可以修改名稱嗎?例如我的名稱是a,但是使用表單自動寄出信件時,可以改成b嗎?

      刪除
    4. 可以啊。根據 https://developers.google.com/apps-script/reference/mail/mail-app#sendEmail(String,String,String,Object)
      的API文件,假設你要呈現的名字為"王小明", 你可以這樣子寫。

      MailApp.sendEmail(userEMail, "表單測試:"+ userName,
      "姓名:" + userName + " submitted by Allen.", { name: "王小明" } );

      刪除
  14. 您好,因為我希望填表人可以收到試算表的計算結果,
    所以需要兩張工作表,第一張工作表負責收表單資料,第二張工作表計算及回信。
    簡言之,如何使用您教的方法,將第二張工作表的資料寄出?

    回覆刪除
  15. TypeError: 無法讀取 undefined 的「response」屬性。

    第四行就過不了了,請問事少打什麼東西嗎??

    回覆刪除
  16. Hi,版大,你這篇文幫助我非常多,非常感謝
    但用您的方法會出現 Type error "e" undefined,線上編譯會過不了
    我猜是因為google把參數無效了
    所以我稍微修改了一些程式,就可以用了,把程式回饋給大家

    function SendRowsMail()
    {
    var sheet = SpreadsheetApp.getActiveSheet();
    var rows = sheet.getDataRange();
    var numRows = rows.getNumRows();
    var values = rows.getValues();
    var row = values[numRows-1];
    var name = values[numRows-1][1]; //假設欄位1是姓名
    var content = "這裡填內容";
    var mail = values[numRows-1][4]; //欄位4是使用者填的Mail

    //傳送mail的方法,沒變
    MailApp.sendEmail(mail, "Twinstar表單自動回應:姓名:"+name,
    content + " \n(注意:此郵件為系統自動發出\n如有疑問請洽TwinStar粉絲團:http://www.facebook.com/twinstarkorea)");

    }

    回覆刪除
  17. 謝謝樓上的回文。:)
    老實說,最近都忙著工作跟學校的事情,都沒來得及回上面這些樓主的問題,真是不好意思啊。

    回覆刪除
  18. function sendMails(e) {
    var 時間戳記 = currentItemResponses[0].getResponse();
    var 訂購說明 = currentItemResponses[1].getResponse();
    var 訂購者姓名 = currentItemResponses[2].getResponse();
    var 訂購者FB名稱 = currentItemResponses[3].getResponse();
    var 訂購者e-mail = currentItemResponses[4].getResponse();
    var 訂購者連絡電話 = currentItemResponses[5].getResponse();
    var 收件者姓名 = currentItemResponses[6].getResponse();
    var 收件者連絡電話 = currentItemResponses[7].getResponse();
    var 收件者地址 = currentItemResponses[8].getResponse();

    陳述式之前遺漏 ;。 (第 6 行,檔案名稱:程式碼)
    請問這是什麼意思啊?謝謝

    回覆刪除
    回覆
    1. 看樣子似乎沒問題,能否私下E-Mail給我看看程式碼?
      我的E-Mail聯絡方式請點上方「關於我」欄位,可得知。

      刪除
  19. 想請教一些問題
    如果我的表單是群組在使用 產生的試算表前兩個欄位就MAIL
    類似這樣 時間戳記 使用者名稱 資料
    怎樣可以在FORM傳送時直接得到傳送者的EMAIL 自行回復呢?

    之前一直用線上debug都過不去 後來發現直接執行是不會有問題的
    是因為表單沒有傳送資料 所以程式會錯誤吧?

    回覆刪除
  20. 想請問一下,我根據上面的操作執行,我在按"執行"的這個按鍵後,它出現了一個訊息"TypeError:無法讀取 undefined的「response」屬性。(第4行,檔名稱:程式碼)

    我是copy google 表單的製作部分…

    想請問一下如何解決這個問題呢?因為我之前也曾經設置過一個自動回覆的功能。不過我那個時候是用google試算表的程式碼,結果運行ok。

    現在就不知道為什麼這一次就無法運行???
    感謝你提供的程式碼^^

    回覆刪除
    回覆
    1. 這是要有人提交表單時才執行的...因為據我了解這些指令是當有人提交表單時(記得要設trigger),讀取提交人發送的資料..

      刪除
    2. 囧,太久沒上來看這個討論串。
      這個是真的有人送出的時候才會觸發。

      刪除
  21. 你好,請問如果我要弄一個比較複雜的自動回覆功能貴作者能幫我弄一個嗎?
    http://postimg.org/image/bk0ns0qzx/
    http://postimg.org/image/x3vsm7lwt/
    [url=http://postimg.org/image/x3vsm7lwt/][img]http://s22.postimg.org/x3vsm7lwt/image.png[/img][/url]

    這個表單能夠自己創做一個隨機的號碼(就在開頭的第一句"我們已經收到你的訂單)
    而在底下能做一個藍白色條列的summary,告訴填單者於填表時的選擇,而且更會自己把數字按照系統設定計算匯價(貨價是39000, 但系統會計算並以港元顯示)

    如果有弄一個這樣的功能作者收費大約多少呢?謝謝

    回覆刪除
  22. 請問我google文件寄件人yahoo要改gmail,要怎麼更改,請教導一下,可以用淺白的話?謝謝

    回覆刪除
  23. 依照之前的經驗,寄件人只能是Gmail信箱。似乎是不能用Yahoo Mail信箱喔。

    回覆刪除
  24. 想請問一下,如果希望發出去的信件中想分配一個自動配置的 ID 該怎麼做呢?
    (每有一個人提交表單時,就自動將下一個人的ID配置為id= id'+1)
    我試著用表單中的function取得資料,但是沒辦法每次執行都依序累加一
    是不是就要修改formEmailer的程式碼了?
    該怎麼修改呢

    回覆刪除
    回覆
    1. 我想到兩種方法,提供給你參考一下

      (1) 取得現在操作的 Form 的回應數量來當作 ID
      (2) 取得現在操作的 From 底下儲存回應的 Spreadsheet 最後一筆紀錄的 ID

      參考程式碼:https://gist.github.com/ChengYuHsu/ff7cabedbd7baab22a6a

      刪除
  25. 你好 請問 如果 我需要做判定已點擊過 我該如何下手呢?
    比如當日 『 第一個 使用者 』 已經點了 下拉選單 A選項
    而當日 『 第二或第三個使用者 』就無法點擊 A選項 只能選 其他選項
    但隔日選項會重新設定 A選項 即可選擇
    請問我這個該如何編寫比較好呢?

    回覆刪除
  26. 請問能夠選擇特定時間寄送嗎?

    例如我要在指定時間日琪計出這封信給填表者而不是立即回覆

    回覆刪除
  27. 您好~我們學校想設計一個探險活動:預定50個地點,學生9班各分6組,在一個指定時間內,到達預定地點拍照上傳,依完成照片數量統計分數,,,,,目前規劃透過google協作平台插入google雲端硬碟資料夾,學生依規定拍照上傳至指定google雲端硬碟資料夾,google協作平台即可顯示該照片,即時計算分數部分只能人工判定照片檔案數量去再改google試算表,讓google協作平台即時呈現該google試算表內的統計圖表,因為照片數量頗大,人工判定有一定的難度,不知您這邊是否有google試算表可自動統計google雲端硬碟某資料夾內檔案數量的方法或其他符合活動需求的方式~tks

    回覆刪除
    回覆
    1. 抱歉太晚回覆。如果試算檔案數量的話,http://stackoverflow.com/questions/25684098/how-to-make-a-list-on-google-spreadsheet-of-all-files-in-a-google-drive-folder
      或是參照
      https://developers.google.com/apps-script/reference/drive/folder#getFiles()
      這個call method應該有解。

      刪除
  28. 想詢問目前使用GOOGLE表單,填寫問卷調查者資料填錯,後台試算表更改過後,在顯示回覆內容摘要仍是未更改前的資料,請問有辦法從後台試算表做修正嗎?

    回覆刪除
    回覆
    1. 應該是無法喔。
      目前的scripts是抓取當時表單輸入值,而不是抓取後台的試算表內容。

      刪除
  29. 你好
    若果我想用表單中輸入的數值作計算~
    例如他輸入了100
    我想利用100*10,
    再用EMAIL 寄給他應該怎樣做??

    回覆刪除
    回覆
    1. 您好!這個要另外改寫script喔。從目前開發的版本,沒有算術運算的功能。

      刪除
  30. 請問一下如何在填表者填完表後,立即回傳填表內容在視窗上…?

    回覆刪除
  31. 您好!請問我建立了一個Google form,可是只有我填寫的表格我才查看得到,別人填的我也收不到。請問我是否有設定錯了?感謝

    回覆刪除
  32. 你好 請問我想要讓填表人的EMAIL 自動記錄下來 並填入G試算表內 不知道有沒有方法可行 麻煩你了!

    回覆刪除
  33. 您好! 可以指定mail嗎?MailApp.sendEmail(email,
    要如何陳述

    回覆刪除
  34. 怹好,請問回應的總表,能如何設定只開放回應者查看自已回覆的資料總表,
    考量隱私問題~

    回覆刪除
  35. 請問sendmail的BODY內文是否有限制長度?,昨天試了一下內文長到某一種程度上就不能寄出了,但內容須那麼多,不知道有沒有替代方式?

    回覆刪除
  36. MailApp.sendEmail(userEMail, "表單測試:"+ userName,
    "姓名:" + userName + " submitted by Allen.");

    想請問回覆郵件的內容,可以更改字體大小或顏色嗎?

    回覆刪除
  37. 您好,請問我用了外掛Simply send,但是發現無法讓單選方格產生的數值,產生至回覆信件內,我可以怎麼做呢?

    回覆刪除