diff --git a/temba/utils/whatsapp/clients.py b/temba/utils/whatsapp/clients.py new file mode 100644 index 00000000000..573d81af7de --- /dev/null +++ b/temba/utils/whatsapp/clients.py @@ -0,0 +1,21 @@ +import requests + +from django.conf import settings + +from temba.utils.whatsapp.interfaces import FacebookCatalog + + +class RequestsFacebookCatalog(FacebookCatalog): + def get_facebook_catalogs(self, waba_id): + url = f"https://graph.facebook.com/v17.0/{waba_id}/product_catalogs" + + headers = {"Authorization": f"Bearer {settings.WHATSAPP_ADMIN_SYSTEM_USER_TOKEN}"} + response = requests.get(url, params=dict(limit=255), headers=headers) + + return response.json() + + +def get_actived_catalog(data: dict): + json_data = data.get("data", []) + if json_data and json_data[0].get("id"): + return json_data[0].get("id") diff --git a/temba/utils/whatsapp/interfaces.py b/temba/utils/whatsapp/interfaces.py new file mode 100644 index 00000000000..772e3c9ebcf --- /dev/null +++ b/temba/utils/whatsapp/interfaces.py @@ -0,0 +1,7 @@ +from abc import ABC, abstractmethod + + +class FacebookCatalog(ABC): + @abstractmethod + def get_facebook_catalogs(waba_id): + pass diff --git a/temba/utils/whatsapp/tasks.py b/temba/utils/whatsapp/tasks.py index 32902132783..804df5ca612 100644 --- a/temba/utils/whatsapp/tasks.py +++ b/temba/utils/whatsapp/tasks.py @@ -16,9 +16,11 @@ from temba.request_logs.models import HTTPLog from temba.templates.models import Template, TemplateButton, TemplateHeader, TemplateTranslation from temba.utils import chunk_list +from temba.utils.whatsapp.interfaces import FacebookCatalog from temba.wpp_products.models import Catalog, Product from . import update_api_version +from .clients import get_actived_catalog from .constants import LANGUAGE_MAPPING, STATUS_MAPPING logger = logging.getLogger(__name__) @@ -212,30 +214,24 @@ def set_false_is_active_catalog(channel, catalogs_data): for catalog in catalogs_data: catalog.is_active = False + catalog.save(update_fields=["is_active"]) return catalogs_data -def update_is_active_catalog(channel, catalogs_data): +def update_is_active_catalog(facebook_catalog: FacebookCatalog, channel: Channel, catalogs_data: list): waba_id = channel.config.get("wa_waba_id", None) if not waba_id: raise ValueError("Channel wa_waba_id not found") - url = f"https://graph.facebook.com/v17.0/{waba_id}/product_catalogs" + response = facebook_catalog.get_facebook_catalogs(waba_id) - headers = {"Authorization": f"Bearer {settings.WHATSAPP_ADMIN_SYSTEM_USER_TOKEN}"} - resp = requests.get(url, params=dict(limit=255), headers=headers) - - if "error" in resp.json(): + if "error" in response: set_false_is_active_catalog(channel, catalogs_data) - logger.error(f"Error refreshing WhatsApp catalog and products: {str(resp.json())}", exc_info=True) + logger.error(f"Error refreshing WhatsApp catalog and products: {str(response())}", exc_info=True) return catalogs_data - json_data = resp.json().get("data", []) - if json_data and json_data[0].get("id"): - actived_catalog = json_data[0]["id"] - else: - actived_catalog = None + actived_catalog = get_actived_catalog(response) if actived_catalog is None or len(actived_catalog) == 0: set_false_is_active_catalog(channel, catalogs_data) @@ -251,11 +247,12 @@ def update_is_active_catalog(channel, catalogs_data): else: catalog.is_active = True + catalog.save(update_fields=["is_active"]) return catalogs_data -def update_local_catalogs(channel, catalogs_data): +def update_local_catalogs(facebook_catalog: FacebookCatalog, channel: Channel, catalogs_data: list): seen = [] for catalog in catalogs_data: new_catalog = Catalog.get_or_create( @@ -267,7 +264,7 @@ def update_local_catalogs(channel, catalogs_data): seen.append(new_catalog) - update_is_active_catalog(channel, seen) + update_is_active_catalog(facebook_catalog, channel, seen) Catalog.trim(channel, seen) @@ -318,7 +315,7 @@ def refresh_whatsapp_catalog_and_products(): with r.lock("refresh_whatsapp_catalog_and_products", 1800): try: for channel in Channel.objects.filter(is_active=True, channel_type="WAC"): - for catalog in Catalog.objects.filter(channel=channel): + for catalog in Catalog.objects.filter(channel=channel, is_active=True): # Fetch products for each catalog products_data, valid = channel.get_type().get_api_products(channel, catalog) if not valid: diff --git a/temba/wpp_products/views.py b/temba/wpp_products/views.py index e84c77a4b72..fe703857713 100644 --- a/temba/wpp_products/views.py +++ b/temba/wpp_products/views.py @@ -5,6 +5,7 @@ from weni.internal.views import InternalGenericViewSet from temba.channels.models import Channel +from temba.utils.whatsapp.clients import RequestsFacebookCatalog from temba.utils.whatsapp.tasks import update_channel_catalogs_status, update_local_catalogs from temba.wpp_products.serializers import UpdateCatalogSerializer @@ -32,7 +33,9 @@ def update_catalog( **kwargs, ): channel = get_object_or_404(Channel, uuid=pk, is_active=True) + facebook_catalog = RequestsFacebookCatalog() if request.data: - update_local_catalogs(channel, request.data.get("data")) + update_local_catalogs(facebook_catalog, channel, request.data.get("data")) + return Response(status=status.HTTP_200_OK)