from anydi import singleton from fansifter_common.adapters.ows_account import OwsAccountClient from fansifter_common.adapters.sendgrid import SendGridClient from fansifter_common.adapters.sendgrid.models import Email, FanData, MergeTags from fansifter_common.adapters.stripo import StripoClient from fansifter_common.encrypter import JWTEncrypter from fansifter_common.identifiers.types import FansifterProfileIdentifier from fansifter_common.identifiers.utils import encrypt_profile_token from fansifter_common.legal_info.constants import DEFAULT_COUNTRY_CODE from fansifter_common.legal_info.services import LegalInfoService from fansifter_common.translation.services import TranslationService from email_campaigns.config import settings from email_campaigns.emails.exceptions import ( EmailContentMissingError, EmailDomainMissingError, ) from email_campaigns.emails.models import BaseEmail, EmailTestSend from email_campaigns.emails.repositories import EmailTestSendRepository from email_campaigns.profile.services import ProfileService @singleton class EmailSendService: def __init__( self, email_test_send_repository: EmailTestSendRepository, profile_service: ProfileService, sendgrid_client: SendGridClient, stripo_client: StripoClient, legal_info_service: LegalInfoService, preference_center_encrypter: JWTEncrypter, ows_account_client: OwsAccountClient, translation_service: TranslationService, ) -> None: self.email_test_send_repository = email_test_send_repository self.profile_service = profile_service self.sendgrid_client = sendgrid_client self.stripo_client = stripo_client self.legal_info_service = legal_info_service self.preference_center_encrypter = preference_center_encrypter self.ows_account_client = ows_account_client self.translation_service = translation_service def send_test_email( self, email: BaseEmail, content: str | None, emails: set[str], identity_id: str, with_unapplied_changes: bool = False, ) -> None: if not content: if not email.html_content or not email.css_content: raise EmailContentMissingError content = self.stripo_client.compress( email.html_content, email.css_content, ) vendor = self.ows_account_client.get_vendor(email.vendor_id) from_email = Email(name=email.sender_name, email=email.sender_email) if not email.email_domain: raise EmailDomainMissingError brand = email.email_domain.brand recipients = self.profile_service.find_email_profiles(emails) email_test_send = EmailTestSend( email_id=email.id, email_type=email.email_type, recipients=list(emails), created_by=identity_id, ) self.email_test_send_repository.save(email_test_send) test_prefix = ( "[TEST-Unsaved version]" if with_unapplied_changes and email.has_unapplied_changes else "[TEST]" ) subject = email.subject or email.name data_to_send: list[FanData] = [] for recipient in recipients: if profile_id := recipient.profile_id: preference_center_profile_token = encrypt_profile_token( self.preference_center_encrypter, identifier=FansifterProfileIdentifier.model_construct( profile_id=str(profile_id), email_campaign_id=email.id, ), ) else: preference_center_profile_token = None fan_country_iso2 = DEFAULT_COUNTRY_CODE legal_entity = self.legal_info_service.get_legal_entity(fan_country_iso2) translations = self.translation_service.get_translations_by_country_code( fan_country_iso2 ) data_to_send.append( FanData( email=recipient.email, profile_token=preference_center_profile_token, privacy_links_block=self.legal_info_service.prepare_privacy_links_for_country( fan_country_iso2, settings.privacy_footer_utm_source_name ), legal_entity_name=legal_entity.name, legal_entity_address=legal_entity.address, country_iso2=fan_country_iso2, opt_in_info=translations["en"].optInInfo, opt_in_info_external=translations["en"].optInInfoExternal, unsubscribe_text=translations["en"].unsubscribe, merge_tags=MergeTags(first_name=recipient.first_name), ) ) self.sendgrid_client.send_mail( email_id=email.id, email_type=email.email_type, automated_email_trigger_id=None, version="v2", brand=brand, vendor_id=vendor.vendor_id, vendor_name=vendor.name, subject=f" {test_prefix} {subject}", to_fans=data_to_send, from_email=from_email, html_content=content, preview_text=email.preview_text, is_test=True, )