Email service with internationalisation and MJML-based markup
Project summary
Title: Email service with internationalisation and MJML-based
markup
Proposed mentors: bitmap, reosarevok, yvanzo
Languages/skills: Rust, HTML & templating, Email
Estimated Project Length: 350 hours, including optional extensions
Expected Outcomes:
-
Mail service that sends multipart HTML and text emails
-
Mail service supports internationalisation
-
Mail service can send emails concurrently
Extension Objectives:
-
Mail service directly reads subscriptions from the main database
-
Mail service handles complex/long term sending errors, like dead
addresses -
Mail service is integrated with other MetaBrainz projects
Contact information
-
JadedBlueEyes on IRC
-
[email redacted]
-
Jade (@JadedBlueEyes@tech.lgbt) - LGBTQIA+ and Tech on
Mastodon -
Timezone: Europe/London (GMT)
Personal Introduction
Hello! I’m Jade - or JadedBlueEyes in most places. I’m a long-time
programmer, and I’m currently in my first year studying Computer Science
with a year in Industry (BSc) at the University of Kent in England. I’ve
been a MusicBrainz user for a while now - I created my account
(Jellis16) back in 2020 because I wanted to add a few albums from my
collection that were missing. When I found that MetaBrainz were
participating in GSoC, I knew I wanted to do my project with you!
Proposed project
This project is starting from the MJML-based email project
idea.
However, it is significantly increased in scope.
-
Currently, emails from the MusicBrainz server are generated using
the Template Toolkit Perl library -
The emails are only sent in plain text
-
The emails can only be sent in English
-
Limitations in the current system make it slow - it takes 4 hours
a day to send subscription updates at the moment
The aim of this project is to implement a new mailing system which:
-
Allows sending both HTML-formatted and plain text multipart emails
-
Significantly improves performance
-
Enables translation of emails.
At a high level, it will achieve this by:
-
Writing a new mailing service in Rust
-
Integrating with existing translation infrastructure to allow translation of email templates
-
Using the MJML markup language (via mrml to format emails
-
Using the html2text library to convert formatted emails into an appropriate textual format
-
Sending the resulting emails via MetaBrainz’s existing infrastructure (SMTP servers or local sendmail installation)
-
Allowing sending emails from the MusicBrainz server to the mailing service in bulk to take advantage of Rust’s parallelism.
-
Handling errors in mail sending, and retrying where appropriate.
-
Optionally, reading subscriptions directly from the Postgres database and sending them without the involvement of the MusicBrainz server at all.
For a single email, this might look like the following:
I have also made a mockup of what an email could look
like, although the
final templates will be created together with aerozol.
Timeline
-
Week 1
-
This week is mostly allocated to getting orientated!
-
This is time to get familiar with the existing codebase and
expected dependencies, talk to everyone involved and make sure
everything is set! -
If I don’t need the full time, I can start on the project early
-
This is also when I will talk with aerozol about the intended
design of the email templates.
-
-
Week 2
-
Implementing a minimum viable service
- This will accept a HTTP JSON API call, select the correct
template and produce a multipart email
- This will accept a HTTP JSON API call, select the correct
-
I’ll be writing documentation, tests and logging throughout the
project
-
-
Week 3/4
-
Integrate translation
-
This involves:
-
Syncing with Weblate
-
Selecting the correct language for the user
-
There is a pre-existing language preference stored for
the UI, which can be used- It may be worth adding a separate option for the
email language.
- It may be worth adding a separate option for the
-
-
Inserting translation strings into the template
-
The existing translation infrastructure uses a custom
perl-inspired template format, and allows a subset of
HTML -
This formatting library does not already exist in Rust,
so some alternative should be used here -
Fluent has been suggested, and there are other options availible.
-
-
-
-
Week 5
-
Template writing
-
I will write some draft versions of the most commonly used
email templates -
These are mainly for testing, finding issues with the
translation setup, and informing the final designs
-
-
Text output finetuning
-
Prior testing shows that the default output of html2text
isn’t as good as it could be -
This is when I will finetune it to gain an acceptible output
-
This may involve implementing a custom
Renderer
-
-
I will work with aerozol to start creating the final templates.
-
-
Week 6
-
Bulk sending
-
This involves adding an API method to send a batch of emails
-
These should then be sent concurrently
-
Once they are all sent, a response should be returned
-
-
-
Week 7
-
Alternative API methods
-
Talking on IRC about how to integrate the service with the
server, a HTTP API over the network may not be the preferred
final implementation. -
The existing React renderer communicates over a local socket
-
This is when I’ll implement the final communication method -
whether that is sockets or something else.
-
-
-
Week 8
-
Integrating with monitoring infrastructure
-
MetaBrainz uses Sentry and Prometheus for monitoring and
observability -
This is when I will work on integrating those into the service.
-
This will involve hooking the Sentry SDK into existing logging
code and writing metrics collectors.
-
-
Week 9
-
Reading subscriptions from the database
-
As an additional optimisation, the service could directly read
user subscriptions from the database and send them itself. -
This would add a fair amount of complexity to the service (and
deploying it), so it’s an optional extension
-
-
Week 10
-
Integration and deployment
-
This should be when I start working on deploying the application
into a production environment -
At this point integration code should have been written, and it
should be clear how the final application will be deployed -
I expect it to be deployed either as a separate container or as
a subprocess of the MusicBrainz server, depending on how
communication is implemented -
This should mostly just be ironing out issues.
-
-
Week 11/12
-
Breathe a sigh of relief that the main project is done! Or not,
because there’s a fair chance something could take longer than
expected and push the timeline back. This is some margin for
that. -
If everything is done on time and there are no issues, I can
work on more complicated error handling at this point- For example, marking dead addresses and mail servers after
some number of retries.
- For example, marking dead addresses and mail servers after
-
Community affinities
What type of music do you listen to?
A lot of music! Some recent favourites:
-
“EVERGREEN” by PVRIS
(Favorite tracks: TAKE MY NIRVANA or HEADLIGHTS) -
“Serpentina” by BANKS
(Favorite track: Meteorite) -
“Excursions” by C418
(Favorite track: Beton, but I usually listen to the whole album!)
What aspects of MusicBrainz/ListenBrainz/BookBrainz/Picard interest
you the most?
I really love the goal of collecting metadata for all the music in the
world! It’s both incredibly useful and incredibly impressive as a
technical and social feat. I created my MusicBrainz account back in
April 2020, and I’d been using Picard for a while before that for my
collection. I also find ListenBrainz fascinating - both in revealing my
own listening habits and opening up music recommendation algorithms,
which have mostly been the secret sauce of streaming services. I’ve
managed to accumulate more than 18,000 listens so far!
Have you ever used MusicBrainz Picard to tag your files or used any of
our projects in the past?
See above!
Programming precedents
When did you first start programming?
It depends on what you count as programming! I started fiddling with
scratch and stuff before I can remember, but I picked up steam when I
was a tween - making a website for a group I volunteered with at 11 and
releasing my first app around 12/13 to 2000+ daily users.
Have you contributed to other open source projects? If so, which
projects and can we see some of your code?
I’ve contributed to a few over the years, but never anything major! A
lot of what I’ve done is locked away in private repos, but I do have a
few public projects, too.
-
GitHub - JadedBlueEyes/fendapp -
A calculator written in Rust using Freya/Dioxus and fend. This is
sitting on my desktop in fairly regular use right now! -
GitHub - JadedBlueEyes/bmc -
A little learning project, this implements the Brookshire Machine
Algorithm in Rust. -
I’ve made small code contributions to projects ranging from Vite to
Jekyll
If you have not contributed to open source projects, do you have other
code we can look at?
If you message me I’m fairly happy to show you most of what I’ve worked
on, from marketing websites to my coursework
What sorts of programming projects have you done on your own time?
-
Quite a few websites, using a variety of tech (Svelte, Vue, Jekyll
are the main names) -
GitHub - JadedBlueEyes/fendapp -
A desktop calculator in Rust -
I’ve modified quite a few libraries for my own purposes
-
Quite a few learning projects - for example, an interactive
visualisation of PageRank.
Practical requirements
What computer(s) do you have available for working on your SoC
project?
-
I’ve got a desktop, running Fedora.
-
I’ve got a laptop running Windows 11 Pro
-
And an Android phone
How much time do you have available per week, and how would you plan
to use it?
My university summer term, exam season, is from the 6th of May to the
14th of June. My final exam is on the 3rd of June. From that point
onwards, it will be my summer holidays. I expect the holidays to be free
of any other major commitments. I expect to be able to spend around 30
hours a week working on the project.