selase
(Selase Krakani)
12 Septiembre, 2025 14:31
2
No, esto no es compatible de forma nativa, aparte de la configuración del sitio email custom headers que se aplica globalmente a todos los correos electrónicos salientes.
Sí, un plugin personalizado sería el mejor enfoque aquí.
emonunix:
¿Sería la modificación del código principal la única solución y, en caso afirmativo, podría indicarme la dirección correcta (por ejemplo, qué archivos debo consultar)?
El flujo actual para los correos electrónicos de resumen es el siguiente:
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 podría engancharse al proceso de construcción del mensaje (Email::MessageBuilder) e inyectar (preferiblemente a través de un modificador) su cabecera personalizada condicionalmente, solo para los resúmenes.
2 Me gusta