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

Add a count of remaining messages to the 80% warning emails #1971

Merged
merged 16 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from 8 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
14 changes: 10 additions & 4 deletions app/notifications/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def send_warning_email_limit_emails_if_needed(service: Service) -> None:
if bool_nearing_email_daily_limit:
cache_key = near_email_daily_limit_cache_key(service.id)
if not redis_store.get(cache_key):
send_near_email_limit_email(service)
send_near_email_limit_email(service, todays_current_email_count)
redis_store.set(cache_key, current_time, ex=cache_expiration)

# Send a warning when reaching the daily message limit
Expand All @@ -198,7 +198,7 @@ def send_warning_sms_limit_emails_if_needed(service: Service):
if nearing_sms_daily_limit:
cache_key = near_sms_daily_limit_cache_key(service.id)
if not redis_store.get(cache_key):
send_near_sms_limit_email(service)
send_near_sms_limit_email(service, todays_requested_sms)
redis_store.set(cache_key, current_time, ex=cache_expiration)

# Send a warning when reaching the daily message limit
Expand Down Expand Up @@ -293,14 +293,17 @@ def warn_about_daily_message_limit(service: Service, messages_sent):
raise LiveServiceTooManyRequestsError(service.message_limit)


def send_near_sms_limit_email(service: Service):
def send_near_sms_limit_email(service: Service, sms_sent):
limit_reset_time_et = get_limit_reset_time_et()
sms_remaining = service.message_limit - sms_sent
send_notification_to_service_users(
service_id=service.id,
template_id=current_app.config["NEAR_DAILY_SMS_LIMIT_TEMPLATE_ID"],
personalisation={
"service_name": service.name,
"contact_url": f"{current_app.config['ADMIN_BASE_URL']}/contact",
"remaining_en": "{:,}".format(sms_remaining),
"remaining_fr": "{:,}".format(sms_remaining).replace(",", " "),
"message_limit_en": "{:,}".format(service.sms_daily_limit),
"message_limit_fr": "{:,}".format(service.sms_daily_limit).replace(",", " "),
"limit_reset_time_et_12hr": limit_reset_time_et["12hr"],
Expand All @@ -311,18 +314,21 @@ def send_near_sms_limit_email(service: Service):
current_app.logger.info(f"service {service.id} is approaching its daily sms limit of {service.sms_daily_limit}")


def send_near_email_limit_email(service: Service) -> None:
def send_near_email_limit_email(service: Service, emails_sent) -> None:
"""
Send an email to service users when nearing the daily email limit.

"""
limit_reset_time_et = get_limit_reset_time_et()
emails_remaining = service.message_limit - emails_sent
send_notification_to_service_users(
service_id=service.id,
template_id=current_app.config["NEAR_DAILY_EMAIL_LIMIT_TEMPLATE_ID"],
personalisation={
"service_name": service.name,
"contact_url": f"{current_app.config['ADMIN_BASE_URL']}/contact",
"remaining_en": "{:,}".format(emails_remaining),
"remaining_fr": "{:,}".format(emails_remaining).replace(",", " "),
"message_limit_en": "{:,}".format(service.message_limit),
"message_limit_fr": "{:,}".format(service.message_limit).replace(",", " "),
"limit_reset_time_et_12hr": limit_reset_time_et["12hr"],
Expand Down
101 changes: 101 additions & 0 deletions migrations/versions/0437_email_templates_msgs_left.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"""

Revision ID: 0437_email_templates_msgs_left
Revises: 0436_add_columns_api_keys
Create Date: 2023-10-05 00:00:00

"""
from datetime import datetime

from alembic import op
from flask import current_app

revision = "0437_email_templates_msgs_left"
down_revision = "0436_add_columns_api_keys"

near_content = "\n".join(
[
"(la version française suit)",
"",
"Hello ((name)),",
"",
"((service_name)) can send ((message_limit_en)) emails per day. You’ll be blocked from sending if you exceed that limit before ((limit_reset_time_et_12hr)) Eastern Time. Check [your current local time](https://nrc.canada.ca/en/web-clock/).",
"",
"((service_name)) can send ((remaining_en)) more messages until your limit resets at 7 pm Eastern Time. Compare [official times across Canada](https://nrc.canada.ca/en/web-clock/).",
"",
"To request a limit increase, [contact us](https://notification.canada.ca/contact). We’ll respond within 1 business day.",
"",
"The GC Notify team",
"",
"---",
"",
"Bonjour ((name)),",
"",
"(service_name)) a envoyé ((count)) courriels de sa limite de ((message_limit_fr)) courriels par 24 heures.",
"",
"((service_name)) peut encore envoyer ((remaining)) messages d’ici à ce que votre limite de courriels soit réinitialisée à 19 h, heure de l’Est. Comparez les heures officielles à travers le Canada.",
"",
"Pour demander une augmentation de votre limite, veuillez nous joindre. Nous vous répondrons en un jour ouvrable.",
"",
"L’équipe Notification GC",
]
)

templates = [
{
"id": current_app.config["NEAR_DAILY_EMAIL_LIMIT_TEMPLATE_ID"],
"name": "Near daily EMAIL limit",
"template_type": "email",
"content": near_content,
"subject": "((service_name)) is near its daily limit for emails. | La limite quotidienne d’envoi de courriels est presque atteinte pour ((service_name)).",
"process_type": "priority",
},
]


def upgrade():
conn = op.get_bind()

for template in templates:
current_version = conn.execute("select version from templates where id='{}'".format(template["id"])).fetchone()
template["version"] = current_version[0] + 1

template_update = """
UPDATE templates SET content = '{}', subject = '{}', version = '{}', updated_at = '{}'
WHERE id = '{}'
"""
template_history_insert = """
INSERT INTO templates_history (id, name, template_type, created_at, content, archived, service_id, subject,
created_by_id, version, process_type, hidden)
VALUES ('{}', '{}', '{}', '{}', '{}', False, '{}', '{}', '{}', {}, '{}', false)
"""

for template in templates:
op.execute(
template_update.format(
template["content"],
template["subject"],
template["version"],
datetime.utcnow(),
template["id"],
)
)

op.execute(
template_history_insert.format(
template["id"],
template["name"],
template["template_type"],
datetime.utcnow(),
template["content"],
current_app.config["NOTIFY_SERVICE_ID"],
template["subject"],
current_app.config["NOTIFY_USER_ID"],
template["version"],
template["process_type"],
)
)


def downgrade():
pass
102 changes: 102 additions & 0 deletions migrations/versions/0438_sms_templates_msgs_left.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
"""

Revision ID: 0438_sms_templates_msgs_left
Revises: 0437_email_templates_msgs_left
Create Date: 2023-10-05 00:00:00

"""
from datetime import datetime

from alembic import op
from flask import current_app

revision = "0438_sms_templates_msgs_left"
down_revision = "0437_email_templates_msgs_left"

near_content = "\n".join(
[
"(la version française suit)",
"",
"Hello ((name)),",
"",
"((service_name)) has sent ((count)) out of its limit of ((message_limit_en)) text messages per 24 hours.",
"",
"((service_name)) can send ((remaining)) more messages until your limit resets at 7 pm Eastern Time. Compare official times across Canada.",
"",
"To request a limit increase, contact us. We’ll respond within 1 business day.",
"",
"The GC Notify team",
"---",
"",
"Bonjour ((name)),",
"",
"((service_name)) a envoyé ((count)) messages de sa limite de ((message_limit_fr)) messages texte par 24 heures.",
"",
"((service_name)) peut encore envoyer ((remaining)) messages d’ici à ce que votre limite de messages texte soit réinitialisée à 19 h, heure de l’Est. Comparez les heures officielles à travers le Canada.",
"",
"Pour demander une augmentation de votre limite, veuillez nous joindre. Nous vous répondrons en un jour ouvrable.",
"",
"L’équipe Notification GC",
]
)


templates = [
{
"id": current_app.config["NEAR_DAILY_SMS_LIMIT_TEMPLATE_ID"],
"template_type": "email",
"subject": "((service_name)) is near its daily limit for text messages. | La limite quotidienne d’envoi de messages texte est presque atteinte pour ((service_name)).",
"content": near_content,
"process_type": "priority",
},
]


def upgrade():
conn = op.get_bind()

for template in templates:
current_version = conn.execute("select version from templates where id='{}'".format(template["id"])).fetchone()
name = conn.execute("select name from templates where id='{}'".format(template["id"])).fetchone()
template["version"] = current_version[0] + 1
template["name"] = name[0]

template_update = """
UPDATE templates SET content = '{}', subject = '{}', version = '{}', updated_at = '{}'
WHERE id = '{}'
"""
template_history_insert = """
INSERT INTO templates_history (id, name, template_type, created_at, content, archived, service_id, subject,
created_by_id, version, process_type, hidden)
VALUES ('{}', '{}', '{}', '{}', '{}', False, '{}', '{}', '{}', {}, '{}', false)
"""

for template in templates:
op.execute(
template_update.format(
template["content"],
template["subject"],
template["version"],
datetime.utcnow(),
template["id"],
)
)

op.execute(
template_history_insert.format(
template["id"],
template["name"],
template["template_type"],
datetime.utcnow(),
template["content"],
current_app.config["NOTIFY_SERVICE_ID"],
template["subject"],
current_app.config["NOTIFY_USER_ID"],
template["version"],
template["process_type"],
)
)


def downgrade():
pass
4 changes: 3 additions & 1 deletion tests/app/notifications/test_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ def test_check_service_message_limit_records_nearing_daily_limit(

service = create_sample_service(notify_db, notify_db_session, restricted=True, limit=5, sms_limit=5)
template = create_sample_template(notify_db, notify_db_session, service=service, template_type=limit_type)
for x in range(4):
for x in range(5):
create_sample_notification(notify_db, notify_db_session, service=service, template=template)

if limit_type == "sms":
Expand All @@ -232,6 +232,8 @@ def test_check_service_message_limit_records_nearing_daily_limit(
personalisation={
"service_name": service.name,
"contact_url": f"{current_app.config['ADMIN_BASE_URL']}/contact",
"remaining_en": "1",
"remaining_fr": "1",
"message_limit_en": "5",
"message_limit_fr": "5",
**kwargs,
Expand Down