Skip to content

Commit

Permalink
New emails
Browse files Browse the repository at this point in the history
  • Loading branch information
blopker committed Nov 7, 2023
1 parent 8d6f19d commit 9b4748d
Show file tree
Hide file tree
Showing 21 changed files with 305 additions and 74 deletions.
1 change: 1 addition & 0 deletions config/settings/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#email-backend
EMAIL_BACKEND = env("DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.console.EmailBackend") # type: ignore
EMAIL_BASE_URL = env("EMAIL_BASE_URL", default=f"http://{SITE_HOST}") # noqa: F405 # type: ignore

# INSTALLED_APPS += ["anymail"] # noqa: F405
# EMAIL_BACKEND = "anymail.backends.mailersend.EmailBackend"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"watch:tailwind": "NODE_ENV=development npm run tw -- --watch",
"esb": "esbuild --bundle --sourcemap ./assets/js/app.js --outfile=./totem/static/js/app.min.js --loader:.js=jsx --jsx-factory=h --jsx-fragment=Fragment",
"tw": "tailwindcss --postcss -i ./assets/css/styles.css -o ./totem/static/css/styles.css --minify",
"livereload": "livereload ./totem/ -e 'html,css,js,py' --wait 200"
"livereload": "livereload ./totem/ -e 'html,css,js,py,mjml' --wait 200"
},
"keywords": [],
"author": "",
Expand Down
59 changes: 22 additions & 37 deletions totem/email/emails.py
Original file line number Diff line number Diff line change
@@ -1,54 +1,41 @@
from __future__ import annotations

import urllib.parse
from pathlib import Path
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING

from django.conf import settings
from django.template.loader import render_to_string
from django.urls import reverse
from mjml import mjml2html
from django.utils.safestring import SafeString

if TYPE_CHECKING:
from totem.circles.models import CircleEvent
from totem.users.models import User

from .utils import send_template_mail

# list files in templates/email/emails
files = Path(__file__).parent.joinpath("templates/email/emails").glob("*.mjml")
templates = {file.stem: file.name for file in files}
from .utils import send_mjml_mail


def send_returning_login_email(email: str, url: str):
_send_button_email(
recipient=email,
subject="Sign in to Totem!",
message="It's great to see you again, welcome back. Use the magic link button below \
to access your account. If this wasn't you, please ignore this email.",
subject="Totem sign in link",
title="Sign in link",
message="You requested a link to sign in, and here it is! Note that this link expires in an hour and can only be used once.",
button_text="Sign in",
link=url,
)


def send_new_login_email(email: str, url: str):
_send_button_email(
recipient=email,
subject="Welcome to ✨Totem✨!",
message="We're excited to have you join us. However, we won't be able to reach you until you \
confirm your email address. Please confirm by clicking the button below. If this wasn't you, \
please ignore this email.",
button_text="Confirm",
link=url,
)
if settings.DEBUG:
print("------------------------------------------")
print(f"Sending email to {email} with link\n{url}")
print("------------------------------------------")


def send_change_email(old_email: str, new_email: str, login_url: str):
_send_button_email(
recipient=new_email,
subject="Confirm your new email address",
title="Confirm your new email address",
message="You're almost there! Please confirm your new email address by clicking the button \
below. If this wasn't you, please ignore this email.",
below.",
button_text="Confirm",
link=login_url,
)
Expand All @@ -59,7 +46,8 @@ def send_notify_circle_starting(event: CircleEvent, user: User):
start = event.start.astimezone(user.timezone).strftime("%I:%M %p %Z on %A, %B %d")
_send_button_email(
recipient=user.email,
subject="Your Circle is starting soon!",
subject="Your Circle is starting in an hour",
title="Get Ready",
message=f"Your Circle, {event.circle.title}, is starting at {start}. \
Click the button below to join the Circle. If you are more than 5 minutes late, you may not be allowed to participate.",
button_text="Join Circle",
Expand All @@ -74,7 +62,8 @@ def send_notify_circle_advertisement(event: CircleEvent, user: User):
unsubscribe_url += f"?user={user.slug}&token={event.circle.subscribe_token(user)}&action=unsubscribe"
_send_button_email(
recipient=user.email,
subject="Join an upcoming Circle!",
subject="Join an upcoming Circle",
title="New Circle",
message=f'A session for a Circle you are subscribed to, "{event.circle.title}", is coming up at {start}. \
Click the button below to reserve a spot before this one fills up. If you no longer wish to get notifications about this Circle, \
you can unsubscribe here: {unsubscribe_url}',
Expand All @@ -83,15 +72,15 @@ def send_notify_circle_advertisement(event: CircleEvent, user: User):
)


def _send_button_email(*, recipient: str, subject: str, message: str, button_text: str, link: str):
link = make_email_url(link)
send_template_mail(
template_id="vywj2lpv631l7oqz",
recipient=recipient,
def _send_button_email(*, recipient: str, subject: str, title: str, message: str, button_text: str, link: str):
link = SafeString(make_email_url(link))
send_mjml_mail(
template="button",
recipient_list=[recipient],
subject=subject,
context={
"subject": subject,
"message": message,
"title": title,
"button_text": button_text,
"link": link,
"support_email": settings.EMAIL_SUPPORT_ADDRESS,
Expand All @@ -101,7 +90,3 @@ def _send_button_email(*, recipient: str, subject: str, message: str, button_tex

def make_email_url(link):
return urllib.parse.urljoin(settings.EMAIL_BASE_URL, link)


def render_email(template: str, context: dict[str, Any]) -> str:
return mjml2html(render_to_string(f"email/emails/{template}.mjml", context=context))
4 changes: 4 additions & 0 deletions totem/email/templates/email/email_viewer.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{{ email|safe }}
<script>
document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1"></' + 'script>')
</script>
37 changes: 37 additions & 0 deletions totem/email/templates/email/emails/_base.mjml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{% load static %}
<mjml>
<mj-head>
<mj-attributes>
<mj-all font-family="'Kanit', 'Helvetica', 'Arial', sans-serif"></mj-all>
<mj-button background-color="#F4DC92" color="#000"></mj-button>
<mj-text color="#2B2B2B"></mj-text>
</mj-attributes>
<mj-font
href="https://fonts.googleapis.com/css?family=Kanit:normal,italic,bold&display=swap"
name="Kanit"
></mj-font>
<mj-font
href="https://fonts.googleapis.com/css?family=Cabin:normal,italic,bold&display=swap"
name="Cabin"
></mj-font>
<mj-style inline="inline">
.link-nostyle { color: inherit; text-decoration: none }
</mj-style>
</mj-head>
<mj-body>
<mj-section>
<mj-column>
<mj-spacer height="20px"></mj-spacer>
<mj-image
align="left"
padding="0px"
src="{% static 'images/totem-logo.png' %}"
width="100px"
></mj-image>
<mj-spacer height="20px"></mj-spacer>
</mj-column>
</mj-section>
{% block content %} {% endblock content %} {% include
'email/emails/_footer.mjml' %}
</mj-body>
</mjml>
65 changes: 65 additions & 0 deletions totem/email/templates/email/emails/_footer.mjml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{% load static %}
<mj-section
padding-bottom="72px"
padding-left="30px"
padding-right="30px"
padding-top="72px"
padding="20px"
>
<mj-column padding="0">
<mj-image
align="left"
padding-bottom="0px"
padding-left="10px"
padding-right="10px"
padding-top="0px"
padding="0px"
src="{% static 'images/totem-symbol.png' %}"
width="48px"
></mj-image>
</mj-column>
<mj-column padding="0">
<mj-social
align="right"
font-size="15px"
icon-padding="0px"
icon-size="20px"
inner-padding="5px"
mode="horizontal"
>
<mj-social-element
src="{% static 'images/email/x.png' %}"
alt="https://www.facebook.com/"
href="https://www.facebook.com/"
title="https://www.facebook.com/"
></mj-social-element>
<mj-social-element
src="{% static 'images/email/instagram.png' %}"
alt="https://www.google.com/"
href="https://www.google.com/"
title="https://www.google.com/"
></mj-social-element>
<mj-social-element
src="{% static 'images/email/github.png' %}"
alt="https://www.twitter.com/"
href="https://www.twitter.com/"
title="https://www.twitter.com/"
></mj-social-element>
</mj-social>
<mj-spacer height="16px"></mj-spacer>
<mj-text
align="right"
color="#5B5B5B"
font-family="'Cabin', 'Helvetica', 'Arial', sans-serif"
font-size="14px"
line-height="1.5"
padding-bottom="0px"
padding-left="10px"
padding-right="10px"
padding-top="0px"
padding="0px"
>
Totem Technologies, 501(c)(3).
</mj-text>
</mj-column>
</mj-section>
60 changes: 60 additions & 0 deletions totem/email/templates/email/emails/button.mjml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{% extends 'email/emails/_base.mjml' %} {% load static %} {% block content %}
<mj-section
background-color="#F3F1E9"
border-radius="24px"
padding-bottom="50px"
padding-left="40px"
padding-right="40px"
padding-top="48px"
padding="40px"
>
<mj-column padding="0">
<mj-text font-size="66px" line-height="1.1" padding="0px">
<strong>{{title}}</strong>
</mj-text>
<mj-spacer height="16px"></mj-spacer>
<mj-text
font-family="'Cabin', 'Helvetica', 'Arial', sans-serif"
font-size="20px"
line-height="1.6"
padding="0px"
>
{{message}}
</mj-text>
<mj-spacer height="40px"></mj-spacer>
<mj-button
href="{{link}}"
align="left"
border-radius="40px"
font-size="24px"
line-height="1.75"
padding="0px"
align="center"
>
<strong>{{button_text}}</strong>
</mj-button>
<mj-spacer height="48px"></mj-spacer>
<mj-text
color="#7a7a7a"
font-family="'Cabin', 'Helvetica', 'Arial', sans-serif"
font-size="14px"
line-height="1.6"
padding="0px"
>
If you didn't request this link, you can safely ignore this email. If the
button doesn't work, copy and paste the link below into your browser:
</mj-text>
<mj-spacer height="16px"></mj-spacer>
<mj-text
color="#7a7a7a"
align="center"
font-family="'Cabin', 'Helvetica', 'Arial', sans-serif"
font-size="14px"
line-height="1.6"
padding="0px"
>
<a class="link-nostyle" href="{{link}}">{{link}}</a>
</mj-text>
</mj-column>
</mj-section>
{% endblock %}
5 changes: 5 additions & 0 deletions totem/email/templates/email/emails/button.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

{{title}}
{{message}}
To continue, please click this link: {{ link }}
If this was not you, please ignore this email.
61 changes: 61 additions & 0 deletions totem/email/templates/email/emails/login.mjml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{% extends 'email/emails/_base.mjml' %} {% load static %} {% block content %}
<mj-section
background-color="#F3F1E9"
border-radius="24px"
padding-bottom="50px"
padding-left="40px"
padding-right="40px"
padding-top="48px"
padding="40px"
>
<mj-column padding="0">
<mj-text font-size="66px" line-height="1.1" padding="0px">
<strong>Sign in link</strong>
</mj-text>
<mj-spacer height="16px"></mj-spacer>
<mj-text
font-family="'Cabin', 'Helvetica', 'Arial', sans-serif"
font-size="20px"
line-height="1.6"
padding="0px"
>
You requested a link to sign in, and here it is! Note that this link
expires in an hour and can only be used once.
</mj-text>
<mj-spacer height="40px"></mj-spacer>
<mj-button
href="{{link}}"
align="left"
border-radius="40px"
font-size="24px"
line-height="1.75"
padding="0px"
align="center"
>
<strong>Sign in</strong>
</mj-button>
<mj-spacer height="48px"></mj-spacer>
<mj-text
color="#7a7a7a"
font-family="'Cabin', 'Helvetica', 'Arial', sans-serif"
font-size="14px"
line-height="1.6"
padding="0px"
>
If you didn't request this link, you can safely ignore this email. If the
button doesn't work, copy and paste the link below into your browser:
</mj-text>
<mj-spacer height="16px"></mj-spacer>
<mj-text
color="#7a7a7a"
align="center"
font-family="'Cabin', 'Helvetica', 'Arial', sans-serif"
font-size="14px"
line-height="1.6"
padding="0px"
>
<a class="link-nostyle" href="{{link}}">{{link}}</a>
</mj-text>
</mj-column>
</mj-section>
{% endblock %}
5 changes: 5 additions & 0 deletions totem/email/templates/email/emails/login.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

Totem sign in link

To continue, please click this link: {{ link }}
If this was not you, please ignore this email.
7 changes: 0 additions & 7 deletions totem/email/templates/email/emails/new_login.html

This file was deleted.

6 changes: 0 additions & 6 deletions totem/email/templates/email/emails/new_login.txt

This file was deleted.

Loading

0 comments on commit 9b4748d

Please sign in to comment.