* Adjust digest rate if recent clicks tracked * Fix issues * Fix issues * Fix issues * Fiddle with tests * Fix syntax * Fiddle with tests * Fiddle with tests * Fiddle with tests * Fiddle with tests * Fiddle with tests * Fiddle with tests * Fiddle with tests * Remove .env.test symlink (#20839) * Update the mdx vscode extension (#20840) * Update @cypress/code-coverage to version 3.12.30 (#20803) Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> Co-authored-by: Mac Siri <mac@forem.com> * Update ruby VSCode extensions for debugging (#20816) The 'rebornix.Ruby' extension is deprecated. I replaced with the 'Shopify.ruby-lsp' extension since VSCode's Ruby docs pointed users to ruby-lsp, see https://code.visualstudio.com/docs/languages/ruby. * Update esbuild to version 0.19.12 (#20841) Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> * Update eslint to version 8.57.0 (#20853) Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> * fix: remove listings option from views/dashboards/_actions_mobile.html.erb (#20849) Co-authored-by: Mac Siri <mac@forem.com> * Update eslint-import-resolver-webpack to version 0.13.8 (#20854) Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> * add timestamp to users roles table (#20844) * Update eslint-plugin-import to version 2.29.1 (#20855) Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> * Adjust tests to account for clicks * Adjust tests to account for clicks --------- Co-authored-by: Mac Siri <mac@forem.com> Co-authored-by: Meredith <meredith.edwards1771@gmail.com> Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> Co-authored-by: Gabriel Quaresma <j.quaresmasantos_98@hotmail.com> Co-authored-by: Philip How <philip.j.how@gmail.com>
89 lines
2.9 KiB
Ruby
89 lines
2.9 KiB
Ruby
class EmailDigestArticleCollector
|
|
include FieldTest::Helpers
|
|
include Instrumentation
|
|
|
|
ARTICLES_TO_SEND = "EmailDigestArticleCollector#articles_to_send".freeze
|
|
RESULTS_COUNT = 7 # Winner of digest_count_03_18 field test
|
|
CLICK_LOOKBACK = 30
|
|
|
|
def initialize(user)
|
|
@user = user
|
|
end
|
|
|
|
def articles_to_send
|
|
# rubocop:disable Metrics/BlockLength
|
|
order = Arel.sql("((score * (feed_success_score + 0.1)) - clickbait_score) DESC")
|
|
instrument ARTICLES_TO_SEND, tags: { user_id: @user.id } do
|
|
return [] unless should_receive_email?
|
|
|
|
articles = if user_has_followings?
|
|
experience_level_rating = @user.setting.experience_level || 5
|
|
experience_level_rating_min = experience_level_rating - 4
|
|
experience_level_rating_max = experience_level_rating + 4
|
|
|
|
@user.followed_articles
|
|
.select(:title, :description, :path)
|
|
.published
|
|
.where("published_at > ?", cutoff_date)
|
|
.where(email_digest_eligible: true)
|
|
.not_authored_by(@user.id)
|
|
.where("score > ?", 8)
|
|
.where("experience_level_rating > ? AND experience_level_rating < ?",
|
|
experience_level_rating_min, experience_level_rating_max)
|
|
.order(order)
|
|
.limit(RESULTS_COUNT)
|
|
else
|
|
Article.select(:title, :description, :path)
|
|
.published
|
|
.where("published_at > ?", cutoff_date)
|
|
.featured
|
|
.where(email_digest_eligible: true)
|
|
.not_authored_by(@user.id)
|
|
.where("score > ?", 15)
|
|
.order(order)
|
|
.limit(RESULTS_COUNT)
|
|
end
|
|
|
|
articles.length < 3 ? [] : articles
|
|
end
|
|
# rubocop:enable Metrics/BlockLength
|
|
end
|
|
|
|
def should_receive_email?
|
|
return true unless last_email_sent
|
|
|
|
email_sent_within_lookback_period = last_email_sent >= Settings::General.periodic_email_digest.days.ago
|
|
return false if email_sent_within_lookback_period && !recent_tracked_click?
|
|
|
|
true
|
|
end
|
|
|
|
private
|
|
|
|
def recent_tracked_click?
|
|
@user.email_messages
|
|
.where(mailer: "DigestMailer#digest_email")
|
|
.where("sent_at > ?", CLICK_LOOKBACK.days.ago)
|
|
.where.not(clicked_at: nil).any?
|
|
end
|
|
|
|
def last_email_sent
|
|
@last_email_sent ||=
|
|
@user.email_messages
|
|
.where(mailer: "DigestMailer#digest_email")
|
|
.maximum(:sent_at)
|
|
end
|
|
|
|
def cutoff_date
|
|
a_few_days_ago = 7.days.ago.utc
|
|
return a_few_days_ago unless last_email_sent
|
|
|
|
[a_few_days_ago, last_email_sent].max
|
|
end
|
|
|
|
def user_has_followings?
|
|
@user.following_users_count.positive? ||
|
|
@user.cached_followed_tag_names.any? ||
|
|
@user.cached_antifollowed_tag_names.any?
|
|
end
|
|
end
|