很多在大型企業上班的人,一定都遇過這個痛點: 公司的 Outlook 日曆鎖得死死的,不對外開放 Microsoft Graph API,也封鎖了 Google Calendar 等一切外部同步通道。每次想在手機上確認工作行程,都得手動手動再手動,極度沒有效率。

身為一個「把寫程式當作效率工具」的非典型開發者,我實在無法忍受這種重複勞動。既然正規的「Server-to-Server」路徑被封死,那我決定走一條最迂迴、也最有趣的「瀏覽器端直連」路徑:

「只要我的瀏覽器能看得到日曆,我就有辦法把它送出去。」

原本以為只是簡單重寫 window.fetch 攔截 API 就搞定,動手後才發現微軟的防禦力驚人,這中間我踩過了三個超級大坑,最後用了一個非常 Geek 的架構成功打通。

🛠️ 終極同步架構拆解

1. 突破 Web Worker 的網路隔離(最大難關 💀)

現在新版的 Outlook 網頁版(OWA)為了效能,將日曆資料的請求與解析全部移到了背景的 Web Worker (DataWorker) 中執行。因為 Worker 運作在獨立的線程(Thread),我們在網頁主線程重寫 window.fetch 根本是瞎子摸象,完全攔截不到封包!

  • 解法:我直接劫持了主線程的 MessagePort.prototype.addEventListener。當背景 Worker 處理完行程、準備透過 postMessage 將 JavaScript 物件傳回主畫面渲染的瞬間,直接在通訊通道(Message Channel)上將資料攔截下來!

2. 深度遞迴掃描與雜訊過濾

攔截到 Message 後,發現微軟傳遞的 JSON 結構極度龐大且複雜。而且裡面混雜了大量「系統區塊」(例如每天的彈性工作時間灰色背景,這根本不是真實行程),且行程 ID 的 Base64 編碼中常常帶有斜線 /,會破壞資料結構。

  • 解法:寫一個「深度優先(DFS)」的遞迴掃描器,自動在複雜的 JSON 樹狀結構中,精準剝離出含有主題、時間、地點的真實行程,並自動過濾掉系統隱藏區塊。同時,對行程 ID 進行「消毒(Sanitize)」,把斜線全換成底線。

3. 繞過網頁 Content Security Policy (CSP) 限制

在 Outlook 網頁中,嚴格的 CSP 限制會阻擋我們直接向外部 API 發送請求。

  • 解法:利用 Tampermonkey 的特權 API GM_xmlhttpRequest。它是從瀏覽器擴充功能的背景(Background)發出請求,完全不受 Outlook 網頁端的 CSP 限制。我將整理好的行程資料,直接 POST 到我部署好的 Google Apps Script (GAS) Web App。

4. Google Apps Script 實時無感同步

GAS Web App 收到 POST 請求後,自動比對 Google 日曆上現有的行程描述(比對我們自訂塞進去的 Outlook ID),若不存在就建立,若時間或地點有變動就直接更新(Deduplication & Upsert)。

💡 實測成果

現在,只要我上班開著 Outlook 瀏覽日曆,Userscript 就會在背景默默把資料推送到 GAS Web App。

  • 零時差:網頁載入或切換月份的瞬間,Google Calendar 馬上同步更新。

  • 零維護:不需要 Firebase 資料庫,不用維持任何伺服器運行,完全無感。

用技術手段(科學)解決現實世界的效率障礙,用駭客精神(哲學)笑看 corporate 嚴格卻留有縫隙的安全限制。

有些路雖然迂迴,但沿途解決問題的風景,才是寫程式最讓人著迷的地方。驗證成功,爽快!

#GitHub #Userscript #GoogleAppsScript #Outlook #Productivity #HackerSpirit #WebWorker #Tampermonkey

創作者介紹
創作者 發卡布洛 的頭像
bshadow

發卡布洛

bshadow 發表在 痞客邦 留言(0) 人氣( 16 )