Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds GOV.UK Notify and allows test emails to be sent #154

Merged
merged 6 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions app/core/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,25 @@ class RegulationSearchForm(forms.Form):
}
),
)


class EmailForm(forms.Form):
"""Email form for sending test emails via GOV.UK Notify."""

name = forms.CharField(
label="Name",
required=True,
widget=forms.TextInput(
attrs={"class": "govuk-input", "placeholder": "Enter your name"}
),
)
message = forms.CharField(
label="Message",
required=True,
widget=forms.Textarea(
attrs={
"class": "govuk-textarea",
"placeholder": "Enter your message",
}
),
)
49 changes: 49 additions & 0 deletions app/core/gov_notify.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import logging
import uuid

from notifications_python_client.notifications import NotificationsAPIClient

from django.conf import settings

logger = logging.getLogger(__name__)


class EmailSendError(Exception):
"""Email send error exception.

This class is used to raise exceptions when there is an error
sending an email via the GovUK Notify service.
"""


def send_email_notification(
email_address, template_id, personalisation=None, reference=None
) -> dict:
"""Send email notification.

This function sends an email notification using the GovUK Notify API.

Note: If successful, the response of the GovUK Notify API is returned
as a dictionary which includes an 'id' key for the successfully sent email.
"""
if settings.SUPPRESS_NOTIFY:
logger.warning(
"SUPPRESS_NOTIFY detected, suppressing email"
f" notification to: {email_address}"
)
return {"id": str(uuid.uuid4()), "status": "testing"}
notifications_client = NotificationsAPIClient(
settings.GOVUK_NOTIFY_API_KEY
)
response: dict = notifications_client.send_email_notification(
email_address=email_address,
template_id=template_id,
personalisation=personalisation,
reference=reference,
)
if "id" in response:
# See docstring
response["status"] = "delivered"
return response
else:
raise EmailSendError(response)
35 changes: 34 additions & 1 deletion app/core/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import logging

from django.conf import settings
from django.http import HttpRequest, HttpResponse, HttpResponseRedirect
from django.shortcuts import redirect, render
Expand All @@ -6,9 +8,12 @@
from django.views.decorators.http import require_http_methods, require_safe

from .cookies import get_ga_cookie_preference, set_ga_cookie_policy
from .forms import CookiePreferenceForm
from .forms import CookiePreferenceForm, EmailForm
from .gov_notify import send_email_notification
from .healthcheck import application_service_health

logger = logging.getLogger(__name__)


@require_http_methods(["GET"])
def home(request: HttpRequest) -> HttpResponse:
Expand All @@ -32,6 +37,34 @@ def home(request: HttpRequest) -> HttpResponse:
return render(request, template_name="home.html", context=context)


@require_http_methods(["GET", "POST"])
def feedback_view(request):
if request.method == "POST":
form = EmailForm(request.POST)
if form.is_valid():
name = form.cleaned_data["name"]
message = form.cleaned_data["message"]
email_address = settings.GOVUK_NOTIFY_EMAIL # Set email address

try:
response = send_email_notification(
email_address=email_address,
template_id=settings.GOVUK_NOTIFY_TEMPLATE_ID,
personalisation={"name": name, "message": message},
)
return HttpResponse(f"Email sent successfully: {response}")
except Exception as e:
logger.error(f"Error sending email: {e}")
return HttpResponse(
"An error occurred while sending the email. Please try again later.", # noqa: E501
status=500,
)
else:
form = EmailForm()

return render(request, "feedback.html", {"form": form})


@require_safe
def health_check(request: HttpRequest) -> HttpResponse:
"""Healthcheck endpoint.
Expand Down
44 changes: 44 additions & 0 deletions app/templates/feedback.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{% extends "base.html" %}

{% block head_title %}{{service_name}} - {{ result.title }}{% endblock %}
{% block service_name %}{{service_name}}{% endblock %}

{% block body_content %}
<div class="govuk-width-container">
<div class="govuk-width-container">
{% comment %} <nav class="govuk-breadcrumbs" aria-label="Breadcrumb">
<ol class="govuk-breadcrumbs__list">
<li class="govuk-breadcrumbs__list-item">
<a class="govuk-breadcrumbs__link" href="{{ request.META.HTTP_REFERER }}">Search results</a>
</li>
<li class="govuk-breadcrumbs__list-item">
{{ result.title }}
</li>
</ol>
</nav> {% endcomment %}
<main class="govuk-main-wrapper" id="main-content" role="main">
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-xl">Send feedback</h1>
<form method="post" class="govuk-form-group">
{% csrf_token %}
<div class="govuk-form-group">
<label class="govuk-label govuk-label--m" for="{{ form.name.id_for_label }}">
{{ form.name.label }}
</label>
{{ form.name }}
</div>
<div class="govuk-form-group">
<label class="govuk-label govuk-label--m" for="{{ form.message.id_for_label }}">
{{ form.message.label }}
</label>
{{ form.message }}
</div>
<button type="submit" class="govuk-button">Send</button>
</form>
</div>
</div>
</main>
</div>
</div>
{% endblock %}
9 changes: 8 additions & 1 deletion fbr/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@
"local": "http://localhost:8081",
"dev": "https://dev.find-business-regulations.uktrade.digital/",
"staging": "https://staging.find-business-regulations.uktrade.digital/",
"prod": "https://find-business-regulations.uktrade.digital/",
"prod": "https://find-business-regulations.private-beta.service.trade.gov.uk/",
}

HOSTNAME = HOSTNAME_MAP.get(ENVIRONMENT.lower(), HOSTNAME_MAP["prod"])
Expand All @@ -338,6 +338,13 @@
"GOOGLE_ANALYTICS_TAG_MANAGER_ID", default=None
)

# GOV Notify
GOVUK_NOTIFY_API_KEY = env.str("GOVUK_NOTIFY_API_KEY", default=None)
GOVUK_NOTIFY_TEMPLATE_ID = env.str("GOVUK_NOTIFY_TEMPLATE_ID", default=None)
GOVUK_NOTIFY_EMAIL = env.str("GOVUK_NOTIFY_EMAIL", default=None)

# Suppress email sending for testing, local dev etc
SUPPRESS_NOTIFY = env.bool("SUPPRESS_NOTIFY", default=False)

# Security settings
SECURE_CONTENT_TYPE_NOSNIFF = (
Expand Down
2 changes: 1 addition & 1 deletion fbr/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def publishers(self, request, *args, **kwargs):
core_views.hide_cookie_banner,
name="hide-cookie-banner",
),
# path("search/", orp_views.search, name="search"),
path("feedback/", core_views.feedback_view, name="feedback"),
]

if settings.DJANGO_ADMIN:
Expand Down
5 changes: 5 additions & 0 deletions local.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,8 @@ POSTGRES_HOST_AUTH_METHOD=trust

# Google analytics
GOOGLE_ANALYTICS_TAG_MANAGER_ID=XXX-XXXXXXX # Check passman or ask a colleague

# GOV Notify
GOVUK_NOTIFY_API_KEY=xxx # Check passman or ask a colleague
GOVUK_NOTIFY_TEMPLATE_ID=xxx # Check passman or ask a colleague
GOVUK_NOTIFY_EMAIL=xxx # Your own email address
Loading
Loading