Skip to content

Email analytics does not filter out bot events flagged by Mailgun (client-info.bot) #30388

Description

@codebarista

Issue Summary

Mailgun provides Open and Click Bot Detection to identify automated interactions (such as email security scanners or webmail bots). When Mailgun identifies a bot, it populates the client-info.bot field in the event payload with one of the following values:

  • apple: Apple MPP bot
  • gmail: Gmail bot
  • generic: Unknown bot (firewall, anti-virus scan, etc.)
  • (empty / omitted): No bot detected

Currently, Ghost's email-analytics service (ghost/core/core/server/services/email-analytics) processes incoming opened and clicked events without inspecting the client-info.bot field. As a result, automated bot events (especially generic security scans) are recorded as genuine member engagement, artificially inflating open and click rates.

If that’s not a bug, then it’s a feature request. :)

Image

Steps to Reproduce

  1. Send a newsletter via Ghost to a recipient domain that triggers automated link/pixel scans (e.g., enterprise mail security gateways).
  2. Mailgun fires an opened or clicked event payload containing client-info.bot (e.g., "generic", "apple", or "gmail").
  3. Ghost ingests the event and increments member analytics regardless of the bot flag.

Expected Behavior
When processing Mailgun payloads in email-analytics, Ghost should evaluate client-info.bot. If populated (e.g., generic, apple, gmail), Ghost should handle or filter these events appropriately instead of treating them as regular human interactions.

Actual Behavior
All incoming opened and clicked events are recorded as legitimate member activity, ignoring the client-info.bot field.

Ghost Version

v6.60.0

Node.js Version

Docker Image

How did you install Ghost?

Docker Image

Database type

MySQL 8

Browser & OS version

No response

Relevant log / error output

Code of Conduct

  • I agree to be friendly and polite to people in this repository

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs:triage[triage] this needs to be triaged by the Ghost team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions