selase
(Selase Krakani)
12 Settembre 2025, 2:31pm
2
No, questo non è supportato “out of the box”, a parte l’impostazione del sito email custom headers che si applica globalmente a tutte le email in uscita.
Sì, un plugin personalizzato sarebbe l’approccio migliore in questo caso.
emonunix:
La modifica del codice principale sarebbe l’unica soluzione e, in tal caso, potresti indicarmi la direzione giusta (ad esempio, quali file guardare)?
Il flusso attuale per le email di riepilogo è il seguente:
def execute(args)
return if SiteSetting.disable_emails == "yes"
return if SiteSetting.disable_digest_emails?
return if SiteSetting.private_email?
target_user_ids.each do |user_id|
::Jobs.enqueue(:user_email, type: "digest", user_id: user_id)
end
end
# frozen_string_literal: true
module Jobs
# Asynchronously send an email to a user
class UserEmail < ::Jobs::Base
include Skippable
sidekiq_options queue: "low"
sidekiq_retry_in do |count, exception|
# retry in an hour when SMTP server is busy
# or use default sidekiq retry formula. returning
# nil/0 will trigger the default sidekiq
# retry formula
#
# See https://github.com/mperham/sidekiq/blob/3330df0ee37cfd3e0cd3ef01e3e66b584b99d488/lib/sidekiq/job_retry.rb#L216-L234
case exception.wrapped
when Net::SMTPServerBusy
return 1.hour + (rand(30) * (count + 1))
end
This file has been truncated. show original
def digest(user, opts = {})
build_summary_for(user)
@unsubscribe_key = UnsubscribeKey.create_key_for(@user, UnsubscribeKey::DIGEST_TYPE)
@since = opts[:since].presence
@since ||= [user.last_seen_at, user.user_stat&.digest_attempted_at, 1.month.ago].compact.max
# Fetch some topics and posts to show
digest_opts = {
limit: SiteSetting.digest_topics + SiteSetting.digest_other_topics,
top_order: true,
}
topics_for_digest = Topic.for_digest(user, @since, digest_opts)
if topics_for_digest.empty? && !user.user_option.try(:include_tl0_in_digests)
# Find some topics from new users that are at least 24 hours old
topics_for_digest =
Topic.for_digest(user, @since, digest_opts.merge(include_tl0: true)).where(
"topics.created_at < ?",
24.hours.ago,
)
This file has been truncated. show original
# frozen_string_literal: true
# Builds a Mail::Message we can use for sending. Optionally supports using a template
# for the body and subject
module Email
class MessageBuilder
attr_reader :template_args, :reply_by_email_key
ALLOW_REPLY_BY_EMAIL_HEADER = "X-Discourse-Allow-Reply-By-Email"
INSTRUCTIONS_SEPARATOR = "---\n"
def initialize(to, opts = nil)
@to = to
@opts = opts || {}
@template_args = {
site_name: SiteSetting.title,
email_prefix: SiteSetting.email_prefix.presence || SiteSetting.title,
base_url: Discourse.base_url,
user_preferences_url: "#{Discourse.base_url}/my/preferences",
hostname: Discourse.current_hostname,
This file has been truncated. show original
Un plugin potrebbe agganciarsi al processo di creazione del messaggio (Email::MessageBuilder) e iniettare (preferibilmente tramite un modificatore) la tua intestazione personalizzata in modo condizionale, solo per i riepiloghi.
2 Mi Piace