今天延伸昨天 [Day 2] 群組不可缺的夥伴 - Line Bot Reminder 的主題,來看 GAS 內部吧
使用別人的服務最好先了解一些配置,這邊分成三個要注意的地方:
「服務」可以想像成 GAS 提供的 library ,以下是 LINE Bot 常用的:
像在這裡的 Reminder 就會用到 UrlFetchApp、ContentService、PropertiesService、ScriptApp...等
以昨天的 Line Bot Reminder 當案例:
首先,昨天也有說到,對外傳要先有 金鑰 (也就是昨天存的 LINE_CHANNEL_ACCESS_TOKEN) ,
這是 LINE 機器人的頻道存取憑證 (Channel Access Token)。
所以在一開始,我們可以先將變數/參數等設好,下面接我們所要用到的function。
const PROPS = PropertiesService.getScriptProperties();
function readToken_() {
const t = PROPS.getProperty('LINE_CHANNEL_ACCESS_TOKEN');
if (!t) throw new Error('缺少 LINE_CHANNEL_ACCESS_TOKEN(Script Properties)');
return t;
}
const REMINDER_TEXT = '🔔 每日最後提醒:請在今天上傳/填寫妳的 iThome 喔~';
doPost(e)
)function doPost(e) {
const out = ContentService.createTextOutput('OK').setMimeType(ContentService.MimeType.TEXT);
try {
const raw = (e && e.postData && e.postData.contents) ? e.postData.contents : '';
if (!raw) return out; // Verify/健康檢查 → 直接 200
const body = JSON.parse(raw);
const events = body.events || [];
const has = PROPS.getProperty('GROUP_ID');
for (const ev of events) {
if (!has && ev.source && ev.source.type === 'group' && ev.source.groupId) {
PROPS.setProperty('GROUP_ID', ev.source.groupId); // 只存一次
console.log('Saved GROUP_ID=' + ev.source.groupId);
}
}
} catch (err) { console.error('doPost error:', err); }
return out;
}
groupId
),並使用 PROPS.setProperty('GROUP_ID', ...)
將其儲存一次到指令碼屬性中。doGet(e)
)function doGet() { // 健康檢查
return ContentService.createTextOutput('ok');
}
sendDailyReminder()
)function sendDailyReminder() {
const groupId = PROPS.getProperty('GROUP_ID');
if (!groupId) {
console.log('GROUP_ID 未設定,請先完成一次性 Webhook 擷取流程。');
return;
}
const url = 'https://api.line.me/v2/bot/message/push';
const payload = {
to: groupId,
messages: [{ type: 'text', text: REMINDER_TEXT }]
};
const options = {
method: 'post',
headers: { 'Authorization': 'Bearer ' + readToken_() },
contentType: 'application/json',
payload: JSON.stringify(payload),
muteHttpExceptions: true
};
const res = UrlFetchApp.fetch(url, options);
console.log('Push result: ' + res.getResponseCode() + ' - ' + res.getContentText());
}
setupDailyTrigger()
)function setupDailyTrigger() {
ScriptApp.getProjectTriggers()
.filter(t => t.getHandlerFunction() === 'sendDailyReminder')
.forEach(t => ScriptApp.deleteTrigger(t));
ScriptApp.newTrigger('sendDailyReminder')
.timeBased()
.atHour(20) // 20:00
.everyDays(1)
.create();
console.log('Daily trigger created for 20:00 Asia/Taipei.');
}
showGroupId()
)function showGroupId() {
console.log('GROUP_ID = ' + (PROPS.getProperty('GROUP_ID') || '(尚未擷取)'));
}
今天就先到這裡 明天以這個基礎做延伸 做一個幫忙健康管理的 bot~