Skip to content

Commit 8dc7419

Browse files
authored
Merge pull request #601 from praekeltfoundation/capi-backend-changes
Add status model and save record
2 parents 05206e1 + f49250b commit 8dc7419

File tree

6 files changed

+114
-11
lines changed

6 files changed

+114
-11
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Generated by Django 4.2.13 on 2024-07-11 09:37
2+
3+
import uuid
4+
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
("eventstore", "0064_openhimqueue_timestamp"),
12+
]
13+
14+
operations = [
15+
migrations.CreateModel(
16+
name="WhatsAppTemplateSendStatus",
17+
fields=[
18+
(
19+
"id",
20+
models.UUIDField(
21+
default=uuid.uuid4,
22+
editable=False,
23+
primary_key=True,
24+
serialize=False,
25+
),
26+
),
27+
("message_id", models.CharField(blank=True, max_length=255)),
28+
("sent_at", models.DateTimeField(auto_now_add=True)),
29+
("event_received_at", models.DateTimeField(null=True)),
30+
("registration_completed_at", models.DateTimeField(null=True)),
31+
(
32+
"preferred_channel",
33+
models.CharField(
34+
choices=[("SMS", "SMS"), ("WhatsApp", "WhatsApp")],
35+
default="WhatsApp",
36+
max_length=8,
37+
),
38+
),
39+
],
40+
),
41+
]

eventstore/models.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,3 +1124,14 @@ class Status(models.IntegerChoices):
11241124
status = models.PositiveSmallIntegerField(
11251125
choices=Status.choices, default=Status.PENDING
11261126
)
1127+
1128+
1129+
class WhatsAppTemplateSendStatus(models.Model):
1130+
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
1131+
message_id = models.CharField(max_length=255, blank=True)
1132+
sent_at = models.DateTimeField(auto_now_add=True)
1133+
event_received_at = models.DateTimeField(null=True)
1134+
registration_completed_at = models.DateTimeField(null=True)
1135+
preferred_channel = models.CharField(
1136+
max_length=8, choices=CHANNEL_TYPES, default=WHATSAPP_CHANNELTYPE
1137+
)

ndoh_hub/serializers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ class MediaField(serializers.Serializer):
1616
child=ParametersField(), allow_empty=True, required=False
1717
)
1818
media = MediaField(required=False)
19+
save_status_record = serializers.BooleanField(default=False)

ndoh_hub/tests/test_utils.py

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import json
22
from unittest import TestCase
33

4+
import pytest
45
import responses
56

7+
from eventstore import models
68
from ndoh_hub.utils import (
79
msisdn_to_whatsapp_id,
810
normalise_msisdn,
@@ -53,6 +55,7 @@ def test_update_turn_contact_details(self):
5355
)
5456

5557

58+
@pytest.mark.django_db
5659
class TestSendWhatsappTemplateMessage(TestCase):
5760
@responses.activate
5861
def test_send_whatsapp_template_message_number_on_whatsapp(self):
@@ -78,11 +81,49 @@ def test_send_whatsapp_template_message_number_on_whatsapp(self):
7881
status=200,
7982
)
8083

81-
response = send_whatsapp_template_message(
84+
preferred_channel, status_id = send_whatsapp_template_message(
8285
msisdn, namespace, template_name, parameters
8386
)
8487

85-
self.assertEqual(response, "WhatsApp")
88+
self.assertEqual(preferred_channel, "WhatsApp")
89+
90+
status_count = models.WhatsAppTemplateSendStatus.objects.count()
91+
self.assertEqual(status_count, 0)
92+
93+
self.assertEqual(len(responses.calls), 2)
94+
95+
@responses.activate
96+
def test_send_whatsapp_template_message_number_on_whatsapp_save_status(self):
97+
"""
98+
Send a template to Whatsapp
99+
"""
100+
parameters = {"type": "text", "text": "test template send"}
101+
namespace = "test"
102+
msisdn = "+27820001001"
103+
template_name = "test template"
104+
105+
responses.add(
106+
method=responses.PATCH,
107+
url="http://turn/v1/contacts/27820001001",
108+
json={},
109+
status=200,
110+
)
111+
112+
responses.add(
113+
method=responses.POST,
114+
url="http://turn/v1/messages",
115+
json={"messages": [{"id": "gBEGkYiEB1VXAglK1ZEqA1YKPrU"}]},
116+
status=200,
117+
)
118+
119+
preferred_channel, status_id = send_whatsapp_template_message(
120+
msisdn, namespace, template_name, parameters, save_status_record=True
121+
)
122+
123+
self.assertEqual(preferred_channel, "WhatsApp")
124+
125+
status = models.WhatsAppTemplateSendStatus.objects.get(id=status_id)
126+
self.assertEqual(status.message_id, "gBEGkYiEB1VXAglK1ZEqA1YKPrU")
86127

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

@@ -122,11 +163,12 @@ def test_send_whatsapp_template_message_number_not_on_whatsapp(self):
122163
},
123164
)
124165

125-
response = send_whatsapp_template_message(
166+
preferred_channel, status_id = send_whatsapp_template_message(
126167
msisdn, namespace, template_name, parameters
127168
)
128169

129-
self.assertEqual(response, "SMS")
170+
self.assertEqual(preferred_channel, "SMS")
171+
self.assertIsNone(status_id)
130172

131173
self.assertEqual(len(responses.calls), 3)
132174
request = json.loads(responses.calls[0].request.body)

ndoh_hub/utils.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from rest_framework.exceptions import AuthenticationFailed
1818
from temba_client.v2 import TembaClient
1919

20+
from eventstore import models
2021
from ndoh_hub.auth import CachedTokenAuthentication
2122
from ndoh_hub.constants import ID_TYPES, LANGUAGES, PASSPORT_ORIGINS # noqa:F401
2223

@@ -220,7 +221,9 @@ def update_turn_contact_details(wa_id, fields):
220221
response.raise_for_status()
221222

222223

223-
def send_whatsapp_template_message(msisdn, template_name, parameters, media=None):
224+
def send_whatsapp_template_message(
225+
msisdn, template_name, parameters, media=None, save_status_record=False
226+
):
224227
# send whatsapp template
225228
headers = {
226229
"Authorization": f"Bearer {settings.TURN_TOKEN}",
@@ -258,10 +261,16 @@ def send_whatsapp_template_message(msisdn, template_name, parameters, media=None
258261

259262
response_data = response.json()
260263

264+
status_id = None
261265
prefered_chanel = "WhatsApp"
262266
if "messages" not in response_data:
263267
if response_data["errors"][0]["code"] == 1013:
264268
prefered_chanel = "SMS"
265269
update_turn_contact_details(wa_id, {"is_fallback_active": True})
270+
elif save_status_record:
271+
message_id = response_data["messages"][0]["id"]
272+
status_id = models.WhatsAppTemplateSendStatus.objects.create(
273+
message_id=message_id
274+
).id
266275

267-
return prefered_chanel
276+
return prefered_chanel, status_id

ndoh_hub/views.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@ def post(self, request):
1717
template_name = serializer.validated_data.get("template_name")
1818
parameters = serializer.validated_data.get("parameters", [])
1919
media = serializer.validated_data.get("media")
20+
save_status_record = serializer.validated_data.get("save_status_record")
2021

21-
preferred_channel = send_whatsapp_template_message(
22-
msisdn, template_name, parameters, media
22+
preferred_channel, status_id = send_whatsapp_template_message(
23+
msisdn, template_name, parameters, media, save_status_record
2324
)
2425

2526
return Response(
26-
{
27-
"preferred_channel": preferred_channel,
28-
}
27+
{"preferred_channel": preferred_channel, "status_id": status_id}
2928
)

0 commit comments

Comments
 (0)