Add confirmation email, logo + tagline signature on all customer emails
This commit is contained in:
parent
66a70d7bc3
commit
b2004bb5ec
2 changed files with 95 additions and 4 deletions
62
app.py
62
app.py
|
|
@ -214,13 +214,14 @@ def save_booth_settings(settings):
|
|||
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 subject: email subject
|
||||
:param body: plain-text body
|
||||
: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
|
||||
if not cfg['SMTP_PASS']:
|
||||
|
|
@ -232,6 +233,25 @@ def send_email(to, subject, body, attachments=None):
|
|||
msg['Subject'] = subject
|
||||
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.
|
||||
if attachments:
|
||||
for path, name in attachments:
|
||||
|
|
@ -244,6 +264,13 @@ def send_email(to, subject, body, attachments=None):
|
|||
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
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -272,6 +299,33 @@ def request_form():
|
|||
extra_requests=request.form.get('extra_requests', '').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')
|
||||
return redirect(url_for('thanks', rid=rid))
|
||||
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']}"
|
||||
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:
|
||||
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')
|
||||
flash('Preview email sent.', 'success')
|
||||
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']}"
|
||||
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:
|
||||
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')
|
||||
flash('Delivery email sent with MP3 attachments.', 'success')
|
||||
except Exception as e:
|
||||
|
|
|
|||
37
example-email.html
Normal file
37
example-email.html
Normal 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>
|
||||
Reference in a new issue