目前正在使用 Line Message API 串接 Google Sheet 的实作。基本流程为:使用者在 Line 群组传送讯息 → 透过 Line Message API 传送至 Google Sheet → 处理资料后回覆至原群组。
我目前尝试了两种方法:
方案一:
- Line Message Webhook 使用 Make 平台串接,将讯息传素至 Google Sheet
- App Script 仅设定触发条件试算表 - 文件内容变更时立即通知
方案二:拆分为两个 .gs 程式码档案
- 第一个档案:Line Message Webhook,透过 App Script 网路应用程式部署,可成功将 Line 讯息写入 Google Sheet
- 第二个档案:处理 Google Sheet 资料并将回覆讯息传送至 Line 群组
- 触发指令设定成第二个档案 并且一样为试算表 - 文件内容变更时立即通知
然而,方案二无法顺利执行完整流程(从使用者输入到处理并回覆)。目前状况是:
- 讯息可以正常写入 Google Sheet
- 手动执行处理程式码时可以正常处理并传送讯息至 Line可以看到有正常被触发恳请各位前辈提供技术建议与解决方案,感谢。
[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 个回答
0
Gary
iT邦好手 1 级 ‧ 2025-02-13 13:31:51
对于方案二给几个方向建议,可能与触发条件或权限有关,可以参考:
- 检查Google Apps Script中文件内容变更的触发器。确保设定的是修改而非新增。
- 确认触发器是否与修改Google Sheet行动同步。可以手动触发测试,看是否成功。
- 关于提到手动执行程式码可正常执行,可能是自动化的执行权限有问题,检查是否正确授权 Apps Script执行操作并回传讯息。
- 最后触发后讯息如果没即时,可能处理时间延迟或处理逻辑上有瓶颈,特别针对需要与外部服务如:Line API 交换资讯。可考虑加入延迟或排程,让讯息能被正确。
-
2 -
-
win895564
iT邦研究生 5 级 ‧
2025-02-13 16:01:17
感谢回复已补充相关程式码跟图片
1.目前为文件内容变更时立即通知
2.触发器的部分有测试过在google sheet直接添加一笔资料是可以正常传到line
3.想了解这个授权的部分该去哪里确认,目前是一开始建立的时候 执行程式码会有需要授权的页面,已经有授权
4.这部分我在加入测试看看,感谢
修改
Gary
iT邦好手 1 级 ‧
2025-02-14 10:00:30
- 确认 Apps Script 触发器类型
- Simple Triggers:如 onEdit(e) 无法存取 Google API,可能导致错误。
- Installable Triggers:需要使用者授权,可存取 Google API。
- 确认 Apps Script OAuth 授权
- 检查专案範围权限Apps Script → 专案设定检查是否包含所需API
- 执行Apps Script触发OAuth授权,或重启Apps Script API
-
确认 Google Workspace 管理设定,API 存取权限控制允许 Apps Script 存取 Google API
-
确认外部 API 存取权限,Apps Script 网路未被公司防火墙或 Google 限制。
2. 确认 Apps Script OAuth 授权
* 检查专案範围权限Apps Script → 专案设定检查是否包含所需API
* 执行Apps Script触发OAuth授权,或重启Apps Script API
3. 确认 Google Workspace 管理设定,API 存取权限控制允许 Apps Script 存取 Google API
4. 确认外部 API 存取权限,Apps Script 网路未被公司防火墙或 Google 限制。
修改