Hike News
Hike News

用 Line Notify 通知當天活動

接續前一篇的 用 Line Notify 通知行事曆行程

試用幾天發現 2 個問題:

  1. 當有 全天的活動 的時候是不會被傳送,只會傳送 有設定時間的活動
  2. 活動說明取得時是有包括 HTML 的標籤,所以 LINE 收到時會出現許多的 HTML 標籤

所以現在要修改一下 傳送當天所有的活動

以及 移除活動的說明的 HTML 標籤

出現一大堆不需要的 HTML 標籤感覺還滿雜亂的

取出月曆的全部活動

關於 Calendar 文件 有寫到

  • getEvents(startTime, endTime) 取得全部有設定時間的事件

  • getEventsForDay(date) 取得指定日期當天的所有事件

    • date 的日期會乎略時間只保留日期

當中有個範例

1
2
3
4
// Determines how many events are happening today.
var today = new Date();
var events = CalendarApp.getDefaultCalendar().getEventsForDay(today);
Logger.log('Number of events: ' + events.length);

從範例可以得知

要取得當天活動的數量就算參數給完整的日期、時間、時區

getEventsForDay() 也只會抓日期

而得到的就會是 today 當天所取得的全部事件

所以寫法就可以大大縮短成

1
2
3
4
5
6
7
8
9
10
const today = new Date(),
getCalendar = CalendarApp.getCalendarById(GoogleCalendarID),
todayCalendar = getCalendar.getEventsForDay(today);
// 依序取得當天的活動事件
todayCalendar.forEach(item => {
if(todayCalendar.length > 0) {
notifyStr += (item.getTitle() != "") ? ("\n\n" + '主題: ' + item.getTitle() + "\n") : ("\n");
notifyStr += (item.getDescription() != "") ? ('內容:\n' + stripHTML(item.getDescription())) : "";
}
})

成功取得需要收到的訊息

移除 HTML 標籤

因為取出來的說明內容是包括了 HTML 標籤的字串

所以用 正則表示式 篩選出標籤的格式

關於正則表示式 MDN 參考文章 裡說到,這是被用來匹配字串中字元組合的模式。

  • 在 JavaScript 中,正則表示式也是物件
  • 可被運用在 RegExpexectest 方法中,以及 Stringmatchreplacesearchsplit 等方法中。

這裡會用到的是 replace() ,這個方法會把原本的字串紿過比對篩選後傳回一個新的字串。 說明文件

文件裡有個的範例就很適合

1
2
3
var str = 'Twas the night before Xmas...';
var newstr = str.replace(/xmas/i, 'Christmas');
console.log(newstr);

結果會回傳 Twas the night before Christmas... 字串

過程就是 replace() 會把 str 字串內有 xmas 字串用 /i 忽略大小寫 的方式比對

要修改 HTML 的話就要把比對方式改為 /g 全域並多次比對。

為什麼是多次比對呢?

再用上方的範例來試試看有不同大小字的字串時

出現第 1 個字串在比對成功後就不會再繼續了

1
2
3
4
var str = 'Xmas & xmas & xmas...';
var newstr = str.replace(/xmas/i, 'Christmas');
console.log(newstr);
// Christmas & xmas & xmas...

當改成 /g

1
2
3
var newstr = str.replace(/xmas/g, 'Christmas');
console.log(newstr);
// Xmas & Christmas & Christmas...

會出現第 1個字串沒改變是因為少加了 忽略大小寫

1
2
3
var newstr = str.replace(/xmas/gi, 'Christmas');
console.log(newstr);
// Christmas & Christmas & Christmas...

加上後就會修改每個不論大小寫的 xmas 成 Christmas

回到一開始的活動說明字串

我只需要把 <> 以及裡面所有字元 . 和空格 \s 全部 *?清空就可以了

然後再用 /g 一一刪除

1
2
3
4
function stripHTML(str) {
let reTag = /<(?:.|\s)*?>/g;
return str.replace(reTag,"");
}

程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const LineNotifyToken = 'abcde...',
GoogleCalendarID = 'ABCED...',
today = new Date(),
getCalendar = CalendarApp.getCalendarById(GoogleCalendarID),
todayCalendar = getCalendar.getEventsForDay(today);

function SendNotify() {
let notifyStr = '';
todayCalendar.forEach(item => {
if(todayCalendar.length > 0) {
notifyStr += (item.getTitle() != "") ? ("\n\n" + '主題: ' + item.getTitle() + "\n") : ("\n");
notifyStr += (item.getDescription() != "") ? ('內容:\n' + stripHTML(item.getDescription())) : "";
}
})

function stripHTML(str) {
let reTag = /<(?:.|\s)*?>/g;
return str.replace(reTag,"");
}

UrlFetchApp.fetch("https://notify-api.line.me/api/notify", {
"method" : "post",
"payload" : {"message" : notifyStr},
"headers" : {"Authorization" : "Bearer " + LineNotifyToken}
});
}