From 2ee668f7e9ec5e7d6b42c4958bd932f81781f0b4 Mon Sep 17 00:00:00 2001 From: elitonzky Date: Fri, 15 Sep 2023 12:37:03 -0300 Subject: [PATCH] feature: adds on create translation new button type OTP --- .../migrations/0007_auto_20230915_1035.py | 52 ++++++++++++++ marketplace/wpp_templates/models.py | 12 +++- marketplace/wpp_templates/requests.py | 14 ++-- marketplace/wpp_templates/serializers.py | 71 +++++++++++++++---- 4 files changed, 127 insertions(+), 22 deletions(-) create mode 100644 marketplace/wpp_templates/migrations/0007_auto_20230915_1035.py diff --git a/marketplace/wpp_templates/migrations/0007_auto_20230915_1035.py b/marketplace/wpp_templates/migrations/0007_auto_20230915_1035.py new file mode 100644 index 00000000..d5abf8ca --- /dev/null +++ b/marketplace/wpp_templates/migrations/0007_auto_20230915_1035.py @@ -0,0 +1,52 @@ +# Generated by Django 3.2.4 on 2023-09-15 13:35 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("wpp_templates", "0006_templatetranslation_message_template_id"), + ] + + operations = [ + migrations.AddField( + model_name="templatebutton", + name="autofill_text", + field=models.CharField(max_length=255, null=True), + ), + migrations.AddField( + model_name="templatebutton", + name="otp_type", + field=models.CharField( + choices=[("COPY_CODE", "Copy Code"), ("ONE_TAP", "One Tap")], + max_length=10, + null=True, + ), + ), + migrations.AddField( + model_name="templatebutton", + name="package_name", + field=models.CharField(max_length=255, null=True), + ), + migrations.AddField( + model_name="templatebutton", + name="signature_hash", + field=models.CharField(max_length=255, null=True), + ), + migrations.AlterField( + model_name="templatebutton", + name="button_type", + field=models.CharField( + choices=[ + ("QUICK_REPLY", "WhatsApp.data.templates.buttons.type.quick_reply"), + ( + "PHONE_NUMBER", + "WhatsApp.data.templates.buttons.type.phone_number", + ), + ("URL", "WhatsApp.data.templates.buttons.type.url"), + ("OTP", "WhatsApp.data.templates.buttons.type.otp"), + ], + max_length=20, + ), + ), + ] diff --git a/marketplace/wpp_templates/models.py b/marketplace/wpp_templates/models.py index f3dd4145..2b22419a 100644 --- a/marketplace/wpp_templates/models.py +++ b/marketplace/wpp_templates/models.py @@ -118,19 +118,27 @@ class TemplateButton(models.Model): ("QUICK_REPLY", "WhatsApp.data.templates.buttons.type.quick_reply"), ("PHONE_NUMBER", "WhatsApp.data.templates.buttons.type.phone_number"), ("URL", "WhatsApp.data.templates.buttons.type.url"), + ("OTP", "WhatsApp.data.templates.buttons.type.otp"), + ) + OTP_TYPE_CHOICES = ( + ("COPY_CODE", "Copy Code"), + ("ONE_TAP", "One Tap"), ) uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) - translation = models.ForeignKey( TemplateTranslation, on_delete=models.CASCADE, related_name="buttons" ) - button_type = models.CharField(max_length=20, choices=BUTTON_TYPE_CHOICES) text = models.CharField(max_length=30, null=True) country_code = models.IntegerField(null=True) phone_number = models.CharField(max_length=20, null=True) url = models.CharField(max_length=2000, null=True) + # to authentication category + otp_type = models.CharField(max_length=10, choices=OTP_TYPE_CHOICES, null=True) + package_name = models.CharField(max_length=255, null=True) + signature_hash = models.CharField(max_length=255, null=True) + autofill_text = models.CharField(max_length=255, null=True) class TemplateHeader(models.Model): diff --git a/marketplace/wpp_templates/requests.py b/marketplace/wpp_templates/requests.py index b708e8e8..27ade67f 100644 --- a/marketplace/wpp_templates/requests.py +++ b/marketplace/wpp_templates/requests.py @@ -45,29 +45,29 @@ def create_template_message( params = dict( name=name, category=category, - components=str(components), + components=components, language=language, access_token=self._access_token, ) response = requests.post( url=f"https://graph.facebook.com/{WHATSAPP_VERSION}/{waba_id}/message_templates", - params=params, + json=params, ) if response.status_code != 200: raise FacebookApiException(response.json()) return response.json() - def update_template_message(self, message_template_id: str, name: str, components: str) -> dict: + def update_template_message( + self, message_template_id: str, name: str, components: str + ) -> dict: params = dict( - name=name, - components=str(components), - access_token=self._access_token + name=name, components=str(components), access_token=self._access_token ) response = requests.post( url=f"https://graph.facebook.com/{WHATSAPP_VERSION}/{message_template_id}", params=params, - ) + ) if response.status_code != 200: raise FacebookApiException(response.json()) diff --git a/marketplace/wpp_templates/serializers.py b/marketplace/wpp_templates/serializers.py index 2534b964..3fe96846 100644 --- a/marketplace/wpp_templates/serializers.py +++ b/marketplace/wpp_templates/serializers.py @@ -37,9 +37,26 @@ class ButtonSerializer(serializers.ModelSerializer): phone_number = serializers.CharField(required=False) url = serializers.CharField(required=False) + otp_type = serializers.ChoiceField( + choices=[("COPY_CODE", "COPY_CODE"), ("ONE_TAP", "ONE_TAP")], required=False + ) + package_name = serializers.CharField(required=False) + signature_hash = serializers.CharField(required=False) + autofill_text = serializers.CharField(required=False) + class Meta: model = TemplateButton - fields = ["button_type", "text", "country_code", "phone_number", "url"] + fields = [ + "button_type", + "text", + "country_code", + "phone_number", + "url", + "otp_type", + "package_name", + "signature_hash", + "autofill_text", + ] class TemplateTranslationSerializer(serializers.Serializer): @@ -138,19 +155,47 @@ def create(self, validated_data: dict) -> None: for button in buttons: button = dict(button) - button["type"] = button.get("button_type") - if button.get("phone_number"): - button[ - "phone_number" - ] = f'+{button.get("country_code")} {button.get("phone_number")}' - - button_component = button - button_component.pop("button_type") - - if button_component.get("country_code"): - button_component.pop("country_code") - buttons_component.get("buttons").append(button_component) + # Specific treatment for "OTP" type buttons in the "AUTHENTICATION" category + if ( + template.category == "AUTHENTICATION" + and button.get("button_type") == "OTP" + ): + button["type"] = "OTP" + if button.get("otp_type") == "COPY_CODE": + button = { + "type": "OTP", + "otp_type": "COPY_CODE", + } + + elif button.get("otp_type") == "ONE_TAP": + if not all(k in button for k in ["package_name", "signature_hash"]): + raise ValidationError( + "For ONE_TAP buttons, 'package_name' and 'signature_hash' are required." + ) + + button = { + "type": "OTP", + "otp_type": "ONE_TAP", + "package_name": button.get("package_name"), + "signature_hash": button.get("signature_hash"), + } + + # Only add autofill_text if it's provided + if "autofill_text" in button: + button["autofill_text"] = button.get("autofill_text") + + else: + if button.get("phone_number"): + button[ + "phone_number" + ] = f'+{button.get("country_code")} {button.get("phone_number")}' + button["type"] = button.get("button_type") + button.pop("button_type", None) + if button.get("country_code"): + button.pop("country_code") + + buttons_component.get("buttons").append(button) if buttons_component.get("buttons"): components = self.append_to_components(components, buttons_component)