<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>V8 on Tarragon</title><link>https://tarrragon.github.io/blog/tags/v8/</link><description>Recent content in V8 on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Mon, 06 Jul 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/v8/index.xml" rel="self" type="application/rss+xml"/><item><title>Apps Script 是什麼、跟一般伺服器差在哪</title><link>https://tarrragon.github.io/blog/automation/01-apps-script-basics/what-is-apps-script/</link><pubDate>Mon, 06 Jul 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/automation/01-apps-script-basics/what-is-apps-script/</guid><description>&lt;p>Apps Script 是 Google 托管的 JavaScript 執行環境：你寫的程式碼跑在 Google 的伺服器上、用 V8 引擎執行，對個人 Google 帳號免費。它的定位是「膠水」——用少量程式碼把 Google 的服務（試算表、Gmail、日曆、雲端硬碟）跟外部串起來，補上這些服務單靠介面做不到的自動化。對流量統計這個案例，它扮演的是接住 beacon、把資料寫進 Sheet 的接收端。&lt;/p>
&lt;h2 id="沒有常駐程序跟一般伺服器最大的差別">沒有常駐程序：跟一般伺服器最大的差別&lt;/h2>
&lt;p>Apps Script 跟一台伺服器最根本的差別是&lt;strong>沒有一個常駐、屬於你的程序&lt;/strong>。一般伺服器是一支持續執行的程式，開機後一直在記憶體裡等請求；Apps Script 的程式碼平時不執行，只在被觸發（有人打 web app 網址、觸發器到點、你手動按執行）時才啟動一個執行實例，跑完就結束。這個模型帶來幾個要先知道的取捨：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>不必管主機&lt;/strong>：沒有作業系統要維護、沒有開關機、沒有閒置費用。程式碼不跑時完全不佔資源。&lt;/li>
&lt;li>&lt;strong>每次執行是獨立的&lt;/strong>：兩次執行之間，記憶體裡的變數不會保留。要跨執行記住東西，得寫進外部儲存（Sheet、&lt;code>PropertiesService&lt;/code>、Drive）。這跟伺服器可以用行程內記憶體 cache 是相反的。&lt;/li>
&lt;li>&lt;strong>有執行上限&lt;/strong>：單次執行最長 6 分鐘、同時併發有數量限制。長時間或高併發的工作不適合，細節見&lt;a href="https://tarrragon.github.io/blog/automation/knowledge-cards/execution-quota/" data-link-title="Execution Quota（執行配額）" data-link-desc="Apps Script 個人帳號的執行時間、同時併發與觸發器每日總時間上限，決定免費膠水層能承受多大的量">執行配額&lt;/a>。&lt;/li>
&lt;/ul>
&lt;p>理解「沒有常駐程序」才知道 Apps Script 適合什麼：短、偶發、由事件觸發的工作，例如「接一則 beacon 寫一列」「每天彙總一次」。不適合的是需要持續連線、低延遲、或狀態常駐記憶體的服務。&lt;/p>
&lt;h2 id="容器綁定-vs-獨立專案">容器綁定 vs 獨立專案&lt;/h2>
&lt;p>Apps Script 專案有兩種存在形式，差別在「它跟一個 Google 檔案綁不綁定」。&lt;/p>
&lt;p>&lt;strong>容器綁定（container-bound）&lt;/strong> 的專案依附在一個具體檔案上——從某張試算表的 &lt;code>擴充功能 → Apps Script&lt;/code> 開出來的專案，就綁定那張試算表。它的好處是程式裡用 &lt;code>SpreadsheetApp.getActiveSpreadsheet()&lt;/code> 直接拿到那張表，不必記檔案 ID；流量統計用這種，程式跟資料表天生綁在一起，最省事。它也能存取容器檔案特有的事件（例如試算表的 &lt;code>onEdit&lt;/code>、表單的 &lt;code>onFormSubmit&lt;/code>）。&lt;/p>
&lt;p>&lt;strong>獨立專案（standalone）&lt;/strong> 不依附任何檔案，從 &lt;code>script.google.com&lt;/code> 直接建立。它適合「不特別綁一個檔案」的工具，或要跨多個檔案操作的情境；存取試算表要用 &lt;code>SpreadsheetApp.openById(&amp;quot;表的ID&amp;quot;)&lt;/code> 明確指定。&lt;/p>
&lt;p>選擇判準很直接：&lt;strong>這段程式主要就是服務某一個檔案嗎&lt;/strong>——是（流量統計服務那張 log 表），用容器綁定；否（一個要操作很多表的通用工具），用獨立專案。&lt;/p>
&lt;h2 id="用到的服務">用到的服務&lt;/h2>
&lt;p>Apps Script 透過一組內建服務物件操作 Google 資源，這個案例會碰到的主要是：&lt;/p>
&lt;ul>
&lt;li>&lt;code>SpreadsheetApp&lt;/code>：讀寫試算表，&lt;code>appendRow&lt;/code>、&lt;code>getRange&lt;/code> 等，是資料的儲存層（模組三詳談）。&lt;/li>
&lt;li>&lt;code>ContentService&lt;/code>：產生 web app 的回應內容，&lt;code>doPost&lt;/code> 必須回傳它的輸出。&lt;/li>
&lt;li>&lt;code>ScriptApp&lt;/code>：管理觸發器，時間排程彙總會用到（模組四）。&lt;/li>
&lt;li>&lt;code>PropertiesService&lt;/code>：存少量 key-value 設定或狀態，適合放「上次處理到哪一列」這種跨執行要記住的小資料。&lt;/li>
&lt;/ul>
&lt;p>這些服務都以你的 Google 帳號身分執行、受你的授權範圍約束，授權模型是下一篇&lt;a href="https://tarrragon.github.io/blog/automation/01-apps-script-basics/web-app-deployment-model/" data-link-title="web app 部署模型與授權" data-link-desc="把 Apps Script 掛成可被 HTTP 呼叫的端點時，doGet/doPost 進入點、exec 與 dev 兩種網址、以及更新部署為什麼要用同一個網址">web app 部署模型&lt;/a>的主題。&lt;/p>
&lt;h2 id="下一步">下一步&lt;/h2>
&lt;p>知道 Apps Script 是什麼之後，要讓它能被 blog 的 beacon 打到，得把它部署成有公開網址的 web app。部署模型、&lt;code>doGet&lt;/code>/&lt;code>doPost&lt;/code>、以及授權流程，見&lt;a href="https://tarrragon.github.io/blog/automation/01-apps-script-basics/web-app-deployment-model/" data-link-title="web app 部署模型與授權" data-link-desc="把 Apps Script 掛成可被 HTTP 呼叫的端點時，doGet/doPost 進入點、exec 與 dev 兩種網址、以及更新部署為什麼要用同一個網址">web app 部署模型&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Apps Script 是 Google 托管的 JavaScript 執行環境：你寫的程式碼跑在 Google 的伺服器上、用 V8 引擎執行，對個人 Google 帳號免費。它的定位是「膠水」——用少量程式碼把 Google 的服務（試算表、Gmail、日曆、雲端硬碟）跟外部串起來，補上這些服務單靠介面做不到的自動化。對流量統計這個案例，它扮演的是接住 beacon、把資料寫進 Sheet 的接收端。</p>
<h2 id="沒有常駐程序跟一般伺服器最大的差別">沒有常駐程序：跟一般伺服器最大的差別</h2>
<p>Apps Script 跟一台伺服器最根本的差別是<strong>沒有一個常駐、屬於你的程序</strong>。一般伺服器是一支持續執行的程式，開機後一直在記憶體裡等請求；Apps Script 的程式碼平時不執行，只在被觸發（有人打 web app 網址、觸發器到點、你手動按執行）時才啟動一個執行實例，跑完就結束。這個模型帶來幾個要先知道的取捨：</p>
<ul>
<li><strong>不必管主機</strong>：沒有作業系統要維護、沒有開關機、沒有閒置費用。程式碼不跑時完全不佔資源。</li>
<li><strong>每次執行是獨立的</strong>：兩次執行之間，記憶體裡的變數不會保留。要跨執行記住東西，得寫進外部儲存（Sheet、<code>PropertiesService</code>、Drive）。這跟伺服器可以用行程內記憶體 cache 是相反的。</li>
<li><strong>有執行上限</strong>：單次執行最長 6 分鐘、同時併發有數量限制。長時間或高併發的工作不適合，細節見<a href="/blog/automation/knowledge-cards/execution-quota/" data-link-title="Execution Quota（執行配額）" data-link-desc="Apps Script 個人帳號的執行時間、同時併發與觸發器每日總時間上限，決定免費膠水層能承受多大的量">執行配額</a>。</li>
</ul>
<p>理解「沒有常駐程序」才知道 Apps Script 適合什麼：短、偶發、由事件觸發的工作，例如「接一則 beacon 寫一列」「每天彙總一次」。不適合的是需要持續連線、低延遲、或狀態常駐記憶體的服務。</p>
<h2 id="容器綁定-vs-獨立專案">容器綁定 vs 獨立專案</h2>
<p>Apps Script 專案有兩種存在形式，差別在「它跟一個 Google 檔案綁不綁定」。</p>
<p><strong>容器綁定（container-bound）</strong> 的專案依附在一個具體檔案上——從某張試算表的 <code>擴充功能 → Apps Script</code> 開出來的專案，就綁定那張試算表。它的好處是程式裡用 <code>SpreadsheetApp.getActiveSpreadsheet()</code> 直接拿到那張表，不必記檔案 ID；流量統計用這種，程式跟資料表天生綁在一起，最省事。它也能存取容器檔案特有的事件（例如試算表的 <code>onEdit</code>、表單的 <code>onFormSubmit</code>）。</p>
<p><strong>獨立專案（standalone）</strong> 不依附任何檔案，從 <code>script.google.com</code> 直接建立。它適合「不特別綁一個檔案」的工具，或要跨多個檔案操作的情境；存取試算表要用 <code>SpreadsheetApp.openById(&quot;表的ID&quot;)</code> 明確指定。</p>
<p>選擇判準很直接：<strong>這段程式主要就是服務某一個檔案嗎</strong>——是（流量統計服務那張 log 表），用容器綁定；否（一個要操作很多表的通用工具），用獨立專案。</p>
<h2 id="用到的服務">用到的服務</h2>
<p>Apps Script 透過一組內建服務物件操作 Google 資源，這個案例會碰到的主要是：</p>
<ul>
<li><code>SpreadsheetApp</code>：讀寫試算表，<code>appendRow</code>、<code>getRange</code> 等，是資料的儲存層（模組三詳談）。</li>
<li><code>ContentService</code>：產生 web app 的回應內容，<code>doPost</code> 必須回傳它的輸出。</li>
<li><code>ScriptApp</code>：管理觸發器，時間排程彙總會用到（模組四）。</li>
<li><code>PropertiesService</code>：存少量 key-value 設定或狀態，適合放「上次處理到哪一列」這種跨執行要記住的小資料。</li>
</ul>
<p>這些服務都以你的 Google 帳號身分執行、受你的授權範圍約束，授權模型是下一篇<a href="/blog/automation/01-apps-script-basics/web-app-deployment-model/" data-link-title="web app 部署模型與授權" data-link-desc="把 Apps Script 掛成可被 HTTP 呼叫的端點時，doGet/doPost 進入點、exec 與 dev 兩種網址、以及更新部署為什麼要用同一個網址">web app 部署模型</a>的主題。</p>
<h2 id="下一步">下一步</h2>
<p>知道 Apps Script 是什麼之後，要讓它能被 blog 的 beacon 打到，得把它部署成有公開網址的 web app。部署模型、<code>doGet</code>/<code>doPost</code>、以及授權流程，見<a href="/blog/automation/01-apps-script-basics/web-app-deployment-model/" data-link-title="web app 部署模型與授權" data-link-desc="把 Apps Script 掛成可被 HTTP 呼叫的端點時，doGet/doPost 進入點、exec 與 dev 兩種網址、以及更新部署為什麼要用同一個網址">web app 部署模型</a>。</p>
]]></content:encoded></item></channel></rss>