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 status model and save record #601

Merged
merged 2 commits into from
Jul 11, 2024
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
41 changes: 41 additions & 0 deletions eventstore/migrations/0065_whatsapptemplatesendstatus.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Generated by Django 4.2.13 on 2024-07-11 09:37

import uuid

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("eventstore", "0064_openhimqueue_timestamp"),
]

operations = [
migrations.CreateModel(
name="WhatsAppTemplateSendStatus",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
("message_id", models.CharField(blank=True, max_length=255)),
("sent_at", models.DateTimeField(auto_now_add=True)),
("event_received_at", models.DateTimeField(null=True)),
("registration_completed_at", models.DateTimeField(null=True)),
(
"preferred_channel",
models.CharField(
choices=[("SMS", "SMS"), ("WhatsApp", "WhatsApp")],
default="WhatsApp",
max_length=8,
),
),
],
),
]
11 changes: 11 additions & 0 deletions eventstore/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1124,3 +1124,14 @@ class Status(models.IntegerChoices):
status = models.PositiveSmallIntegerField(
choices=Status.choices, default=Status.PENDING
)


class WhatsAppTemplateSendStatus(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
message_id = models.CharField(max_length=255, blank=True)
sent_at = models.DateTimeField(auto_now_add=True)
event_received_at = models.DateTimeField(null=True)
registration_completed_at = models.DateTimeField(null=True)
preferred_channel = models.CharField(
max_length=8, choices=CHANNEL_TYPES, default=WHATSAPP_CHANNELTYPE
)
1 change: 1 addition & 0 deletions ndoh_hub/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ class MediaField(serializers.Serializer):
child=ParametersField(), allow_empty=True, required=False
)
media = MediaField(required=False)
save_status_record = serializers.BooleanField(default=False)
50 changes: 46 additions & 4 deletions ndoh_hub/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import json
from unittest import TestCase

import pytest
import responses

from eventstore import models
from ndoh_hub.utils import (
msisdn_to_whatsapp_id,
normalise_msisdn,
Expand Down Expand Up @@ -53,6 +55,7 @@ def test_update_turn_contact_details(self):
)


@pytest.mark.django_db
class TestSendWhatsappTemplateMessage(TestCase):
@responses.activate
def test_send_whatsapp_template_message_number_on_whatsapp(self):
Expand All @@ -78,11 +81,49 @@ def test_send_whatsapp_template_message_number_on_whatsapp(self):
status=200,
)

response = send_whatsapp_template_message(
preferred_channel, status_id = send_whatsapp_template_message(
msisdn, namespace, template_name, parameters
)

self.assertEqual(response, "WhatsApp")
self.assertEqual(preferred_channel, "WhatsApp")

status_count = models.WhatsAppTemplateSendStatus.objects.count()
self.assertEqual(status_count, 0)

self.assertEqual(len(responses.calls), 2)

@responses.activate
def test_send_whatsapp_template_message_number_on_whatsapp_save_status(self):
"""
Send a template to Whatsapp
"""
parameters = {"type": "text", "text": "test template send"}
namespace = "test"
msisdn = "+27820001001"
template_name = "test template"

responses.add(
method=responses.PATCH,
url="http://turn/v1/contacts/27820001001",
json={},
status=200,
)

responses.add(
method=responses.POST,
url="http://turn/v1/messages",
json={"messages": [{"id": "gBEGkYiEB1VXAglK1ZEqA1YKPrU"}]},
status=200,
)

preferred_channel, status_id = send_whatsapp_template_message(
msisdn, namespace, template_name, parameters, save_status_record=True
)

self.assertEqual(preferred_channel, "WhatsApp")

status = models.WhatsAppTemplateSendStatus.objects.get(id=status_id)
self.assertEqual(status.message_id, "gBEGkYiEB1VXAglK1ZEqA1YKPrU")

self.assertEqual(len(responses.calls), 2)

Expand Down Expand Up @@ -122,11 +163,12 @@ def test_send_whatsapp_template_message_number_not_on_whatsapp(self):
},
)

response = send_whatsapp_template_message(
preferred_channel, status_id = send_whatsapp_template_message(
msisdn, namespace, template_name, parameters
)

self.assertEqual(response, "SMS")
self.assertEqual(preferred_channel, "SMS")
self.assertIsNone(status_id)

self.assertEqual(len(responses.calls), 3)
request = json.loads(responses.calls[0].request.body)
Expand Down
13 changes: 11 additions & 2 deletions ndoh_hub/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from rest_framework.exceptions import AuthenticationFailed
from temba_client.v2 import TembaClient

from eventstore import models
from ndoh_hub.auth import CachedTokenAuthentication
from ndoh_hub.constants import ID_TYPES, LANGUAGES, PASSPORT_ORIGINS # noqa:F401

Expand Down Expand Up @@ -220,7 +221,9 @@ def update_turn_contact_details(wa_id, fields):
response.raise_for_status()


def send_whatsapp_template_message(msisdn, template_name, parameters, media=None):
def send_whatsapp_template_message(
msisdn, template_name, parameters, media=None, save_status_record=False
):
# send whatsapp template
headers = {
"Authorization": f"Bearer {settings.TURN_TOKEN}",
Expand Down Expand Up @@ -258,10 +261,16 @@ def send_whatsapp_template_message(msisdn, template_name, parameters, media=None

response_data = response.json()

status_id = None
prefered_chanel = "WhatsApp"
if "messages" not in response_data:
if response_data["errors"][0]["code"] == 1013:
prefered_chanel = "SMS"
update_turn_contact_details(wa_id, {"is_fallback_active": True})
elif save_status_record:
message_id = response_data["messages"][0]["id"]
status_id = models.WhatsAppTemplateSendStatus.objects.create(
message_id=message_id
).id

return prefered_chanel
return prefered_chanel, status_id
9 changes: 4 additions & 5 deletions ndoh_hub/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@ def post(self, request):
template_name = serializer.validated_data.get("template_name")
parameters = serializer.validated_data.get("parameters", [])
media = serializer.validated_data.get("media")
save_status_record = serializer.validated_data.get("save_status_record")

preferred_channel = send_whatsapp_template_message(
msisdn, template_name, parameters, media
preferred_channel, status_id = send_whatsapp_template_message(
msisdn, template_name, parameters, media, save_status_record
)

return Response(
{
"preferred_channel": preferred_channel,
}
{"preferred_channel": preferred_channel, "status_id": status_id}
)
Loading