透過電子郵件中的圖片作為電子郵件讀取紀錄的發送管道。
前言
當企業在發送重要通知給內部員工時,後台會需要了解通知成效為何,因此希望在員工讀取郵件當下回傳訊息給伺服端,作為通知達成率的統計依據;筆者最近就是接收到這項任務,BUT 電子郵件當然不會允許我們直接插入一段 JavaScript 來送出訊息,因此我們可以透過一張圖片間接地完成這項任務。以下介紹。
切入既有系統
在企業中對於發送郵件/簡訊之類的服務通常都會有一張資料表記錄這些資訊,然後透過排程或服務定期掃那張資料表,將未發送的資料依據發送型態執行發送任務,最後將執行結果回寫回資料表中。
通知編號 | 發送目標 | 發送內容 | 發送時間 | 發送狀態 | 讀取時間 |
1020114 | emp01@gmail.com | <p>通知晉升</p> | 2018/01/10 11:11:11 | 成功 | |
1020115 | emp02@gmail.com | <p>請假代理</p> |
我們只要針對實際執行發送郵件的那隻程式動手就好,不需要動到所有寫入資料表的程式邏輯;因為既然可以發送資料,必定可以獲得「通知編號」及「發送內容」這兩個最重要的東西,而取得這兩項資訊的目的如下。
- 通知編號:作為讀取項目的識別碼 Key
- 發送內容:補上一張看不見的 img 標籤,在下載 img 過程中將「通知編號」向後傳遞
圖片來源
在郵件中出現一張圖是在合理不過的事情了,我們可以透過讀取郵件圖片的當下來傳遞「發送編號」給伺服端,好讓系統在取得這個編號後去註記該則郵件已被讀取。
以下 img 為例,在讀取這張照片的時候會向 http://xx.xx.xx.xx/log/readMail/ 發出一個包含參數動作為 Get 的 HTTP Request,而在 Web API 端就可以獲得 1020114 這個參數值來註記該則郵件已被讀取。
最後只要在發送郵件的那支程式做調整,在郵件發送前於內容加入 img 標籤,讓每一封郵件 img 標籤擁有自己的通知編號;當收到郵件的用戶開啟後讀取圖片時,就可以將該郵件專屬的編號送出讓後端識別。
建立 Web API
萬事俱備只欠東風,因此依據先前的需求開發一隻 Web API 就搞定了。
[Route("readMail/{pushNoticeSerilNo}")]
[HttpGet]
public HttpResponseMessage GetReadMail(int pushNoticeSerilNo)
{
// 依據 pushNoticeSerilNo 註記該則 Mail 通知已被讀取
service.PushService.UpdatePushMailRead(pushNoticeSerilNo);
// 回傳圖片
var imagePath = HttpContext.Current.Server.MapPath($@"~/image/transparent.png");
FileStream file = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StreamContent(file);
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/png");
return response;
}
Outlook 限制
筆者測試過這個機制在 Web Mail - Gmail 或手持式裝置都是可以正常運作 (相信其他 Web Mail 也是相同),但面對 Outlook 預設不自動下載圖片的安全性設定下,那就真的沒辦法了。
希望此篇文章可以幫助到需要的人
若內容有誤或有其他建議請不吝留言給筆者喔 !