feat: feed url update email dispatch#1776
Conversation
There was a problem hiding this comment.
Pull request overview
Implements HTML email templates and fallback rendering for notification dispatch (notably feed.url_updated and an admin dispatch summary), and ensures Cloud Function builds include the new template assets.
Changes:
- Added a shared Jinja2-based email layout (
_base_email.html.j2) and new templates for feed URL updates (single + digest) and admin dispatch summaries. - Updated
brevo_notification_senderto render HTML fallbacks via Jinja2 templates (instead of inline string concatenation) and to enrich event row context (feed page URLs, providers, etc.). - Updated Cloud Function build/deps to include
.j2templates in the build artifact and add Jinja2 totasks_executorrequirements.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/function-python-build.sh | Includes .j2 template files when assembling function build artifacts. |
| functions-python/tasks_executor/requirements.txt | Adds Jinja2 dependency needed for template rendering in notification dispatch. |
| api/tests/unittest/test_brevo_notification_sender.py | Adds/updates unit tests for template loading and Jinja2 autoescape behavior. |
| api/src/shared/notifications/templates/feed_url_updated_single.html.j2 | New single-event feed URL update email template (extends shared base). |
| api/src/shared/notifications/templates/feed_url_updated_digest.html.j2 | New digest feed URL update email template (extends shared base). |
| api/src/shared/notifications/templates/change_tracker_email.html.j2 | Refactors existing GTFS diff template to extend the shared base layout. |
| api/src/shared/notifications/templates/admin_event_summary.html.j2 | New admin dispatch summary email template (extends shared base). |
| api/src/shared/notifications/templates/_base_email.html.j2 | New shared base layout for notification emails (header/footer/styles/blocks). |
| api/src/shared/notifications/brevo_notification_sender.py | Introduces Jinja2 environment, safe-link/thousands filters, and template-based HTML fallbacks. |
Comments suppressed due to low confidence (1)
api/src/shared/notifications/templates/change_tracker_email.html.j2:103
- In Jinja2,
{% extends %}must appear before any executable template statements (macros, blocks, etc.). This template defines macros earlier in the file before theextendstag, which can raise aTemplateAssertionErroror prevent inheritance from working. Move theextendstag to the top (after the initial{# ... #}comment block) and keep macro definitions after it (or extract macros into an imported template).
| if events[0].notification_type_id == NotificationTypeId.ADMIN_EVENT_SUMMARY: | ||
| # One run summary per event (most digests contain a single summary). | ||
| return "".join(build_admin_summary_html(e) for e in events) |
|
@Alessandro100 The feed ID won't be meaningful to users who subscribe. We should include the old producer URL, the new producer URL, and the transit provider name so users can understand the change. We also talked about prompting users to subscribe to the new feed. |
|
@emmambd I agree that adding the transit provider name would be more meaningful than just the stable id, but in the notification event we currently do not expose the transit provider name, that would be a larger change For prompting the user, was the vision
For option 1, it's already in place |
|
@Alessandro100 Option 1 works here for sure. In regards to not exposing the transit provider name, I think that's a larger change we have to do, otherwise the email notification will not be meaningful and users will be confused. I can open a new issue for it - I assume it goes back to the backend logic in #1723? cc @davidgamez |
|
@emmambd provider name was added |
|
@Alessandro100 Amazing! I'd use the transit provider name in the Subject Line and remove the id from the table column |
|
@emmambd done |
8e26ba2 to
99f812f
Compare
|
@Alessandro100 This is great! Thanks for these changes. Maybe a broader comment: If the email will show as from Mobility Database, do we need [Mobility Database] in the subject line? |
|
@emmambd Good point, the email sender will aways be MobilityData which gives context to the user to what this is |
| @@ -0,0 +1,295 @@ | |||
| <!doctype html> | |||
|
LGTM to me now as well |


Summary:
closes #1751
Implements email templates for the following notification events
Expected behavior:
When a producer url changes or redirects it should send an email to the users who are subscribed
Testing tips:
[Internal team]
For integrated tests, use DEV environment. As the notification endpoints are not implemented, notification-related entities need to be created via SQL.
notification_subscriptiontable; replace with the target user id(REPLACE_ME_WITH_USER_ID)notifications_dispatch_plantask from retool(DEV)Notes
account/notification(good)Please make sure these boxes are checked before submitting your pull request - thanks!
./scripts/api-tests.shto make sure you didn't break anything(bonus)
