Skip to content

Commit 3fcd353

Browse files
notes email
1 parent 5df9691 commit 3fcd353

File tree

6 files changed

+179
-11
lines changed

6 files changed

+179
-11
lines changed

scripts/email/execute_template.py

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
# from templates.feb2025_vday.vday import *
99

1010
# from templates.dryrun import *
11+
from templates.notes_release.notesEmail import *
1112

1213
# Load environment variables from .env
1314
load_dotenv(".env.private")

scripts/email/helpers/firebase_users_loader.py

+26-11
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,38 @@
2626
# return user_names
2727

2828

29+
def get_all_user_names() -> Dict[str, Tuple[str, str, str]]:
30+
"""Fetches all user names from Firebase and returns a mapping of email to (first, middle, last) names."""
31+
print("Fetching all user names from Firebase...")
32+
user_names = {}
33+
docs = db.collection("user-name").get()
34+
for doc in docs:
35+
data = doc.to_dict()
36+
user_names[doc.id] = (
37+
data.get("firstName", None),
38+
data.get("middleName", None),
39+
data.get("lastName", None),
40+
)
41+
return user_names
42+
43+
2944
def get_users() -> Dict[Tuple[str, str], List[Dict]]:
3045
print("Fetching all user data from Firebase...")
31-
# user_names = get_all_user_names()
46+
user_names = get_all_user_names()
3247
users = db.collection("user-onboarding-data").get()
3348
user_map = defaultdict(list)
3449

3550
for user in users:
3651
user_data = user.to_dict()
3752
email = user.id
38-
# first_name, middle_name, last_name = user_names.get(
39-
# email, (None, None, None)
40-
# ) # NOTE: may cause type errors if we don't have a name for this user and try
41-
# # to send them an email regardless. (Deliberate decision.)
53+
first_name, middle_name, last_name = user_names.get(
54+
email, (None, None, None)
55+
) # NOTE: may cause type errors if we don't have a name for this user and try
56+
# to send them an email regardless. (Deliberate decision.)
4257

43-
# # Deleted accounts or something? Not sure to do with these people.
44-
# if first_name is None and middle_name is None and last_name is None:
45-
# print(f"User {email} not found in user-name collection!")
58+
# Deleted accounts or something? Not sure to do with these people.
59+
if first_name is None and middle_name is None and last_name is None:
60+
print(f"User {email} not found in user-name collection!")
4661

4762
colleges = [
4863
college.get("acronym", "") for college in user_data.get("colleges", [])
@@ -59,9 +74,9 @@ def get_users() -> Dict[Tuple[str, str], List[Dict]]:
5974
user_map[key].append(
6075
{
6176
"email": email,
62-
# "first_name": first_name,
63-
# "middle_name": middle_name,
64-
# "last_name": last_name,
77+
"first_name": first_name,
78+
"middle_name": middle_name,
79+
"last_name": last_name,
6580
"colleges": colleges,
6681
"grad_programs": grad_programs,
6782
"entrance_semester": entrance_sem,
Loading
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import sys
2+
import os
3+
4+
# Add the root directory to the system path. The script should be run from the root (`courseplan`) directory.
5+
sys.path.append(
6+
os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "..", ".."))
7+
)
8+
9+
from scripts.email.helpers.firebase_users_loader import USERS
10+
11+
12+
# BCC = [user["email"] for user_list in USERS.values() for user in user_list]
13+
BCC = ["[email protected]", "[email protected]"] # 2025 Spring PMM & PM
14+
# BCC = ["[email protected]"] # 2024 Fall and 2025 Spring TPM
15+
16+
print(f"{len(BCC)} users are relevant to this template.\n")
17+
SUBJECT = "Take Note! CoursePlan Just Got Smarter."
18+
HTML = f"""
19+
20+
<div style="font-family: Proxima Nova, sans-serif; margin: 0 auto; background-color: #F7F7F7; font-size: 16px;">
21+
<div style="text-align: center; padding: 40px 0px;">
22+
<a href="https://ibb.co/dsg7Ww5R"><img src="https://i.ibb.co/NgS7VdyM/Screenshot-2025-02-13-at-5-12-07-PM.png" alt="CoursePlan Logo" border="0" style="height: 60px; width: 60px;";></a>
23+
</div>
24+
<div style="background-color: #FFFFFF; border-radius: 10px; padding: 40px 48px; max-width: 600px; margin: 0 auto;">
25+
26+
<p style="font-weight: bold;">HEY COURSEPLANNER,</p>
27+
28+
<h2 style="color: #198F80; text-transform: uppercase; text-align: center; margin-bottom: 5px;">Introducing</h2>
29+
<h1 style="text-align: center; font-weight: bold; margin-top: 0;">NOTES</h1>
30+
31+
<p>Picking the right classes just got easier! CoursePlan now lets you add <strong>Notes</strong> under your courses — perfect for reminders like:</p>
32+
33+
<p>
34+
✅ Only take this if [Professor Name] is teaching!<br>
35+
✅ Pairs well with [Another Course] for a lighter workload<br>
36+
✅ This class fills fast—enroll ASAP!
37+
</p>
38+
39+
<h3 style="font-weight: bold;">Add a Note in Seconds 📑</h3>
40+
<p>Quickly jot down important details under any course in your planner. Just click on a class, select "Add Note," and type away!</p>
41+
42+
<div style="text-align: center;">
43+
<a href="https://gifyu.com/image/bblzy"><img src="https://s3.gifyu.com/images/bblzy.gif" alt="creatingNotes1" border="0" style="height:400px; width: 300px; border-radius: 20px"/></a>
44+
<div style="position: relative; height: 0;"><iframe id="js_video_iframe" src="https://jumpshare.com/embed/hjuKgADurbT4UzqAZNFa" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen style="position: absolute; top: 0; left: 0; height: 50px; width: 50px;"></iframe></div>
45+
46+
<p style="color: #198F80; text-align: center; font-size: 14px;">🔹Pro tip: Use notes to flag prerequisites or warnings from upperclassmen!</p>
47+
48+
<h3 style="font-weight: bold;">Customize Your Notes 🎨</h3>
49+
<p>Make Notes work for you! Edit them anytime by clicking on the note field.</p>
50+
51+
<div style="text-align: center;">
52+
<a href="https://gifyu.com/image/bblsg"><img src="https://s3.gifyu.com/images/bblsg.png" alt="Editing Note" border="0" style="height: 240px; width: 300px; border-radius: 0" /></a>
53+
54+
<h3 style="font-weight: bold;">Delete When You're Done ❌</h3>
55+
<p>Changing plans? Removing a note is as easy as clicking the "X" next to it. Keep your CoursePlan clean and up to date!</p>
56+
<div style="text-align: center; margin: 20px 0;">
57+
<a href="https://gifyu.com/image/bblLW"><img src="https://s3.gifyu.com/images/bblLW.gif" alt="creatingNotes2" border="0" style="height: 285px; width: 280px; border-radius:20px" /></a>
58+
</div>
59+
<p>We're always taking notes 🗒️ on how to improve CoursePlan for you! Got feedback? Questions? Suggestions? Hit us up at <a href="mailto:[email protected]" style="color: #1AA9A5; text-decoration: none;">[email protected]</a>.</p>
60+
61+
<p>We’re also working on some exciting updates, so follow us on <a href="https://www.instagram.com/courseplan.io/" style="color: #1AA9A5; text-decoration: none;">Instagram</a> for the latest! Expect to hear from us every so often—right in your inbox.</p>
62+
<p>See you soon,<br>
63+
Your friends at CoursePlan DTI ❤️</p>
64+
65+
<p style="text-align: center;">
66+
Not a user yet? <a href="https://courseplan.io" style="color: #1AA9A5; text-decoration: underline;">Get started here</a><br>
67+
Don't want to graduate? <a href="https://courseplan.io" style="color: #1AA9A5; text-decoration: underline;">Unsubscribe</a>
68+
</p>
69+
</div>
70+
</div>
71+
72+
<div
73+
style="background-color: #105351; color: white; padding: 15px 35px; font-size: 16px; font-family: Proxima Nova, sans-serif;">
74+
<div style="display: flex; margin: 0 auto;">
75+
<p style="margin-left: 0; margin-right: auto;">Schedule Smarter. Plan Ahead.</p>
76+
<p style="margin-left: auto; margin-right: 0;">
77+
<a href="https://www.instagram.com/courseplan.io/" style="color: #1AA9A5; text-decoration: underline;">Instagram</a>
78+
<span style="margin: 0 5px;">•</span>
79+
<a href="https://courseplan.io" style="color: #1AA9A5; text-decoration: underline;"">CoursePlan</a>
80+
</p>
81+
</div>
82+
</div>
83+
84+
"""
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import sys
2+
import os
3+
4+
# Add the root directory to the system path. The script should be run from the root (`courseplan`) directory.
5+
sys.path.append(
6+
os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "..", ".."))
7+
)
8+
9+
from scripts.email.helpers.firebase_users_loader import USERS
10+
11+
USER_DATA = [
12+
(user["email"], user["first_name"])
13+
for user_list in USERS.values()
14+
for user in user_list
15+
]
16+
# BCC = [user["email"] for user_list in USERS.values() for user in user_list]
17+
18+
19+
20+
print(f"{len(BCC)} users are relevant to this template.\n")
21+
SUBJECT = "Make your Schedule Swoon Worthy - Hello from CoursePlan💙"
22+
for email, first_name in USER_DATA:
23+
greeting_name = (
24+
first_name if first_name else "there"
25+
) # Fallback to "Hi there!" if no name
26+
27+
HTML = f"""
28+
<div style="font-family: Proxima Nova, sans-serif; margin: 0 auto; background-color: #F7F7F7; font-size: 16px;">
29+
<div style="text-align: center; padding: 40px 0px;">
30+
<a href="https://ibb.co/dsg7Ww5R"><img src="https://i.ibb.co/NgS7VdyM/Screenshot-2025-02-13-at-5-12-07-PM.png"
31+
alt="CoursePlan Logo" border="0" style="height: 60px; width: 60px;"></a>
32+
</div>
33+
<div style="background-color: #FFFFFF; border-radius: 10px; padding: 40px 48px; margin-bottom: 20px; max-width: 600px; margin: 0 auto;">
34+
35+
<p style="margin: 0; font-size: 16px;"><strong>💘 Hi {greeting_name}, Welcome Back, Big Red! 💘</strong></p>
36+
<p style="line-height: 1.5; font-size: 16px;">Roses are red, violets are blue, Spring semester is here, and we’re excited for you! 🌹✨
37+
Whether you're falling in love with new classes or just happy to reunite with campus, CoursePlan is here to help you stay on track. </p>
38+
39+
<p style="line-height: 1.5; font-size: 16px;"> 💡 Need to organize your schedule or check your requirements? We’ve got you covered—because nothing says true love like a well-planned semester. 💕 </p>
40+
41+
<h3 style="font-size: 24px; text-align: center; margin-bottom: 5px;">Love is in the Air… and So is Course Planning!</h3>
42+
43+
<div style="padding: 20px;">
44+
<img src="https://user-images.githubusercontent.com/55263191/117371152-669f2d00-ae95-11eb-9b92-3d18a0505f57.png"
45+
alt="Schedule Planning" style="width: 100%; height: auto; margin-bottom: -4px;">
46+
<p style="color: #3D3D3D; text-align: center; font-size: 15px; width: 50%; margin: 0 auto 16px;">Your dream schedule is just one click away!</p>
47+
<div style="text-align: center;">
48+
<a href="https://courseplan.io" target="_blank"
49+
style="background-color: #508197; color: white; text-decoration: none; padding: 10px 33px; border-radius: 5px; display: inline-block; font-family: Albert Sans, Proxima Nova, sans-serif; font-size: 15px; letter-spacing: 0.05em;">Start Planning</a>
50+
</div>
51+
</div>
52+
53+
<p style="line-height: 1.5; font-size: 16px;">Wishing you a semester full of success, learning, and love at first plan as you map out the perfect schedule! Happy Spring 2025! 🎉</p>
54+
55+
<p style="line-height: 1.5; font-size: 16px;">Got a question, comment, or just wanna share some CoursePlan love? 💌 Hit us up at
56+
<a href="mailto:[email protected]" style="color: #1AA9A5; text-decoration: none;" target="_blank">[email protected]</a>
57+
— we’d love to hear from you!! P.S. We’re working on some sweet updates just for you. 🍫 Follow us on
58+
<a href="https://www.instagram.com/courseplan.io/" style="color: #1AA9A5; text-decoration: none;" target="_blank">Instagram</a>
59+
to stay in the loop, and keep an eye on your inbox for little love notes (aka helpful tips & updates) from us!</p>
60+
61+
<p style="line-height: 1.5; font-size: 16px;">
62+
Catch you soon!<br>
63+
Your Valentine - CoursePlan DTI 💕 </p>
64+
</div>
65+
</div>
66+
"""
67+
68+
# print(f"Sending email to {email} with personalized greeting: Hi {greeting_name}!")

0 commit comments

Comments
 (0)