def subscribe_newsletter(user: User): if not feature_send_mail_to_users_enabled(): logger.logger.info("Subscription in DEV or STAGING mode is disabled") return None try: contact = get_contact(user) except Exception: # pylint: disable=broad-except contact_data = {"Email": user.email, "Name": user.publicName} contact_json = app.mailjet_client.contact.create( data=contact_data).json() contact = contact_json["Data"][0] if "Data" in contact_json else None if contact is None: raise MailServiceException # ('Pass Culture - Liste de diffusion', 1795144) contact_lists_data = { "ContactsLists": [{ "Action": "addnoforce", "ListID": 1795144 }] } return app.mailjet_client.contact_managecontactslists.create( id=contact["ID"], data=contact_lists_data).json()
def retrieve_offerer_bookings_recap_email_data_after_offerer_cancellation( bookings: List[Booking], recipients: str) -> Dict: booking = bookings[0] stock = booking.stock offer = stock.offer event_date = format_booking_date_for_email(booking) event_hour = format_booking_hours_for_email(booking) offer_link = build_pc_pro_offer_link(offer) offer_price = str(stock.price) if stock.price > 0 else "Gratuit" environment = format_environment_for_email() quantity = sum([booking.quantity for booking in bookings]) venue_name = offer.venue.publicName if offer.venue.publicName else offer.venue.name return { "FromEmail": settings.SUPPORT_EMAIL_ADDRESS, "MJ-TemplateID": 1116333, "MJ-TemplateLanguage": True, "To": recipients if feature_send_mail_to_users_enabled() else settings.DEV_EMAIL_ADDRESS, "Vars": { "offer_name": offer.name, "venue_name": venue_name, "price": offer_price, "is_event": int(offer.isEvent), "event_date": event_date, "event_hour": event_hour, "quantity": quantity, "reservations_number": len(bookings), "env": environment, "lien_offre_pcpro": offer_link, "users": _extract_users_information_from_bookings_list(bookings), }, }
def retrieve_data_to_warn_user_after_stock_update_affecting_booking(booking: Booking) -> Dict: stock = booking.stock offer = stock.offer offer_name = offer.name user_first_name = booking.user.firstName venue_name = offer.venue.publicName if offer.venue.publicName else offer.venue.name is_event = int(offer.isEvent) event_date = "" event_hour = "" if is_event: event_date = format_date(get_event_datetime(stock), format="full", locale="fr") event_hour = format_booking_hours_for_email(booking) email_to = booking.user.email if feature_send_mail_to_users_enabled() else settings.DEV_EMAIL_ADDRESS return { "FromEmail": settings.SUPPORT_EMAIL_ADDRESS, "MJ-TemplateID": 1332139, "MJ-TemplateLanguage": True, "To": email_to, "Vars": { "offer_name": offer_name, "user_first_name": user_first_name, "venue_name": venue_name, "event_date": event_date, "event_hour": event_hour, }, }
def build_soon_to_be_expired_bookings_recap_email_data_for_beneficiary( beneficiary: User, bookings: typing.List[Booking] ) -> typing.Dict: return { "FromEmail": settings.SUPPORT_EMAIL_ADDRESS if feature_send_mail_to_users_enabled() else settings.DEV_EMAIL_ADDRESS, "Mj-TemplateID": 1927224, "Mj-TemplateLanguage": True, "To": beneficiary.email if feature_send_mail_to_users_enabled() else settings.DEV_EMAIL_ADDRESS, "Vars": { "user_firstName": beneficiary.firstName, "bookings": _extract_bookings_information_from_bookings_list(bookings), "env": format_environment_for_email(), }, }
def build_beneficiary_information_email_change_data( beneficiary_email: str, beneficiary_name: str) -> dict: return { "FromEmail": SUPPORT_EMAIL_ADDRESS, "MJ-TemplateID": 2066067, "MJ-TemplateLanguage": True, "To": beneficiary_email if feature_send_mail_to_users_enabled() else DEV_EMAIL_ADDRESS, "Vars": { "beneficiary_name": beneficiary_name, }, }
def retrieve_data_for_pro_user_waiting_offerer_validation_email( user: User, offerer: Offerer) -> Dict: return { "FromEmail": settings.SUPPORT_EMAIL_ADDRESS, "MJ-TemplateID": 778329, "MJ-TemplateLanguage": True, "To": user.email if feature_send_mail_to_users_enabled() else settings.DEV_EMAIL_ADDRESS, "Vars": { "nom_structure": offerer.name }, }
def build_expired_bookings_recap_email_data_for_offerer( offerer: Offerer, recipients: str, bookings: typing.List[Booking] ) -> typing.Dict: return { "FromEmail": settings.SUPPORT_EMAIL_ADDRESS, "Mj-TemplateID": 1952508, "Mj-TemplateLanguage": True, "To": recipients if feature_send_mail_to_users_enabled() else settings.DEV_EMAIL_ADDRESS, "Vars": { "bookings": _extract_bookings_information_from_bookings_list(bookings), "department": PostalCode(offerer.postalCode).get_departement_code(), "env": format_environment_for_email(), }, }
def retrieve_data_for_new_offerer_validation_email(offerer: Offerer) -> Dict: recipients = find_new_offerer_user_email(offerer.id) pro_user_email = recipients if feature_send_mail_to_users_enabled( ) else settings.DEV_EMAIL_ADDRESS environment = format_environment_for_email() return { "FromEmail": settings.SUPPORT_EMAIL_ADDRESS, "MJ-TemplateID": 778723, "MJ-TemplateLanguage": True, "To": pro_user_email, "Vars": { "offerer_name": offerer.name, "env": environment, }, }
def retrieve_data_for_reset_password_native_app_email( user_email: str, token_value: str, expiration_date: datetime) -> Dict: reset_password_link = ( f"{settings.API_URL}/native/v1/redirect_to_native/mot-de-passe-perdu?token={token_value}" f"&expiration_timestamp={int(expiration_date.timestamp())}" f"&email={user_email}") return { "FromEmail": settings.SUPPORT_EMAIL_ADDRESS, "MJ-TemplateID": 1838526, "MJ-TemplateLanguage": True, "To": user_email if feature_send_mail_to_users_enabled() else settings.DEV_EMAIL_ADDRESS, "Vars": { "native_app_link": reset_password_link }, }
def retrieve_data_for_reset_password_pro_email(user: User) -> Dict: user_email = user.email if feature_send_mail_to_users_enabled( ) else settings.DEV_EMAIL_ADDRESS user_reset_password_token = user.resetPasswordToken env = format_environment_for_email() reinit_password_url = f"{settings.PRO_URL}/mot-de-passe-perdu?token={user_reset_password_token}" return { "FromEmail": settings.SUPPORT_EMAIL_ADDRESS, "MJ-TemplateID": 779295, "MJ-TemplateLanguage": True, "To": user_email, "Vars": { "lien_nouveau_mdp": reinit_password_url, "env": env }, }
def compute_email_html_part_and_recipients( email_html_part, recipients: Union[List[str], str]) -> (str, str): if isinstance(recipients, list): recipients_string = ", ".join(recipients) else: recipients_string = recipients if feature_send_mail_to_users_enabled(): email_to = recipients_string else: email_html_part = ( "<p>This is a test (ENV={environment})." " In production, email would have been sent to : {recipients}</p>{html_part}" .format(environment=settings.ENV, recipients=recipients_string, html_part=email_html_part)) email_to = settings.DEV_EMAIL_ADDRESS return email_html_part, email_to
def retrieve_data_to_warn_beneficiary_after_pro_booking_cancellation( booking: Booking) -> Dict: stock = booking.stock offer = stock.offer event_date = "" event_hour = "" email_to = booking.user.email if feature_send_mail_to_users_enabled( ) else settings.DEV_EMAIL_ADDRESS is_event = int(offer.isEvent) if is_event: event_date = format_date(get_event_datetime(stock), format="full", locale="fr") event_hour = format_booking_hours_for_email(booking) is_free_offer = 1 if stock.price == 0 else 0 is_thing = int(offer.isThing) is_online = int(offer.isDigital) if is_online: is_event = 0 is_thing = 0 offerer_name = offer.venue.managingOfferer.name offer_name = offer.name offer_price = str(stock.price * booking.quantity) user_first_name = booking.user.firstName venue_name = offer.venue.publicName if offer.venue.publicName else offer.venue.name return { "FromEmail": settings.SUPPORT_EMAIL_ADDRESS, "MJ-TemplateID": 1116690, "MJ-TemplateLanguage": True, "To": email_to, "Vars": { "event_date": event_date, "event_hour": event_hour, "is_event": is_event, "is_free_offer": is_free_offer, "is_online": is_online, "is_thing": is_thing, "offer_name": offer_name, "offer_price": offer_price, "offerer_name": offerer_name, "user_first_name": user_first_name, "venue_name": venue_name, }, }
def retrieve_data_for_offerer_ongoing_attachment_email( user_offerer: UserOfferer) -> Dict: recipient = find_user_offerer_email(user_offerer.id) pro_user_email = recipient if feature_send_mail_to_users_enabled( ) else settings.DEV_EMAIL_ADDRESS offerer = find_first_by_user_offerer_id(user_offerer.id) environment = format_environment_for_email() return { "FromEmail": settings.SUPPORT_EMAIL_ADDRESS, "MJ-TemplateID": 778749, "MJ-TemplateLanguage": True, "To": pro_user_email, "Vars": { "nom_structure": offerer.name, "env": environment }, }
def retrieve_data_for_reset_password_user_email(user: User) -> Dict: user_first_name = user.firstName user_email = user.email user_reset_password_token = user.resetPasswordToken env = format_environment_for_email() return { "FromEmail": settings.SUPPORT_EMAIL_ADDRESS, "MJ-TemplateID": 912168, "MJ-TemplateLanguage": True, "To": user_email if feature_send_mail_to_users_enabled() else settings.DEV_EMAIL_ADDRESS, "Vars": { "prenom_user": user_first_name, "token": user_reset_password_token, "env": env }, }
def get_activation_email_data_for_native(user: User, token: models.Token) -> Dict: expiration_timestamp = int(token.expirationDate.timestamp()) query_string = urlencode({ "token": token.value, "expiration_timestamp": expiration_timestamp, "email": user.email }) email_confirmation_link = f"{settings.NATIVE_APP_URL}/signup-confirmation?{query_string}" return { "FromEmail": settings.SUPPORT_EMAIL_ADDRESS, "Mj-TemplateID": 1897370, "Mj-TemplateLanguage": True, "To": user.email if feature_send_mail_to_users_enabled() else settings.DEV_EMAIL_ADDRESS, "Vars": { "native_app_link": email_confirmation_link, }, }
def make_webapp_user_validation_email(user: User, app_origin_url: str) -> Dict: template = "mails/webapp_user_validation_email.html" email_html = render_template(template, user=user, api_url=settings.API_URL, app_origin_url=app_origin_url) return { "Html-part": email_html, "To": user.email, "Subject": "Validation de votre adresse email pour le pass Culture", "FromName": "pass Culture", "FromEmail": settings.SUPPORT_EMAIL_ADDRESS if feature_send_mail_to_users_enabled() else settings.DEV_EMAIL_ADDRESS, }
def get_activation_email_data(user: User) -> Dict: first_name = user.firstName.capitalize() email = user.email token = user.resetPasswordToken env = format_environment_for_email() return { "FromEmail": settings.SUPPORT_EMAIL_ADDRESS, "Mj-TemplateID": 994771, "Mj-TemplateLanguage": True, "To": email if feature_send_mail_to_users_enabled() else settings.DEV_EMAIL_ADDRESS, "Vars": { "prenom_user": first_name, "token": token, "email": quote(email), "env": env }, }
def retrieve_offerer_booking_recap_email_data_after_user_cancellation( booking: Booking, recipients: str) -> Dict: user = booking.user stock = booking.stock bookings = list( filter(lambda ongoing_booking: not ongoing_booking.isCancelled, stock.bookings)) offer = stock.offer venue = offer.venue departement_code = venue.departementCode or "numérique" price = str(stock.price) if stock.price > 0 else "Gratuit" offer_pc_pro_link = build_pc_pro_offer_link(offer) environment = format_environment_for_email() booked_date = format_booking_date_for_email(booking) booked_hour = format_booking_hours_for_email(booking) is_active = _is_offer_active_for_recap(stock) return { "FromEmail": settings.SUPPORT_EMAIL_ADDRESS, "MJ-TemplateID": 780015, "MJ-TemplateLanguage": True, "To": recipients if feature_send_mail_to_users_enabled() else settings.DEV_EMAIL_ADDRESS, "Vars": { "departement": departement_code, "nom_offre": offer.name, "lien_offre_pcpro": offer_pc_pro_link, "nom_lieu": venue.name, "prix": price, "is_event": int(offer.isEvent), "date": booked_date, "heure": booked_hour, "quantite": booking.quantity, "user_name": user.publicName, "user_email": user.email, "is_active": int(is_active), "nombre_resa": len(bookings), "env": environment, "users": extract_users_information_from_bookings(bookings), }, }
def make_offerer_driven_cancellation_email_for_offerer( booking: Booking) -> Dict: stock_name = booking.stock.offer.name venue = booking.stock.offer.venue user_name = booking.user.publicName user_email = booking.user.email email_subject = "Confirmation de votre annulation de réservation pour {}, proposé par {}".format( stock_name, venue.name) ongoing_stock_bookings = find_ongoing_bookings_by_stock(booking.stock.id) stock_date_time = None booking_is_on_event = booking.stock.beginningDatetime is not None if booking_is_on_event: date_in_tz = get_event_datetime(booking.stock) stock_date_time = format_datetime(date_in_tz) email_html = render_template( "mails/offerer_recap_email_after_offerer_cancellation.html", booking_is_on_event=booking_is_on_event, user_name=user_name, user_email=user_email, stock_date_time=stock_date_time, number_of_bookings=len(ongoing_stock_bookings), stock_bookings=ongoing_stock_bookings, stock_name=stock_name, venue=venue, ) return { "FromName": "pass Culture", "FromEmail": settings.SUPPORT_EMAIL_ADDRESS if feature_send_mail_to_users_enabled() else settings.DEV_EMAIL_ADDRESS, "Subject": email_subject, "Html-part": email_html, }
def make_pro_user_validation_email(user: User, app_origin_url: str) -> Dict: return { "FromEmail": settings.SUPPORT_EMAIL_ADDRESS if feature_send_mail_to_users_enabled() else settings.DEV_EMAIL_ADDRESS, "FromName": "pass Culture pro", "Subject": "[pass Culture pro] Validation de votre adresse email pour le pass Culture", "MJ-TemplateID": 778688, "MJ-TemplateLanguage": True, "Recipients": [{ "Email": user.email, "Name": user.publicName }], "Vars": { "nom_structure": user.publicName, "lien_validation_mail": f"{app_origin_url}/inscription/validation/{user.validationToken}", }, }
def create_email_recipients(recipients: List[str]) -> str: if feature_send_mail_to_users_enabled(): return ", ".join(recipients) return settings.DEV_EMAIL_ADDRESS
def retrieve_data_for_beneficiary_booking_confirmation_email( booking: Booking) -> Dict: stock = booking.stock offer = stock.offer venue = offer.venue beneficiary = booking.user is_digital_offer = offer.isDigital is_physical_offer = ProductType.is_thing( name=offer.type) and not is_digital_offer is_event = ProductType.is_event(name=offer.type) can_expire = int(offer.offerType.get("canExpire", False)) department_code = venue.departementCode if not is_digital_offer else beneficiary.departementCode booking_date_in_tz = utc_datetime_to_department_timezone( booking.dateCreated, department_code) beneficiary_email = beneficiary.email if feature_send_mail_to_users_enabled( ) else settings.DEV_EMAIL_ADDRESS beneficiary_first_name = beneficiary.firstName formatted_booking_date = get_date_formatted_for_email(booking_date_in_tz) formatted_booking_time = get_time_formatted_for_email(booking_date_in_tz) offer_name = offer.name offerer_name = venue.managingOfferer.name formatted_event_beginning_time = "" formatted_event_beginning_date = "" # FIXME: booking.price == stock.price, so we should just write str(booking.total_amount), right? stock_price = str(stock.price * booking.quantity) if stock.price > 0 else "Gratuit" booking_token = booking.token venue_name = venue.name venue_address = venue.address or "" venue_postal_code = venue.postalCode or "" venue_city = venue.city or "" is_event_or_physical_offer_stringified_boolean = 1 if is_event or is_physical_offer else 0 is_physical_offer_stringified_boolean = 1 if is_physical_offer else 0 is_event_stringified_boolean = 1 if is_event else 0 is_single_event_stringified_boolean = 1 if is_event and booking.quantity == 1 else 0 is_duo_event_stringified_boolean = 1 if is_event and booking.quantity == 2 else 0 offer_id = humanize(offer.id) mediation_id = humanize( offer.activeMediation.id) if offer.activeMediation else "vide" environment = format_environment_for_email() if is_event: event_beginning_date_in_tz = utc_datetime_to_department_timezone( stock.beginningDatetime, department_code) formatted_event_beginning_time = get_time_formatted_for_email( event_beginning_date_in_tz) formatted_event_beginning_date = get_date_formatted_for_email( event_beginning_date_in_tz) return { "FromEmail": settings.SUPPORT_EMAIL_ADDRESS, "MJ-TemplateID": 1163067, "MJ-TemplateLanguage": True, "To": beneficiary_email, "Vars": { "user_first_name": beneficiary_first_name, "booking_date": formatted_booking_date, "booking_hour": formatted_booking_time, "offer_name": offer_name, "offerer_name": offerer_name, "event_date": formatted_event_beginning_date, "event_hour": formatted_event_beginning_time, "offer_price": stock_price, "offer_token": booking_token, "venue_name": venue_name, "venue_address": venue_address, "venue_postal_code": venue_postal_code, "venue_city": venue_city, "all_but_not_virtual_thing": is_event_or_physical_offer_stringified_boolean, "all_things_not_virtual_thing": is_physical_offer_stringified_boolean, "is_event": is_event_stringified_boolean, "is_single_event": is_single_event_stringified_boolean, "is_duo_event": is_duo_event_stringified_boolean, "offer_id": offer_id, "mediation_id": mediation_id, "env": environment, "can_expire": can_expire, }, }