const LINE_CHANNEL_ACCESS_TOKEN = PropertiesService.getScriptProperties().getProperty('LINE_CHANNEL_ACCESS_TOKEN')
const cache = CacheService.getScriptCache() // default expired time: 600s(10min), max: 21600s(6hr)
const lock = LockService.getScriptLock()
const currentDate = new Date()
const currentYear = currentDate.getFullYear() // 2025
const currentMonth = currentDate.getMonth() + 1 // 0 means January
const currentDay = currentDate.getDate() // 1
function doPost(e) {
try {
let eventObj = JSON.parse(e.postData.contents)
let eventType = eventObj.events[0].type
let timestamp = eventObj.events[0].timestamp
let eventId = eventObj.events[0].message.id
let userMessage
if (eventType !== 'follow' && eventType !== 'message') {
return
}
if (eventType === 'message') {
userMessage = eventObj.events[0].message.text
if (!isCommand(userMessage)) {
return
}
}
// 防止處理相同的上傳要求兩次
if (cache.get(eventId)) {
return
}
cache.put(eventId, 'proccessed', 60)
let replyToken = eventObj.events[0].replyToken
if (!replyToken) {
console.log("No valid replyToken found.");
throw new Error('replyToken is no valid!')
}
// let sourceType = eventObj.events[0].source.type
let userID = eventObj.events[0].source.userId
// let groupID = ''
// if (sourceType === 'group') {
// groupID = eventObj.events[0].source.groupId
// }
let userName = cache.get(userID)
if (!userName) {
let userProfile = getUserProfile(replyToken, userID)
cache.put(userID, userProfile.displayName, 21600)
userName = userProfile.displayName
}
let sheet = SpreadsheetApp.openByUrl(spreadsheetUrl)
if (eventType === 'follow') {
setUserData(replyToken, userName, userID, sheet)
} else if (eventType === 'message') {
if (userMessage === '/設定基本資料') {
setUserData(replyToken, userName, userID, sheet)
} else if (userMessage === '/提醒推播測試') {
pushToUser(userID, '測試成功!')
} else if (userMessage === '/查詢提醒時間') {
let userSheet = sheet.getSheetByName('LINE_UserInfo')
let userData = userSheet.getDataRange().getValues()
checkRemindTime(replyToken, userID, userName, userData)
} else if (userMessage.startsWith('/設定提醒時間')) {
let timeString = userMessage.slice(7).trim()
if (!/^\d{1,2}$/.test(timeString)) {
replyToUser(replyToken, `「/設定提醒時間」後面只能接0~23的數字!`)
return
}
let remindTime = parseInt(timeString, 10)
if (isNaN(remindTime) || remindTime < 0 || remindTime > 23) {
replyToUser(replyToken, `「/設定提醒時間」後面只能接0~23的數字!`)
return
}
let userSheet = sheet.getSheetByName('LINE_UserInfo')
let userData = userSheet.getDataRange().getValues()
updateRemindTime(replyToken, remindTime, userID, userName, userSheet, userData)
} else {
let workSheet = sheet.getSheetByName('美術部')
let lastRow = workSheet.getLastRow()
let lastColumn = workSheet.getLastColumn()
let startRow = getStartRow(replyToken, workSheet)
let dateData = workSheet.getRange(startRow, 1, lastRow, 2).getValues()
let usersCellSet = workSheet.getRange(1, 1, 1, lastColumn).getValues()
let todayRow = getTodayRow(dateData, startRow)
let userColumn = findUserColumn(userID, usersCellSet, lastColumn)
if (!todayRow || !userColumn) {
replyToUser(replyToken, '找不到todayRow或userColumn!')
return
}
if (userMessage === '/查詢今日上傳內容') {
checkTodayProgress(replyToken, todayRow, userColumn, userName, workSheet)
} else if (userMessage.includes('/上傳進度')) {
let cleanText = userMessage.replace(/@\S+\s*/g, "").trim()
let progressText = cleanText.split('/上傳進度')[1].trim()
updateProgress(replyToken, todayRow, userColumn, userName, progressText, workSheet)
}
}
}
// 紀錄log到event_log
let eventLog = sheet.getSheetByName('event_log')
let logTime = new Date(timestamp)
lock.waitLock(30000)
eventLog.appendRow([userID, userName, eventId, logTime])
SpreadsheetApp.flush() // 將所有待處理的變更提交至試算表。
lock.releaseLock()
} catch (error) {
console.log('doPost failed!', error.message)
} finally {
lock.releaseLock()
}
}
function isCommand(userMessage = '') {
const commands = ['/設定基本資料', '/提醒推播測試', '/查詢今日上傳內容', '/查詢提醒時間']
let result = false
if (commands.includes(userMessage)) {
result = true
} else if (userMessage.includes('/上傳進度')) {
result = true
} else if (userMessage.startsWith('/設定提醒時間')) {
result = true
}
return result
}