场景

最近工作消息模块通过邮件发消息,需要有个邮件已读追踪的功能,即邮件发出去能知道是否已读并记录状态。

思路

利用阅读回执

阅读回执的原理就是发送邮件的时候,在 header 信息中增加("Disposition-Notification-To","发件人邮箱"),属于邮件协议的一部分,跟业务没什么关系。接收方打开后会回一封邮件给发送方,表明之前的邮件已读。在实测试中发现接收方可以选择是否发送回执,算是君子协定。

利用图片加载

考虑发送时默认在邮件中加一张图片,利用打开邮件时加载图片来实现,也可实现阅读次数统计。网上也有类似的邮件追踪工具,感觉可行,开始干活。

实现

可以使用 logo 或者 1*1px 的透明图片,插入到邮件中的效果如下,12345 为消息记录的id,用来与业务对应

<img src="http://域名/track?msgId=123456" id="track" style="" alt="" />

img 标签加载时是 get 请求,后台写个方法用来接请求的参数,pom 依赖和 controller 内容如下

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
@Controller
public class TrackingController {

@GetMapping("/track")
public ResponseEntity<byte[]> getImage(@RequestParam("msgId") String msgId) throws IOException {
//保存消息状态/计数,这里直接打印出来
System.out.println("消息ID:" + msgId);

ClassPathResource img = new ClassPathResource("static/ifread.png");
byte[] imageBytes = Files.readAllBytes(img.getFile().toPath());

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_PNG);
return ResponseEntity.ok().headers(headers).body(imageBytes);
}
}

经测试,可以拿到参数 msgId,如需要也可获取 IP 等其他信息。

优点和局限性

优点:

  • 实现简单,没有太多代码和逻辑。
  • 不需要对方确认,强制追踪阅读情况。

局限性:

  • 在某些特定的网络/系统/客户端限制访问图片的链接,可能无法生效。
  • 因为对方不知情,可能涉及隐私的问题。