Repository: hedyorg/hedy

Issue:
Send email when teacher is made teacher
I can draft the email! Something with: 

* Welcome to Hedy
* What teachers accounts can do
* How to ask for help



Discussion:
Nice idea! Feel free to assign me the bit that sends the email if you want, once the text is there.
Hi @fpereiro,

Can you work with this text:

----

[Hedy logo]

**Welcome!**

Congratulations with your brand new Hedy teachers account. Welcome to the world wide community of Hedy teachers!

**What teachers accounts can do**

With your teacher account, you have the option to create classes. Your students can than join your classes and you can see their progress. Classes are made and managed though the for teachers page [link].

**How to shares ideas**

If you are using Hedy in class, you probably get ideas for improvements! You can shares those ideas with us on the Ideas Discussion [link: https://github.com/Felienne/hedy/discussions/categories/ideas]

**How to ask for help**

If anything is unclear, you can post in the Q&A discussion [link: https://github.com/Felienne/hedy/discussions/categories/q-a], or send us an email [mailto]

Keep programming!
The Hedy team.


------

And can we send this email with Hedy website fonts instead of plain text? And a bit of Hedy/tailwind coloring too, like a blue bar on the top and the grey sides?

@Felienne A few points:
- Do we plan on internationalizing this text or just keep it in English?
- We currently store the texts for our current emails in a line-by-line basis here: https://github.com/Felienne/hedy/blob/main/coursedata/texts/en.yaml#L112 . If we want to add custom templating, maybe we should start using an actual Jinja template for emails, starting with this one.
- External stylesheets won't work, but I can embed a minimum amount of inline CSS to give it a Hedy style.
> @Felienne A few points:
> 
> * Do we plan on internationalizing this text or just keep it in English?

English is fine for now.

> * We currently store the texts for our current emails in a line-by-line basis here: https://github.com/Felienne/hedy/blob/main/coursedata/texts/en.yaml#L112 . If we want to add custom templating, maybe we should start using an actual Jinja template for emails, starting with this one.
> * External stylesheets won't work, but I can embed a minimum amount of inline CSS to give it a Hedy style.

Let's start with a bit of inline css than, I think templates for emails would be too much work (not really worth it)



Resolving patch:
diff --git a/website/auth.py b/website/auth.py
--- a/website/auth.py
+++ b/website/auth.py
@@ -4,7 +4,7 @@
 import urllib
 from flask import request, make_response, jsonify, redirect
 from flask_helpers import render_template
-from utils import timems, times, extract_bcrypt_rounds, is_testing_request, is_debug_mode, valid_email, is_heroku, mstoisostring
+from utils import timems, times, extract_bcrypt_rounds, is_testing_request, is_debug_mode, valid_email, is_heroku, mstoisostring, load_yaml_uncached
 import datetime
 from functools import wraps
 from config import config
@@ -55,6 +55,7 @@ def is_teacher (request):
 # The translations are imported here because current_user above is used by hedyweb.py and we need to avoid circular dependencies
 import hedyweb
 TRANSLATIONS = hedyweb.Translations ()
+EMAILS = load_yaml_uncached ('website/emails.yaml')
 
 # Thanks to https://stackoverflow.com/a/34499643
 def requires_login (f):
@@ -223,7 +224,7 @@ def signup ():
             resp = make_response ({'username': username, 'token': hashed_token})
         # Otherwise, we send an email with a verification link and we return an empty body
         else:
-            send_email_template ('welcome_verify', email, requested_lang (), os.getenv ('BASE_URL', 'http://localhost') + '/auth/verify?username=' + urllib.parse.quote_plus (username) + '&token=' + urllib.parse.quote_plus (hashed_token))
+            send_email_template ('welcome_verify', email, os.getenv ('BASE_URL', 'http://localhost') + '/auth/verify?username=' + urllib.parse.quote_plus (username) + '&token=' + urllib.parse.quote_plus (hashed_token))
             resp = make_response ({})
 
         # We set the cookie to expire in a year, just so that the browser won't invalidate it if the same cookie gets renewed by constant use.
@@ -292,7 +293,7 @@ def change_password (user):
 
         DATABASE.update_user(user ['username'], {'password': hashed})
         if not is_testing_request (request):
-            send_email_template ('change_password', user ['email'], requested_lang (), None)
+            send_email_template ('change_password', user ['email'], None)
 
         return '', 200
 
@@ -340,7 +341,7 @@ def update_profile (user):
                 if is_testing_request (request):
                    resp = {'username': user ['username'], 'token': hashed_token}
                 else:
-                    send_email_template ('welcome_verify', email, requested_lang (), os.getenv ('BASE_URL') + '/auth/verify?username=' + urllib.parse.quote_plus (user['username']) + '&token=' + urllib.parse.quote_plus (hashed_token))
+                    send_email_template ('welcome_verify', email, os.getenv ('BASE_URL') + '/auth/verify?username=' + urllib.parse.quote_plus (user['username']) + '&token=' + urllib.parse.quote_plus (hashed_token))
 
         username = user ['username']
 
@@ -400,7 +401,7 @@ def recover ():
             # If this is an e2e test, we return the email verification token directly instead of emailing it.
             return jsonify ({'username': user ['username'], 'token': token}), 200
         else:
-            send_email_template ('recover_password', user ['email'], requested_lang (), os.getenv ('BASE_URL') + '/reset?username=' + urllib.parse.quote_plus (user ['username']) + '&token=' + urllib.parse.quote_plus (token))
+            send_email_template ('recover_password', user ['email'], os.getenv ('BASE_URL') + '/reset?username=' + urllib.parse.quote_plus (user ['username']) + '&token=' + urllib.parse.quote_plus (token))
             return '', 200
 
     @app.route ('/auth/reset', methods=['POST'])
@@ -432,7 +433,7 @@ def reset ():
         user = DATABASE.user_by_username(body ['username'])
 
         if not is_testing_request (request):
-            send_email_template ('reset_password', user ['email'], requested_lang (), None)
+            send_email_template ('reset_password', user ['email'], None)
 
         return '', 200
 
@@ -460,6 +461,9 @@ def mark_as_teacher ():
 
         DATABASE.update_user(user ['username'], {'is_teacher': 1 if body ['is_teacher'] else 0})
 
+        if body ['is_teacher'] and not is_testing_request (request):
+            send_email_template ('welcome_teacher', user ['email'], '')
+
         return '', 200
 
     @app.route ('/admin/changeUserEmail', methods=['POST'])
@@ -494,7 +498,7 @@ def change_user_email():
         if is_testing_request (request):
            resp = {'username': user ['username'], 'token': hashed_token}
         else:
-            send_email_template ('welcome_verify', body ['email'], requested_lang (), os.getenv ('BASE_URL') + '/auth/verify?username=' + urllib.parse.quote_plus (user ['username']) + '&token=' + urllib.parse.quote_plus (hashed_token))
+            send_email_template ('welcome_verify', body ['email'], os.getenv ('BASE_URL') + '/auth/verify?username=' + urllib.parse.quote_plus (user ['username']) + '&token=' + urllib.parse.quote_plus (hashed_token))
 
         return '', 200
 
@@ -527,8 +531,8 @@ def send_email (recipient, subject, body_plain, body_html):
     else:
         print ('Email sent to ' + recipient)
 
-def send_email_template (template, email, lang, link):
-    texts = TRANSLATIONS.get_translations (lang, 'Auth')
+def send_email_template (template, email, link):
+    texts = EMAILS
     subject = texts ['email_' + template + '_subject']
     body = texts ['email_' + template + '_body'].split ('\n')
     body = [texts ['email_hello']] + body
@@ -537,11 +541,14 @@ def send_email_template (template, email, lang, link):
     body = body + texts ['email_goodbye'].split ('\n')
 
     body_plain = '\n'.join (body)
-    body_html = '<p>' + '</p><p>'.join (body) + '</p>'
+
+    with open('templates/base_email.html', 'r', encoding='utf-8') as f:
+        body_html = f.read ()
+    body_html += '<p>' + '</p><p>'.join (body) + '</p>'
+    body_html += '</div>'
     if link:
         body_plain = body_plain.replace ('@@LINK@@', 'Please copy and paste this link into a new tab: ' + link)
         body_html = body_html.replace ('@@LINK@@', '<a href="' + link + '">Link</a>')
-    body_html += '<br><img style="max-width: 100px" src="http://www.hedycode.com/images/Hedy-logo.png">'
 
     send_email (email, subject, body_plain, body_html)
 


Test patch: