Add confirmation email, logo + tagline signature on all customer emails

This commit is contained in:
Troll (Hermes Agent) 2026-08-01 23:06:19 +00:00
parent 66a70d7bc3
commit b2004bb5ec
2 changed files with 95 additions and 4 deletions

62
app.py
View file

@ -214,13 +214,14 @@ def save_booth_settings(settings):
flash(f'Warning: could not save settings: {e}', 'error') flash(f'Warning: could not save settings: {e}', 'error')
def send_email(to, subject, body, attachments=None): def send_email(to, subject, body, attachments=None, inline_images=None):
""" """
Send an email via SMTP_SSL. Send an email via SMTP using credentials from the app config.
:param to: recipient address :param to: recipient address
:param subject: email subject :param subject: email subject
:param body: plain-text body :param body: plain-text body
:param attachments: optional list of (filepath, attachment_name) tuples :param attachments: optional list of (filepath, attachment_name) tuples
:param inline_images: optional list of (filepath, cid) tuples for inline images
""" """
cfg = current_app.config cfg = current_app.config
if not cfg['SMTP_PASS']: if not cfg['SMTP_PASS']:
@ -232,6 +233,25 @@ def send_email(to, subject, body, attachments=None):
msg['Subject'] = subject msg['Subject'] = subject
msg.set_content(body) msg.set_content(body)
# Build HTML version of the email with the same body and optional inline images.
html_body = body.replace('\n', '<br>\n')
if inline_images:
for _, cid in inline_images:
html_body += f'<br><img src="cid:{cid}" alt="Dionysis Media" style="max-width:200px;margin-top:1rem;"/>'
html_body += f'<br><br><hr style="border:none;border-top:1px solid #ddd;"/><p style="font-size:0.9rem;color:#555;">Dionysis Media: stories, sound, and a little divine chaos — <a href="https://dionysismedia.ca/">https://dionysismedia.ca/</a></p>'
msg.add_alternative(html_body, subtype='html')
# Attach inline images for HTML rendering.
if inline_images:
for path, cid in inline_images:
with open(path, 'rb') as f:
data = f.read()
# Guess subtype from extension.
ext = Path(path).suffix.lower().lstrip('.')
maintype = 'image'
subtype = ext if ext in ('png', 'jpg', 'jpeg', 'gif', 'webp') else 'png'
msg.get_payload()[1].add_related(data, maintype=maintype, subtype=subtype, cid=f'<{cid}>')
# Attach any MP3 files as audio/mpeg attachments. # Attach any MP3 files as audio/mpeg attachments.
if attachments: if attachments:
for path, name in attachments: for path, name in attachments:
@ -244,6 +264,13 @@ def send_email(to, subject, body, attachments=None):
server.send_message(msg) server.send_message(msg)
def build_signature_images():
"""Return inline image tuple list for the Dionysis Media logo if present."""
logo_path = Path('/mnt/Storage/DM-Logo.png')
if logo_path.exists():
return [(str(logo_path), 'dm-logo')]
return []
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Public customer routes # Public customer routes
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -272,6 +299,33 @@ def request_form():
extra_requests=request.form.get('extra_requests', '').strip(), extra_requests=request.form.get('extra_requests', '').strip(),
vocal_gender=request.form.get('vocal_gender', '').strip(), vocal_gender=request.form.get('vocal_gender', '').strip(),
) )
# Send confirmation email with a summary of what the customer asked for.
req = get_request_by_id(rid)
if req:
try:
body_lines = [
f"Hi {req['name']},",
"",
"Thanks for stopping by the Trollgorithm Theme Song Booth! We've received your request and will start crafting your custom song soon.",
"",
"Here's what we have on file:",
f"Name: {req['name']}",
f"Email: {req['email']}",
f"Style / genre: {req['style_genre'] or '-'}",
f"Preferred singer voice / gender: {req['vocal_gender'] or 'No preference'}",
f"Hobbies: {req['hobbies'] or '-'}",
f"Notable facts: {req['notable_facts'] or '-'}",
f"Extra requests: {req['extra_requests'] or '-'}",
"",
"You'll get another email with a private link to preview two versions of your song when they're ready.",
"",
"— Trollgorithm / Dionysis Media"
]
send_email(req['email'], 'Your theme song request is received', '\n'.join(body_lines), inline_images=build_signature_images())
except Exception as e:
flash(f'Your request was saved, but we could not send a confirmation email: {e}', 'error')
flash('Your request has been submitted! Check your email soon.', 'success') flash('Your request has been submitted! Check your email soon.', 'success')
return redirect(url_for('thanks', rid=rid)) return redirect(url_for('thanks', rid=rid))
return render_template('request.html') return render_template('request.html')
@ -495,7 +549,7 @@ def admin_request(rid):
player_link = f"{current_app.config['PUBLIC_BASE_URL']}/play/{req['player_token']}" player_link = f"{current_app.config['PUBLIC_BASE_URL']}/play/{req['player_token']}"
body = f"Hi {req['name']},\n\nYour custom theme song has been created. Listen to both versions and let us know which one you want:\n\n{player_link}\n\n- Version A\n- Version B\n- Or both versions\n\nOnce you make your choice, we'll send you to the booth to finalize payment and deliver your files.\n\nThanks for stopping by!\n\n{current_app.config['BOOTH_NAME']}" body = f"Hi {req['name']},\n\nYour custom theme song has been created. Listen to both versions and let us know which one you want:\n\n{player_link}\n\n- Version A\n- Version B\n- Or both versions\n\nOnce you make your choice, we'll send you to the booth to finalize payment and deliver your files.\n\nThanks for stopping by!\n\n{current_app.config['BOOTH_NAME']}"
try: try:
send_email(req['email'], 'Your custom theme song is ready — listen and pick your version', body) send_email(req['email'], 'Your custom theme song is ready — listen and pick your version', body, inline_images=build_signature_images())
update_request(rid, preview_sent_at=now_utc(), status='songs_uploaded') update_request(rid, preview_sent_at=now_utc(), status='songs_uploaded')
flash('Preview email sent.', 'success') flash('Preview email sent.', 'success')
except Exception as e: except Exception as e:
@ -523,7 +577,7 @@ def admin_request(rid):
player_link = f"{current_app.config['PUBLIC_BASE_URL']}/play/{req['player_token']}" player_link = f"{current_app.config['PUBLIC_BASE_URL']}/play/{req['player_token']}"
body = f"Hi {req['name']},\n\nThanks for your payment! Your selected song(s) are attached to this email.\n\nYou can also keep streaming them here: {player_link}\n\nEnjoy!\n\n{current_app.config['BOOTH_NAME']}" body = f"Hi {req['name']},\n\nThanks for your payment! Your selected song(s) are attached to this email.\n\nYou can also keep streaming them here: {player_link}\n\nEnjoy!\n\n{current_app.config['BOOTH_NAME']}"
try: try:
send_email(req['email'], 'Your theme song files are here!', body, attachments=attachments) send_email(req['email'], 'Your theme song files are here!', body, attachments=attachments, inline_images=build_signature_images())
update_request(rid, square_payment_ref=payment_ref, delivery_sent_at=now_utc(), status='delivered') update_request(rid, square_payment_ref=payment_ref, delivery_sent_at=now_utc(), status='delivered')
flash('Delivery email sent with MP3 attachments.', 'success') flash('Delivery email sent with MP3 attachments.', 'success')
except Exception as e: except Exception as e:

37
example-email.html Normal file
View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: system-ui, sans-serif; background: #f3f4f6; padding: 2rem; }
.email { max-width: 600px; margin: 0 auto; background: #fff; border: 1px solid #ddd; border-radius: 8px; padding: 2rem; }
h2 { color: #111827; }
hr { border: none; border-top: 1px solid #ddd; margin: 1.5rem 0; }
.footer { font-size: 0.9rem; color: #555; }
.footer img { max-width: 200px; margin-top: 1rem; display: block; }
</style>
</head>
<body>
<div class="email">
<h2>Your theme song request is received</h2>
<p>Hi Craig,</p>
<p>Thanks for stopping by the Trollgorithm Theme Song Booth! We've received your request and will start crafting your custom song soon.</p>
<p><strong>Here's what we have on file:</strong></p>
<ul>
<li>Name: Craig</li>
<li>Email: craig@example.com</li>
<li>Style / genre: Country Metal</li>
<li>Preferred singer voice / gender: male</li>
<li>Hobbies: Dungeons and dragons, Video Games, family</li>
<li>Notable facts: Cattle Rancher, chalk artist, loves "Ted Lasso" TV Show, Lives on Nickel Valley Ranch</li>
<li>Extra requests: -</li>
</ul>
<p>You'll get another email with a private link to preview two versions of your song when they're ready.</p>
<p>— Trollgorithm / Dionysis Media</p>
<hr>
<div class="footer">
<img src="file:///mnt/Storage/DM-Logo.png" alt="Dionysis Media">
<p>Dionysis Media: stories, sound, and a little divine chaos — <a href="https://dionysismedia.ca/">https://dionysismedia.ca/</a></p>
</div>
</div>
</body>
</html>