6

設定 Outlook 收件匣規則對特定通知信進行花式處理 - 使用 VBA 巨集

 1 year ago
source link: https://blog.darkthread.net/blog/outlook-vba-for-rule/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

設定 Outlook 收件匣規則對特定通知信進行花式處理

Outlook 的收件匣規則應該很多人用過,它能依據事先設定條件,將特定發信者寄來或主旨包含特定關鍵字的信件移到指定資料夾、自動轉寄,甚至直接刪除,當信如潮水般湧來時,至少有基本的分類,還可加上簡單的自動化處理,是常身陷 Email 地獄社畜們的一大救贖。

Fig1_638107745252589748.png

我有個困擾,信箱會收到大大小小系統自動寄發的通知,有些系統的做法非常簡單粗暴,一筆事件發一封,內容是近似原始 Log 的未排版文字,有些狀況一次會觸發數十上百個事件,於是 Outlook 就會迎來一波信件轟炸,因通知中可能包含重要訊息,不能置之不理,一封封看頗為煩人,也很沒效率。

當然,根本解決之道是從源頭下手,改變通知寄發頻率(例如:將五分鐘的事件彙整成一封)與訊息格式(例如:從 Log 文字擷取關鍵欄位重新排版),就能有效改善問題。不過,大家都知道,既然系統不歸自己管,這種「不方便但堪用」的小問題多半會被擺著,很難等到優化改善的一天,求人不如求己,還是想想如何自力救濟比較實際。

我先想到的做法是用寫個排程作業,定期讓 C# 程式存取 Outlook 掃收件匣(跑程式操作 Outlook 的概念可參考PowerShell 實用技巧 - 借用 Outlook 寄送電子郵件),挑出系統通知信進行彙整、取出關鍵資訊做成彙總表格另寄一封。定期輪詢簡單歸簡單,但沒啥效率,每次要重新掃瞄最近一段時間的所有來信,掃瞄頻率訂得低即時性不夠、掃瞄範圍太小怕遺漏,太頻繁範圍太大又浪費資源,很難做到優雅。

於是我想到,能不能在收件匣規則將動作設定執行 VBA 巨集?這樣就能加入天馬行空的自訂邏輯,擴充沒有極限! 查了一下,Outlook 的規則動作支援「執行指令碼」,可指定由巨集函數處理新信件。

Fig2_638107744383410320.png

但這個功能預設被停用,不會出現在動作清單,需加入 Registry HKCU\Software\Microsoft\Office\1x.0\Outlook\Security\EnableUnsafeClientMailRule DWORD 0x1 啟用:

Fig3_638107744385231262.png

至於 VBA 程式部分,則要宣告一個 Sub 方法接收 MailItem 物件參數,該物件即為新收到的信件,由 Subject、Body 可取得信件主旨、內文... 等,後續如果應用可自由發揮。

好久沒寫 VBA,想起它連 try ... catch 都沒有,流下兩行清淚,有穿越回石器時代的感覺。立即決定寫個 ASP.NET Core Minimal API 把主戰場拉回 21 世紀,在 VBA 設法組出 HTTP POST application/x-www-form-urlencoded 內容,將資料交給現代化科技後速速逃離。(VBA 甚至沒有現成程式庫可以 UrlEncode,我參考網路做法,借用 HTML DOM 跑 JavaScript encodeURIComponent(),又學到一招)

Sub ProcessQRNotify(item As Outlook.MailItem)
    On Error GoTo ErrHandle
    Dim mailBody As String
    Dim url As String
    url = "http://localhost:8888/new-event"
    mailBody = item.Body
    Dim xhr
    Set xhr = CreateObject("WinHttp.WinHttpRequest.5.1")
    xhr.Open "POST", url, False
    xhr.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
    Dim mailId As String
    xhr.Send "entryId=" & item.EntryID & "&alertContent=" & UrlEncode(mailBody)
    If (xhr.ResponseText = "OK") Then
        ''Success
    Else
        ''Fallback
    End If
    Exit Sub
ErrHandle:
    MsgBox Err.Description
End Sub

Function UrlEncode(t As String)
    Dim html
    Set html = CreateObject("htmlfile")
    With html.parentWindow
        .ExecScript "function encode(s) { return encodeURIComponent(s); }", "JScript"
    End With
    UrlEncode = html.parentWindow.encode(t)
End Function

簡單試出 PoC,看來是可行的。未來遇到雜亂的摻水的系統通知,都可以用這招提取信件內容上傳到 Web API 後製,提煉成高純度資訊,提高吸收效率,少傷一些眼睛。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK