目前正在使用 Line Message API 串接 Google Sheet 的實作。
基本流程為:
使用者在 Line 群組傳送訊息 → 透過 Line Message API 傳送至 Google Sheet → 處理資料後回覆至原群組。
我目前嘗試了兩種方法:
方案一:
方案二:拆分為兩個 .gs 程式碼檔案
然而,方案二無法順利執行完整流程(從使用者輸入到處理並回覆)。
目前狀況是:
[02/13]更
補上程式碼還有相關圖片。
另外後續我將兩段程式碼整和在一起 不使用觸發 單純部屬就可以正常執行
process_message.gs
// LINE Channel Access Token
const CHANNEL_ACCESS_TOKEN = "{token已先移除}";
// 主要處理函數
function processMessageAndSendToLine() {
try {
// 記錄開始日誌
Logger.log("開始處理訊息並發送到 Line");
// 從試算表獲取最後一列資料
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const lastRow = sheet.getLastRow();
// 確保有資料
if (lastRow <= 1) {
Logger.log("試算表中沒有資料");
return;
}
// 直接使用 D 欄位作為群組ID
const groupId = sheet.getRange(lastRow, 4).getValue();
// 使用 C 欄位作為訊息內容
const message = sheet.getRange(lastRow, 3).getValue();
Logger.log("群組ID: " + groupId);
Logger.log("訊息內容: " + message);
// 直接發送訊息到 Line
const sendResult = sendLineMessage(CHANNEL_ACCESS_TOKEN, groupId, message);
if (sendResult) {
Logger.log("成功發送訊息到 Line");
} else {
Logger.log("發送 Line 訊息失敗");
}
} catch (error) {
// 記錄任何錯誤
Logger.log("處理訊息時發生錯誤: " + error.toString());
}
}
function sendLineMessage(channelAccessToken, groupId, text) {
try {
const LINE_API_URL = 'https://api.line.me/v2/bot/message/push';
const messages = [{
type: "text",
text: text
}];
const options = {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${channelAccessToken}`,
'X-Line-Retry-Key': Utilities.getUuid()
},
payload: JSON.stringify({
to: groupId,
messages: messages
}),
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(LINE_API_URL, options);
return response.getResponseCode() === 200;
} catch (error) {
Logger.log("發送 Line 訊息錯誤: " + error.toString());
return false;
}
}
// 手動觸發函數
function manualTrigger() {
processMessageAndSendToLine();
}
webhook.gs
function doPost(e) {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName("工作表1");
try {
// 系統當前時間
var currentTime = new Date().toLocaleString();
// 解析 LINE 傳來的 JSON 資料
var postData = JSON.parse(e.postData.contents);
// 確保有事件資料
if (postData.events && postData.events.length > 0) {
var event = postData.events[0];
// 取得所需資料
var lineTime = new Date(parseInt(event.timestamp));
var formattedTime = Utilities.formatDate(lineTime, Session.getScriptTimeZone(), "yyyy/MM/dd HH:mm:ss");
var messageText = event.message ? event.message.text || "" : "";
var groupId = event.source ? event.source.groupId || "" : "";
var userId = event.source ? event.source.userId || "" : "";
// 建立要寫入的資料陣列
var rowData = [
[currentTime, formattedTime, messageText, groupId, userId, e.postData.contents]
];
// 取得最後一列的下一列
var lastRow = sheet.getLastRow() + 1;
// 明確指定要寫入的範圍(從A到F欄)
var range = sheet.getRange(lastRow, 1, 1, 6);
// 寫入資料
range.setValues(rowData);
// 設定儲存格格式(自動調整高度、文字換行等)
range.setVerticalAlignment("top");
range.setWrap(true);
}
// 回傳成功訊息給 LINE 平台
return ContentService.createTextOutput(JSON.stringify({
'status': 'success',
'code': 200
})).setMimeType(ContentService.MimeType.JSON);
} catch(error) {
// 發生錯誤時,將錯誤訊息寫入試算表
var lastRow = sheet.getLastRow() + 1;
var range = sheet.getRange(lastRow, 1, 1, 6);
range.setValues([[
currentTime,
"",
"ERROR: " + error.toString(),
"",
"",
e.postData ? e.postData.contents : "No post data"
]]);
// 回傳錯誤訊息給 LINE 平台
return ContentService.createTextOutput(JSON.stringify({
'status': 'error',
'code': 500,
'message': error.toString()
})).setMimeType(ContentService.MimeType.JSON);
}
}
function doGet(e) {
return ContentService.createTextOutput("Webhook is working.");
}
觸發圖片
對於方案二給幾個方向建議,可能與觸發條件或權限有關,可以參考:
感謝回復已補充相關程式碼跟圖片
1.目前為文件內容變更時立即通知
2.觸發器的部分有測試過在google sheet直接添加一筆資料是可以正常傳到line
3.想了解這個授權的部分該去哪裡確認,目前是一開始建立的時候 執行程式碼會有需要授權的頁面,已經有授權
4.這部分我在加入測試看看,感謝
確認 Google Workspace 管理設定,API 存取權限控制允許 Apps Script 存取 Google API
確認外部 API 存取權限,Apps Script 網路未被公司防火牆或 Google 限制。