目前正在使用 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

对于方案二给几个方向建议,可能与触发条件或权限有关,可以参考:

  1. 检查Google Apps Script中文件内容变更的触发器。确保设定的是修改而非新增。
  2. 确认触发器是否与修改Google Sheet行动同步。可以手动触发测试,看是否成功。
  3. 关于提到手动执行程式码可正常执行,可能是自动化的执行权限有问题,检查是否正确授权 Apps Script执行操作并回传讯息。
  4. 最后触发后讯息如果没即时,可能处理时间延迟或处理逻辑上有瓶颈,特别针对需要与外部服务如: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

  1. 确认 Apps Script 触发器类型
  • Simple Triggers:如 onEdit(e) 无法存取 Google API,可能导致错误。
  • Installable Triggers:需要使用者授权,可存取 Google API。
  1. 确认 Apps Script OAuth 授权
  • 检查专案範围权限Apps Script → 专案设定检查是否包含所需API
  • 执行Apps Script触发OAuth授权,或重启Apps Script API
  1. 确认 Google Workspace 管理设定,API 存取权限控制允许 Apps Script 存取 Google API

  2. 确认外部 API 存取权限,Apps Script 网路未被公司防火墙或 Google 限制。

修改