Hệ thống email có thể thống kê số lượt click bằng cách không đưa người nhận đi thẳng tới URL đích. Thay vào đó, mỗi link trong email sẽ trỏ về một endpoint trung gian của hệ thống. Endpoint này ghi nhận lượt click, sau đó redirect người dùng tới URL thật.

Ý tưởng chính

Thay vì viết link như sau:
<a href="https://example.com/promotion">Xem ưu đãi</a>
ta viết thành:
<a href="/ezymail/api/v1/mail/click?contentId=&url=https%3A%2F%2Fexample.com%2Fpromotion">
    Xem ưu đãi
</a>
Trong đó:
  • contentId là mã định danh duy nhất của email đã gửi.
  • url là URL đích, cần được encode bằng encodeURIComponent.
  • là domain web public nơi endpoint tracking có thể được người nhận truy cập.

Cách hệ thống hoạt động

Khi gửi email theo template, hệ thống sinh một contentId dạng UUID và đưa biến này vào dữ liệu render template. Vì vậy trong nội dung mail, bạn có thể dùng để gắn email cụ thể với hành vi click.
Khi người nhận bấm vào link tracking:
  1. Trình duyệt gọi endpoint /ezymail/api/v1/mail/click.
  2. Endpoint kiểm tra url.
  3. Nếu url rỗng hoặc không hợp lệ, người dùng được redirect về / và không lưu click.
  4. Nếu contentId tồn tại, hệ thống tìm email tương ứng.
  5. Nếu tìm thấy email, hệ thống lưu một bản ghi click gồm mailId, url, createdAt.
  6. Cuối cùng, người dùng được redirect tới URL đích.
sequenceDiagram
    participant User as Người nhận email
    participant Browser as Trình duyệt
    participant Tracking as Endpoint tracking click
    participant MailDB as Bảng email
    participant ClickDB as Bảng click
    participant Target as URL đích

    User->>Browser: Bấm link trong email
    Browser->>Tracking: GET /mail/click?contentId=...&url=...
    Tracking->>Tracking: Kiểm tra URL hợp lệ
    Tracking->>MailDB: Tìm email theo contentId
    alt Tìm thấy email
        Tracking->>ClickDB: Lưu mailId, url, createdAt
    end
    Tracking->>Browser: Redirect tới URL đích
    Browser->>Target: Mở trang đích

Cách tạo link tracking

Với mỗi URL muốn đo lượt click, hãy tạo link theo mẫu:
<a href="/ezymail/api/v1/mail/click?contentId=&url=">
    Link text
</a>
Ví dụ URL đích là:
https://example.com/products/summer-sale?utm_source=email&utm_campaign=summer
Sau khi encode:
https%3A%2F%2Fexample.com%2Fproducts%2Fsummer-sale%3Futm_source%3Demail%26utm_campaign%3Dsummer
Link trong template sẽ là:
<a href="/ezymail/api/v1/mail/click?contentId=&url=https%3A%2F%2Fexample.com%2Fproducts%2Fsummer-sale%3Futm_source%3Demail%26utm_campaign%3Dsummer">
    Xem chương trình
</a>
Lưu ý: trong HTML nên dùng & thay vì & để tránh lỗi parse HTML.

Dữ liệu được lưu

Mỗi lần click hợp lệ sẽ tạo một bản ghi mới trong bảng tracking, gồm các thông tin chính:
  • mail_id: email nào được click.
  • url: URL đích mà người nhận muốn mở.
  • created_at: thời điểm click.
Điều này có nghĩa là hệ thống đang đếm theo số lần click thực tế. Nếu cùng một người bấm cùng một link nhiều lần, mỗi lần bấm sẽ được tính là một lượt click riêng.

Các lưu ý quan trọng

URL đích phải hợp lệ. Nếu URL rỗng hoặc không đạt điều kiện validate, hệ thống sẽ redirect về / và không lưu click.
contentId phải thuộc về một email đã được lưu. Nếu không tìm thấy email theo contentId, hệ thống vẫn redirect tới URL hợp lệ nhưng không ghi bản ghi tracking.
URL được lưu có giới hạn độ dài ở tầng ứng dụng. Nếu URL quá dài, hệ thống sẽ cắt bớt trước khi lưu vào bản ghi click.
Cơ chế hiện tại không phân biệt unique click và total click. Nếu cần thống kê unique click theo người nhận, thiết bị hoặc phiên, cần bổ sung thêm dữ liệu như recipient id, user agent, IP hash hoặc token riêng cho từng link.

Kết luận

Để thống kê lượt click qua email, hãy biến mỗi URL đích thành một tracking link đi qua endpoint trung gian. Endpoint này chịu trách nhiệm xác thực URL, tìm email theo contentId, ghi nhận lượt click, rồi redirect người nhận tới trang thật.
Cách làm này đơn giản, ít ảnh hưởng trải nghiệm người dùng, và đủ linh hoạt để thống kê theo email, theo URL hoặc theo thời gian.