Skip to content

Fix inconsistent SendGrid transactional email configuration #272

Description

@gaidheal1

Summary

Transactional email is configured inconsistently: the app is using Django SMTP delivery, but the environment/config suggests a partial Twilio SendGrid setup that does not match the code path.

Findings

  1. The app is using SMTP, not the SendGrid API client.

    • progress_rpg/settings/prod.py sets EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend".
    • There are no active sendgrid client imports/usages in the email send path.
  2. The configured credential name does not match the backend in use.

    • Django SMTP reads EMAIL_HOST_PASSWORD from progress_rpg/settings/base.py.
    • The local env has a SENDGRID_API_KEY entry, but no EMAIL_HOST_PASSWORD entry.
    • Result: SMTP auth will fail even if a SendGrid API key exists, because the SMTP backend never reads SENDGRID_API_KEY.
  3. The SMTP host value is malformed.

    • The local env's EMAIL_HOST value has leading whitespace.
    • Result: hostname resolution / SMTP connection can fail before auth.
  4. The built-in email smoke-test command is broken.

    • users/management/commands/send_test_email.py references an undefined recipient variable after calling send_mail(...).
    • Result: manual verification is misleading because the command crashes even if the send succeeds.
  5. Some auth emails are sent asynchronously through Celery.

    • users/adapters.py queues confirmation emails through send_rendered_email_task.delay(...).
    • Result: even with correct SMTP config, signup/confirmation mail also depends on the Celery worker having the same valid email env vars and being healthy.

Why this breaks in practice

  • Signup requires email verification (ACCOUNT_EMAIL_VERIFICATION = "mandatory"), so if transactional email fails, users cannot complete registration.
  • The current setup mixes SendGrid package presence / API-key naming with an SMTP backend, so the key config is effectively disconnected from the code that actually sends mail.

Recommended fix

Choose one delivery path and wire it consistently.

Option A: Keep SMTP (smallest change)

  • Set EMAIL_HOST=smtp.sendgrid.net with no leading/trailing whitespace.
  • Set EMAIL_PORT=587.
  • Set EMAIL_HOST_USER=apikey.
  • Set EMAIL_HOST_PASSWORD to the SendGrid API key.
  • Keep EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend.
  • Set DEFAULT_FROM_EMAIL / sender address to a verified sender or authenticated domain in SendGrid.
  • Ensure the same env vars are present for both the web service and Celery worker.
  • Fix the send_test_email command so it reports success correctly.

Option B: Switch to the SendGrid API backend

  • Replace SMTP backend usage with a real SendGrid backend/client integration.
  • Use SENDGRID_API_KEY directly in settings.
  • Remove unused/confusing SMTP-only env expectations.

Acceptance criteria

  • Transactional emails send successfully in the target environment.
  • Signup confirmation emails are delivered end-to-end.
  • Web and Celery use the same valid email configuration.
  • The smoke-test command provides a trustworthy pass/fail result.
  • Email configuration is documented so the chosen delivery path is unambiguous.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: adminSubscription, billing, account management, and backend configuration

    Type

    No fields configured for Task.

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions