「明天記得繳信用卡費。」這個念頭可能在搭捷運時突然冒出來;開會時,主管又交代一句:「這份資料週五前補齊。」當下想著晚點再記,接著幾封訊息、幾通電話一來,轉眼就忘了。
以上這些生活或工作中的「差點忘記」,對你來說也是常常發生的痛點嗎?如果能直接在每天都會使用的 LINE 裡記下待辦,不必另外切換 App,也不用逐一填寫欄位,或許就能有效降低忘記的風險。使用者只要傳一句「明天早上十點交報表」,甚至丟一張繳費單截圖,AI 就能自動整理出事項、日期、時間和備註。
《數位時代》實測,用 Google 應用程式開發平台 Apps Script 與 Gemini API,全程不需要租伺服器,帶你從零打造免費的 LINE AI 待辦小幫手!
製作 LINE AI 待辦機器人前,要準備哪些工具?
建立此自動化流程需要串接4項服務。使用者僅需準備 Google 帳號和 LINE 帳號,無需具備程式撰寫背景。這4項服務皆具備免費額度或方案:
| 服務 | 系統角色 | 費用評估 |
|---|---|---|
| Google 試算表 | 存放待辦事項的資料庫 | 免費 |
| Google Apps Script | 執行程式碼的環境(無須自建伺服器) | 於 Google 免費額度內 |
| Gemini API | 語意分析中樞(拆解語音/文字指令) | 具免費層級(依官方規範動態調整) |
| LINE 官方帳號 | 前端互動介面(接收訊息與發布提醒) | 免費 |
LINE AI 待辦機器人怎麼做?4 步驟完整教學
要建立這套系統,建議先依序測試步驟 1~2 的「AI 判讀 → 寫入試算表」流程,通過無誤後再進入步驟 3 串接 LINE。
步驟 1:建立 Google 試算表,將程式碼貼進 Apps Script
打開 Google 試算表建立一個新檔案,命名為「LINE待辦助理」。網址列裡夾在兩個斜線之間的那串英數字就是 SHEET_ID,等一下設定金鑰時會用到,先存到記事本:
https://docs.google.com/spreadsheets/d/【這一串是 SHEET_ID】/edit?gid=0#gid=0
接著點上方選單「擴充功能 → Apps Script」,畫面會切換到 Apps Script 程式碼編輯區。先把預設的範例程式碼全部刪掉,並貼上以下內容並存檔(Ctrl/Cmd + S):
/**
* LINE AI 待辦助理
* 訊息/截圖 → Gemini 判讀 → 寫入試算表 →(有日期時間)建立日曆提醒 → 回覆確認
*/
const CONFIG = {
MODEL: 'gemini-3.6-flash', // 截至 2026 年 8 月的免費層可用型號;Google 會不定期停用舊版本,執行前建議到 AI Studio 或官方文件確認目前是否仍存在
TIMEZONE: 'Asia/Taipei',
};
function getSecrets_() {
const p = PropertiesService.getScriptProperties();
return {
lineToken: p.getProperty('LINE_CHANNEL_ACCESS_TOKEN'),
geminiKey: p.getProperty('GEMINI_API_KEY'),
sheetId: p.getProperty('SHEET_ID'),
};
}
// ---------- LINE 進來的每一則訊息,都會先經過這裡 ----------
function doPost(e) {
try {
const events = JSON.parse(e.postData.contents).events || [];
events.forEach(routeMessage_);
} catch (err) {
console.error('doPost 例外:' + err);
}
return ContentService.createTextOutput(JSON.stringify({ status: 'ok' }))
.setMimeType(ContentService.MimeType.JSON);
}
function routeMessage_(event) {
if (event.type !== 'message') return;
const token = event.replyToken;
const msg = event.message;
let record;
if (msg.type === 'text') {
record = interpretText_(msg.text);
} else if (msg.type === 'image') {
record = interpretImage_(fetchLineImage_(msg.id));
} else {
sendReply_(token, '目前只支援文字訊息和截圖喔!');
return;
}
writeRecord_(record);
const calendarNote = maybeCreateEvent_(record) ? '\n📅 已加入日曆並設定提醒' : '';
sendReply_(
token,
'⭕ 已記錄\n' +
'事項:' + (record.summary || '—') + '\n' +
'分類:' + (record.category || '—') + '\n' +
'日期:' + (record.date || '—') + '\n' +
'時間:' + (record.time || '—') +
calendarNote
);
}
// ---------- 呼叫 Gemini 做判讀 ----------
function buildPrompt_() {
const today = Utilities.formatDate(new Date(), CONFIG.TIMEZONE, 'yyyy-MM-dd (EEE)');
return [
'你是行政助理,負責從訊息中抽取待辦重點,今天是 ' + today + '。',
'規則:',
'- 日期一律轉成 YYYY-MM-DD;「明天」「下週三」等相對日期依今天推算。',
'- 時間一律轉成 24 小時制 HH:mm;訊息沒提到時間就留空字串。',
'- category 欄位只能填「繳費」「會議」「其他」三選一。',
'- 找不到的欄位一律回空字串,不要自行編造內容。',
'- 只回傳 JSON,不要加任何說明文字。',
'輸出格式固定為:',
'{"summary":"","category":"","date":"","time":""}',
].join('\n');
}
function interpretText_(text) {
return callGemini_({
systemInstruction: { parts: [{ text: buildPrompt_() }] },
contents: [{ parts: [{ text: text }] }],
generationConfig: { responseMimeType: 'application/json' },
});
}
function interpretImage_(base64Image) {
return callGemini_({
systemInstruction: { parts: [{ text: buildPrompt_() }] },
contents: [{
parts: [
{ text: '請讀出這張截圖的文字內容,並依規則抽取待辦重點。' },
{ inline_data: { mime_type: 'image/jpeg', data: base64Image } },
],
}],
generationConfig: { responseMimeType: 'application/json' },
});
}
function callGemini_(payload) {
const secrets = getSecrets_();
const url = 'https://generativelanguage.googleapis.com/v1beta/models/' +
CONFIG.MODEL + ':generateContent?key=' + secrets.geminiKey;
const res = UrlFetchApp.fetch(url, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload),
muteHttpExceptions: true,
});
const data = JSON.parse(res.getContentText());
if (!data.candidates || !data.candidates[0]) {
console.error('Gemini 無回應:' + res.getContentText());
return { summary: '(AI 判讀失敗,請改用文字重傳一次)', category: '', date: '', time: '' };
}
return JSON.parse(data.candidates[0].content.parts[0].text);
}
// ---------- LINE 圖片下載、回覆 ----------
function fetchLineImage_(messageId) {
const secrets = getSecrets_();
const res = UrlFetchApp.fetch(
'https://api-data.line.me/v2/bot/message/' + messageId + '/content',
{ headers: { Authorization: 'Bearer ' + secrets.lineToken }, muteHttpExceptions: true }
);
return Utilities.base64Encode(res.getContent());
}
function sendReply_(replyToken, text) {
const secrets = getSecrets_();
UrlFetchApp.fetch('https://api.line.me/v2/bot/message/reply', {
method: 'post',
contentType: 'application/json',
headers: { Authorization: 'Bearer ' + secrets.lineToken },
payload: JSON.stringify({ replyToken: replyToken, messages: [{ type: 'text', text: text }] }),
muteHttpExceptions: true,
});
}
// ---------- 寫入試算表、建立日曆事件 ----------
function writeRecord_(record) {
const secrets = getSecrets_();
const sheet = SpreadsheetApp.openById(secrets.sheetId).getSheets()[0];
sheet.appendRow([
new Date(),
record.summary || '',
record.category || '',
record.date || '',
record.time || '',
'未完成',
]);
}
function maybeCreateEvent_(record) {
if (!record.date || !record.time) return false;
const start = new Date(record.date + 'T' + record.time + ':00+08:00');
const end = new Date(start.getTime() + 30 * 60 * 1000);
const event = CalendarApp.getDefaultCalendar().createEvent(
'[' + (record.category || '待辦') + '] ' + (record.summary || ''),
start,
end
);
event.addPopupReminder(30);
return true;
}
// ---------- 手動測試用函式,接 LINE 之前先跑一遍確認邏輯正確 ----------
function initSheet() {
const secrets = getSecrets_();
const sheet = SpreadsheetApp.openById(secrets.sheetId).getSheets()[0];
sheet.getRange(1, 1, 1, 6)
.setValues([['建立時間', '事項', '分類', '日期', '時間', '狀態']])
.setFontWeight('bold');
}
function testParseSample() {
const result = interpretText_('明天早上十點要交房租,記得轉帳給房東');
console.log(JSON.stringify(result, null, 2));
writeRecord_(result);
}
步驟 2:申請 Gemini API Key,設定 Apps Script 指令碼屬性
到 Google AI Studio 用 Google 帳號登入,在左下方找到鑰匙圖示「Get API Key」並點擊進入頁面,點右上方「Create API key」,在下方選單「新增 Project」,將新 Project 簡單命名,點擊「Create Key」,就會產生一組金鑰,按右下「Copy Key」完成複製。
接著,回到 Apps Script 頁面找到齒輪圖示,進入左側選單「專案設定」後往下滑,會看到「指令碼屬性」區塊,點擊2次「新增指令碼屬性」,依照以下表格,填入兩筆屬性與值:
| 屬性 | 值 |
|---|---|
| GEMINI_API_KEY | 剛才複製的金鑰 |
| SHEET_ID | 複製的那串試算表 ID |
目前還沒拿到LINE的金鑰,因此填完後按儲存,進到測試環節。
在 Apps Script 程式碼畫面,上方函式下拉選單選 initSheet,按執行。Google 會先跳出授權確認視窗,這是第一次存取你的試算表時必經的安全機制:依畫面指示選擇帳號、點進階選項、確認允許即可,之後就不會再跳出來。跑完回試算表看,第一列應該出現「建立時間、事項、分類…」的標題列。
接著選 testParseSample 執行。成功的話,試算表會多一列「房租/繳費」的資料——代表「AI 判讀 → 寫入試算表」這階段已打通。
步驟 3:建立 LINE 官方帳號,啟用 Messaging API
這一步要提醒,LINE 從 2024 年 9 月起調整了申請流程,目前無法直接在 LINE Developers Console 建立 Messaging API Channel,而是要先用 LINE Official Account Manager 建立官方帳號,再從帳號設定裡啟用 Messaging API(啟用後系統會自動在 Developers Console 產生對應的Channel)。
首先,用自己的 LINE 帳號登入LINE Official Account Manager,點選左側選單「建立」建立一組官方帳號,填入帳號名稱、電子郵件帳號、業種等資訊後,點選「確定」。
再來,登入 LINE Developers Console,點選左側選單建立新的「Providers」,名稱可隨意,例如:個人工作區,此命名純粹是識別用途,之後可以在同一個 Provider 底下建立多個 Channel。
回到 LINE Official Account Manager,點擊進入創好的官方帳號,點選右上方的「設定」齒輪,在左側選單中點選「設定 → Messaging API」,接著點選「啟用 Messaging API」,在「選擇提供者」視窗中將剛剛建立好的「個人工作區」並同意,第二個視窗選填可跳過,第三個視窗點選「確定」即可完成建立 Messaging API。
啟用後,會看到系統自動建立的 Messaging API Channel,這時點選回到 LINE Developers Console,進入剛剛設定好的 Channel 中的「Messaging API」分頁,捲到最下方「Channel access token」按「Issue」產生金鑰,全部複製起來。
拿到 LINE 的金鑰後,回到 Apps Script 的指令碼屬性欄目,新增第三筆:
| 屬性 | 值 |
|---|---|
| LINE_CHANNEL_ACCESS_TOKEN | 剛才產生的金鑰 |
步驟 4:部署 Apps Script 網頁應用程式,設定 LINE Webhook
回到 Apps Script 程式碼介面,在右上角點「部署 → 新增部署作業」,齒輪圖示選「網頁應用程式」,設定:
執行身分:我
誰可以存取:所有人(設定錯誤將導致 Webhook 無法接收訊息)
最後按下部署並複製發布的 Webhook URL(結尾為 /exec)。
回到 LINE Developers Console 的「Messaging API」分頁,把這串網址貼進「Webhook URL」欄位並更新,接著把「Use webhook」開關打開。
記得回到 LINE Official Account Manager,左側選單點選「回應設定」,關閉「自動回應訊息」,否則系統預設回覆會干擾你提供的程式。
以上完成後,按下驗證(Verify)按鈕,若畫面出現紅字錯誤代碼,通常屬於 Apps Script 網頁應用程式轉址機制的正常現象,不代表設定失敗。
用手機掃 Channel 上方的 QR Code 加自己好友,傳一句「明天下午三點要開會」測試,如果收到「已記錄」的回覆,回頭檢查試算表有沒有新增資料,若兩邊都順利出現,就代表功能可正常使用了。
要注意的是,改動 Apps Script 程式碼後,必須進入「部署 → 管理部署作業」,點選編輯(鉛筆圖示),版本欄位選「新版本」再部署一次,改動才會真正生效;這個過程中 Webhook 網址維持不變,LINE 端的設定不用動。
LINE Bot 沒有回應怎麼辦?5 個常見錯誤與排除方法
在系統串接過程中,開發環境的設定細節常導致回傳失敗。以下為常見報錯原因與排除邏輯:
| 錯誤現象 | 技術原因與排除方法 |
|---|---|
| 修改程式碼後,LINE 無法套用新邏輯 | Apps Script 部署具有版本鎖定特性。修改程式碼後,必須重新執行部署流程,且「版本」欄位須手動切換至「新版本」,覆蓋舊有網址。 |
| LINE 後台 Verify Webhook 顯示 302 Found | Apps Script 處理 HTTP POST 請求時的轉址特性所致,屬正常架構反應。請忽略紅字,直接以手機傳送測試訊息驗證。 |
| 執行 Apps Script 時出現安全警告 | 因程式碼為個人帳號開發且未經 Google 官方安全性審查。需點擊「進階 → 前往專案名稱 → 允許」完成授權。 |
| 送出訊息後,系統完全無回應 | 檢查三項設定點:1. Webhook URL 是否正確填入且開啟。2. 部署權限是否開放給「所有人」。3. LINE 後台自動回應訊息是否確實關閉。 |
| AI 回覆欄位空缺,或判讀明顯失敗 | 確認訊息是否講清楚時間;若突然大量失敗,多半是腳本中的 MODEL 遭 Google 汰換下架,需至官方文件確認並更新型號。 |
LINE AI 待辦機器人免費嗎?使用前要知道的 3 項限制
儘管本方案能免除訂閱費用,但採用免費 API 與無伺服器環境架構,仍存在技術層面的妥協與限制。導入前需建立客觀的預期:
1. Apps Script 無法驗證 LINE Webhook 簽章
標準的 LINE 機器人開發流程中,伺服器應驗證 HTTP Header 中的 x-line-signature 確保請求來自官方。
但 Google Apps Script 的 doPost(e) 無法直接讀取 HTTP Headers,這意味著只要有人取得你的 /exec 網址,便可偽造請求寫入資料。防範方式是將網址視為密碼保管,或進階於程式碼中寫入 userId 白名單。
2. Gemini API 免費額度與模型可能調整
Google 會不定期調整 Gemini 免費層的可用模型(如原有的 gemini-2.5-flash 已遭停用)。當系統突然無回應時,通常需至 AI Studio 尋找最新的模型名稱替換。
3. 使用 Gemini API 傳送資料有隱私風險
依據 Google 規範,免費版 Gemini API 的請求內容可能被蒐集用於改善 AI 產品。建議不要利用此系統傳輸機密事項、銀行密碼或高度敏感個資。
LINE AI 待辦機器人常見問題(FAQ)
LINE 已有待辦機器人,為什麼還要自己做?
現成機器人確實門檻較低,適合輕度使用者。自製的優勢在於「資料主控權」:待辦資料儲存於您個人的 Google 帳號中,非第三方伺服器;且可高度客製化輸入辨識邏輯、提醒時間及回覆文案。
一定要建立 LINE 官方帳號嗎?
必須開設,因為 LINE 平台並無獨立的 Bot 帳號類別。但只要建立「未認證的一般官方帳號」,系統將核發隨機 ID,該帳號便不會出現在 LINE 的關鍵字搜尋結果中,僅有掃描專屬 QR Code 的人才能加入。
LINE AI 待辦機器人有使用次數限制嗎?
在 LINE 傳輸層採用「被動回覆(Reply API)」機制,僅在接收訊息時觸發回應。此管道完全免費,不計入 LINE 官方帳號每月 200 則的主動推播(Push API)額度,因此在 LINE 端沒有使用次數限制。
真正可能碰到上限的是 Gemini API 的免費用量(依請求次數計算),但個人待辦一天頂多幾則到十幾則訊息,通常遠用不到門檻,但如果是開放供多人共用,或改造為高頻率對話的客服系統,即可能觸發 API 請求上限,導致服務中斷或需綁定信用卡付費。
Gemini API 會不會拿到我的待辦內容?
使用免費版 Gemini API 時,傳送的內容有可能被用於改善 Google 的產品,因此不建議拿來記錄機密或敏感資訊;試算表與日曆本身則是你 Google 帳號下的私人資料,只有你自己看得到。
LINE AI 待辦機器人可以和家人或同事共用嗎?
技術上可行,只需將對方的 userId 加入程式的白名單陣列中。但需注意兩點限制:第一,所有人的待辦事項都會混雜在同一張試算表中;第二,所有人將共享每月 200 則的推播免費額度,極易超標。
延伸閱讀:
6種LINE自動化應用快學起來!AI回覆客戶、自動備份檔案、整理待辦事項⋯應用情境一次盤點
LINE Notify 3月底終止服務,快用替代方案!LINE Notify是什麼?為何小商家愛用?
資料來源:LINE Developers Messaging API 開發文件、Google AI Studio、LINE 官方帳號 2026 年資費方案說明
本文初稿為AI編撰,整理.編輯/蘇柔瑋
