Commit Graph

9 Commits

Author SHA1 Message Date
Kevin Ansfield
2b1dc351d2 Added members.email_open_rate aggregation to email analytics (#12458)
refs https://github.com/TryGhost/Ghost/issues/12421
requires https://github.com/TryGhost/Ghost/pull/12457

- updates stats aggregator to calculate and store an open rate for each member
  - uses two queries because I couldn't find a reasonable approach to perform the update in a single query as per the email aggregation
  - benchmarked locally at <1sec/1000members
  - will not store an open rate unless the number of tracked emails sent to a member is above a certain threshold (defaults to 5) to avoid new members being heavily weighted
- fixes typo in EmailAnalytics that was stopping member stats from being aggregated
2021-02-24 21:03:29 +00:00
Kevin Ansfield
723218ee34 Added guard for page.items existing in Mailgun response
no issue

- it's possible to get Mailgun responses where the `items` array doesn't exist so we need to guard against that so we don't error
2021-02-24 21:03:29 +00:00
Kevin Ansfield
bef65aa8a2 Fixed email count check in email-analytics service
no issue

- raw knex `.count()` does not return a straight number, we need to handle an array of rowDataPacket objects
2021-02-24 21:03:29 +00:00
Kevin Ansfield
2b747e6b53 Fixed misleading emailAnalytics.fetchLatest debug statement 2021-02-24 21:03:29 +00:00
Kevin Ansfield
a84ec49854 Added no-emails guard check when fetching latest email events
no issue

- replicates the same guard used in `fetchLatest()` to prevent contacting Mailgun when there are no emails in the database
2021-02-24 21:03:29 +00:00
Kevin Ansfield
837334b536 Fixed linting 2021-02-24 21:03:29 +00:00
Kevin Ansfield
7bbf644d0d Added email analytics service (#12393)
no issue

- added `EmailAnalyticsService`
  - `.fetchAll()` grabs and processes all available events
  - `.fetchLatest()` grabs and processes all events since the last seen event timestamp
  - `EventProcessor` passed event objects and updates `email_recipients` or `members` records depending on the event being analytics or list hygiene
    - always returns a `EventProcessingResult` instance so that progress can be tracked and merged across individual events, batches (pages of events), and total runs
    - adds email_id and member_id to the returned result where appropriate so that the stats aggregator can limit processing to data that has changed
    - sets `email_recipients.{delivered_at, opened_at, failed_at}` for analytics events
    - sets `members.subscribed = false` for permanent failure/unsubscribed/complained list hygiene events
  - `StatsAggregator` takes an `EventProcessingResult`-like object containing arrays of email ids and member ids on which to aggregate statistics.
  - jobs for `fetch-latest` and `fetch-all` ready for use with the JobsService
- added `initialiseRecurringJobs()` function to Ghost bootup procedure that schedules the email analytics "fetch latest" job to run every minute
2021-02-24 21:03:29 +00:00
Kevin Ansfield
788676845d Added empty email analytics packages 2021-02-24 21:03:29 +00:00
Kevin Ansfield
2d12ab60ae Initial commit 2020-11-25 15:13:40 +00:00