From 03620e3d4e83379552563ff085dde42e8984122a Mon Sep 17 00:00:00 2001 From: elitonzky Date: Fri, 30 Jun 2023 16:54:11 -0300 Subject: [PATCH] feature: migrate endpoints from connect client to flows client --- marketplace/accounts/views.py | 4 +- marketplace/connect/client.py | 147 ------------------ marketplace/core/tests/test_validators.py | 4 +- .../types/channels/facebook/serializers.py | 4 +- .../channels/facebook/tests/test_views.py | 2 +- .../types/channels/generic/serializers.py | 4 +- .../types/channels/generic/tests/test_view.py | 2 +- .../types/channels/instagram/serializers.py | 4 +- .../channels/instagram/tests/test_views.py | 2 +- .../types/channels/telegram/serializers.py | 4 +- .../channels/telegram/tests/test_views.py | 2 +- .../channels/weni_web_chat/serializers.py | 4 +- .../weni_web_chat/tests/test_views.py | 4 +- .../core/types/channels/whatsapp/tasks.py | 5 +- .../channels/whatsapp/tests/test_tasks.py | 10 +- .../types/channels/whatsapp_cloud/tasks.py | 6 +- .../whatsapp_cloud/tests/test_tasks.py | 6 +- .../types/channels/whatsapp_cloud/views.py | 3 +- .../whatsapp_demo/tests/test_views.py | 12 +- .../types/channels/whatsapp_demo/views.py | 6 +- marketplace/core/types/views.py | 7 +- marketplace/core/validators.py | 6 +- marketplace/flows/client.py | 98 ++++++++++++ 23 files changed, 148 insertions(+), 198 deletions(-) delete mode 100644 marketplace/connect/client.py diff --git a/marketplace/accounts/views.py b/marketplace/accounts/views.py index 0cd034df..0d7be9f4 100644 --- a/marketplace/accounts/views.py +++ b/marketplace/accounts/views.py @@ -10,7 +10,7 @@ ProjectAuthorizationSerializer, UserPermissionSerializer, ) -from marketplace.connect.client import ConnectProjectClient +from marketplace.flows.client import FlowsClient from .models import ProjectAuthorization @@ -90,7 +90,7 @@ def get(self, request: "Request") -> Response: dict(detail="The project-uuid needs to be sent in headers!") ) - client = ConnectProjectClient() + client = FlowsClient() response = client.get_user_api_token(request.user.email, project_uuid) return Response(response.json(), status=response.status_code) diff --git a/marketplace/connect/client.py b/marketplace/connect/client.py deleted file mode 100644 index a702b452..00000000 --- a/marketplace/connect/client.py +++ /dev/null @@ -1,147 +0,0 @@ -import requests - -from django.conf import settings - -from rest_framework.exceptions import ValidationError - - -class ConnectAuth: - def __get_auth_token(self) -> str: - request = requests.post( - url=settings.OIDC_OP_TOKEN_ENDPOINT, - data={ - "client_id": settings.OIDC_RP_CLIENT_ID, - "client_secret": settings.OIDC_RP_CLIENT_SECRET, - "grant_type": "client_credentials", - }, - ) - token = request.json().get("access_token") - return f"Bearer {token}" - - def auth_header(self) -> dict: - return {"Authorization": self.__get_auth_token()} - - -class ConnectProjectClient(ConnectAuth): # TODO: change class name to FlowsRESTClient - base_url = settings.FLOWS_REST_ENDPOINT - use_connect_v2 = settings.USE_CONNECT_V2 - - def _get_url(self, endpoint: str) -> str: - assert endpoint.startswith("/"), "the endpoint needs to start with: /" - return self.base_url + endpoint - - def list_channels(self, channeltype_code: str) -> list: - params = {"channel_type": channeltype_code} - - url = self._get_url("/api/v2/internals/channel/") - - response = requests.get( - url=url, params=params, headers=self.auth_header(), timeout=60 - ) - - def map_org_to_project_uuid(channel: dict) -> dict: - channel["project_uuid"] = channel.pop("org") - return channel - - return list(map(map_org_to_project_uuid, response.json())) - - def create_channel( - self, user: str, project_uuid: str, data: dict, channeltype_code: str - ) -> dict: - payload = { - "user": user, - "org": str(project_uuid), - "data": data, - "channeltype_code": channeltype_code, - } - - url = self._get_url("/api/v2/internals/channel/") - - response = requests.post( - url=url, json=payload, headers=self.auth_header(), timeout=60 - ) - - if response.status_code not in [200, 201]: - raise ValidationError(f"{response.status_code}: {response.text}") - - return response.json() - - def create_wac_channel( - self, user: str, project_uuid: str, phone_number_id: str, config: dict - ) -> dict: - payload = { - "user": user, - "org": str(project_uuid), - "config": config, - "phone_number_id": phone_number_id, - } - url = self._get_url("/api/v2/internals/channel/create_wac/") - - response = requests.post( - url=url, json=payload, headers=self.auth_header(), timeout=60 - ) - return response.json() - - def release_channel( - self, channel_uuid: str, project_uuid: str, user_email: str - ) -> None: - params = {"user": user_email} - url = self._get_url(f"/api/v2/internals/channel/{channel_uuid}") - requests.delete(url=url, params=params, headers=self.auth_header(), timeout=60) - - return None - - def get_user_api_token(self, user: str, project_uuid: str): - params = dict(user=user, project=str(project_uuid)) - url = self._get_url("/api/v2/internals/users/api-token/") - response = requests.get( - url=url, params=params, headers=self.auth_header(), timeout=60 - ) - return response - - def list_availables_channels(self): - url = self.base_url + "/v1/channel-types" - response = requests.get(url=url, headers=self.auth_header(), timeout=60) - return response - - def detail_channel_type(self, channel_code: str): - params = {"channel_type_code": channel_code} - url = self.base_url + "/v1/channel-types" - response = requests.get( - url=url, params=params, headers=self.auth_header(), timeout=60 - ) - return response - - def create_external_service( - self, user: str, project_uuid: str, type_fields: dict, type_code: str - ): - url = settings.CONNECT_ENGINE_BASE_URL + "/v1/externals" - payload = { - "user": user, - "project": str(project_uuid), - "type_fields": type_fields, - "type_code": type_code, - } - response = requests.post(url, json=payload, headers=self.auth_header()) - return response - - def release_external_service(self, uuid: str, user_email: str): - url = self._get_url("/v1/externals") - params = {"uuid": str(uuid), "user": user_email} - - response = requests.delete(url=url, params=params, headers=self.auth_header()) - return response - - -class WPPRouterChannelClient(ConnectAuth): - base_url = settings.ROUTER_BASE_URL - - def get_channel_token(self, uuid: str, name: str) -> str: - payload = {"uuid": uuid, "name": name} - response = requests.post( - url=self.base_url + "/integrations/channel", - json=payload, - headers=self.auth_header(), - timeout=60, - ) - return response.json().get("token", "") diff --git a/marketplace/core/tests/test_validators.py b/marketplace/core/tests/test_validators.py index b4bc0c96..8b3f999c 100644 --- a/marketplace/core/tests/test_validators.py +++ b/marketplace/core/tests/test_validators.py @@ -9,7 +9,7 @@ class ValidateAppCodeExistsTestCase(TestCase): - @patch("marketplace.connect.client.ConnectProjectClient.detail_channel_type") + @patch("marketplace.flows.client.FlowsClient.list_channel_types") def test_invalid_app_code(self, mock_list_detail_channel_type): response_data = None mock_response = Mock() @@ -27,7 +27,7 @@ def test_valid_app_code(self): value = "wwc" validate_app_code_exists(value) - @patch("marketplace.connect.client.ConnectProjectClient.detail_channel_type") + @patch("marketplace.flows.client.FlowsClient.list_channel_types") def test_valid_generic_app_code(self, mock_list_detail_channel_type): response_data = { "attributes": { diff --git a/marketplace/core/types/channels/facebook/serializers.py b/marketplace/core/types/channels/facebook/serializers.py index 8e19fae0..6fc4aa2a 100644 --- a/marketplace/core/types/channels/facebook/serializers.py +++ b/marketplace/core/types/channels/facebook/serializers.py @@ -2,7 +2,7 @@ from marketplace.core.serializers import AppTypeBaseSerializer from marketplace.applications.models import App -from marketplace.connect.client import ConnectProjectClient +from marketplace.flows.client import FlowsClient class FacebookSerializer(AppTypeBaseSerializer): @@ -48,7 +48,7 @@ def validate(self, attrs: dict): def _create_channel(self, attrs: dict, app: App) -> str: user = self.context.get("request").user - client = ConnectProjectClient() + client = FlowsClient() payload = { "user_access_token": attrs.get("user_access_token"), diff --git a/marketplace/core/types/channels/facebook/tests/test_views.py b/marketplace/core/types/channels/facebook/tests/test_views.py index d216058c..6c84f55f 100644 --- a/marketplace/core/types/channels/facebook/tests/test_views.py +++ b/marketplace/core/types/channels/facebook/tests/test_views.py @@ -149,7 +149,7 @@ def view(self): return self.view_class.as_view({"patch": "configure"}) @patch( - "marketplace.core.types.channels.facebook.serializers.ConnectProjectClient.create_channel" + "marketplace.core.types.channels.facebook.serializers.FlowsClient.create_channel" ) def test_configure_facebook_success(self, mock_create_external_service): data = { diff --git a/marketplace/core/types/channels/generic/serializers.py b/marketplace/core/types/channels/generic/serializers.py index 27c66454..a00b399f 100644 --- a/marketplace/core/types/channels/generic/serializers.py +++ b/marketplace/core/types/channels/generic/serializers.py @@ -2,7 +2,7 @@ from marketplace.applications.models import App from marketplace.core.serializers import AppTypeBaseSerializer -from marketplace.connect.client import ConnectProjectClient +from marketplace.flows.client import FlowsClient class GenericChannelSerializer(AppTypeBaseSerializer): @@ -49,7 +49,7 @@ def _create_channel(self, attrs: dict, app: App) -> str: request = self.context.get("request") user = request.user channeltype_code = app.config.get("channel_code") - client = ConnectProjectClient() + client = FlowsClient() return client.create_channel( user.email, app.project_uuid, attrs, channeltype_code.upper() ) diff --git a/marketplace/core/types/channels/generic/tests/test_view.py b/marketplace/core/types/channels/generic/tests/test_view.py index 9ee89189..1dd11e80 100644 --- a/marketplace/core/types/channels/generic/tests/test_view.py +++ b/marketplace/core/types/channels/generic/tests/test_view.py @@ -206,7 +206,7 @@ def view(self): return self.view_class.as_view({"patch": "configure"}) @patch( - "marketplace.core.types.channels.generic.serializers.ConnectProjectClient.create_channel" + "marketplace.core.types.channels.generic.serializers.FlowsClient.create_channel" ) def test_configure_channel_success(self, mock_configure): mock_configure.return_value = {"channelUuid": str(uuid.uuid4())} diff --git a/marketplace/core/types/channels/instagram/serializers.py b/marketplace/core/types/channels/instagram/serializers.py index 0e2f7f03..5bd5cfba 100644 --- a/marketplace/core/types/channels/instagram/serializers.py +++ b/marketplace/core/types/channels/instagram/serializers.py @@ -2,7 +2,7 @@ from marketplace.core.serializers import AppTypeBaseSerializer from marketplace.applications.models import App -from marketplace.connect.client import ConnectProjectClient +from marketplace.flows.client import FlowsClient class InstagramSerializer(AppTypeBaseSerializer): @@ -49,7 +49,7 @@ def validate(self, attrs: dict): def _create_channel(self, attrs: dict, app: App) -> str: user = self.context.get("request").user - client = ConnectProjectClient() + client = FlowsClient() payload = { "user_access_token": attrs.get("user_access_token"), diff --git a/marketplace/core/types/channels/instagram/tests/test_views.py b/marketplace/core/types/channels/instagram/tests/test_views.py index 50af6a97..a20f8544 100644 --- a/marketplace/core/types/channels/instagram/tests/test_views.py +++ b/marketplace/core/types/channels/instagram/tests/test_views.py @@ -149,7 +149,7 @@ def view(self): return self.view_class.as_view({"patch": "configure"}) @patch( - "marketplace.core.types.channels.instagram.serializers.ConnectProjectClient.create_channel" + "marketplace.core.types.channels.instagram.serializers.FlowsClient.create_channel" ) def test_configure_instagram_success(self, mock_create_external_service): data = { diff --git a/marketplace/core/types/channels/telegram/serializers.py b/marketplace/core/types/channels/telegram/serializers.py index cfedc0b3..4bed7148 100644 --- a/marketplace/core/types/channels/telegram/serializers.py +++ b/marketplace/core/types/channels/telegram/serializers.py @@ -2,7 +2,7 @@ from marketplace.core.serializers import AppTypeBaseSerializer from marketplace.applications.models import App -from marketplace.connect.client import ConnectProjectClient +from marketplace.flows.client import FlowsClient class TelegramSerializer(AppTypeBaseSerializer): @@ -42,7 +42,7 @@ def validate(self, attrs: dict): def _create_channel(self, attrs: dict, app: App) -> str: user = self.context.get("request").user - client = ConnectProjectClient() + client = FlowsClient() return client.create_channel( user.email, app.project_uuid, diff --git a/marketplace/core/types/channels/telegram/tests/test_views.py b/marketplace/core/types/channels/telegram/tests/test_views.py index c033a9c7..bf18f0cc 100644 --- a/marketplace/core/types/channels/telegram/tests/test_views.py +++ b/marketplace/core/types/channels/telegram/tests/test_views.py @@ -149,7 +149,7 @@ def view(self): return self.view_class.as_view({"patch": "configure"}) @patch( - "marketplace.core.types.channels.telegram.serializers.ConnectProjectClient.create_channel" + "marketplace.core.types.channels.telegram.serializers.FlowsClient.create_channel" ) def test_configure_telegram_success(self, mock_create_external_service): data = { diff --git a/marketplace/core/types/channels/weni_web_chat/serializers.py b/marketplace/core/types/channels/weni_web_chat/serializers.py index f604e839..bfd84216 100644 --- a/marketplace/core/types/channels/weni_web_chat/serializers.py +++ b/marketplace/core/types/channels/weni_web_chat/serializers.py @@ -10,7 +10,7 @@ from marketplace.core.storage import AppStorage from . import type as type_ -from marketplace.connect.client import ConnectProjectClient +from marketplace.flows.client import FlowsClient class WeniWebChatSerializer(AppTypeBaseSerializer): @@ -117,7 +117,7 @@ def _create_channel(self) -> str: name = f"{type_.WeniWebChatType.name} - #{self.app.id}" data = {"name": name, "base_url": settings.SOCKET_BASE_URL} - client = ConnectProjectClient() + client = FlowsClient() return client.create_channel( user.email, self.app.project_uuid, data, self.app.flows_type_code ) diff --git a/marketplace/core/types/channels/weni_web_chat/tests/test_views.py b/marketplace/core/types/channels/weni_web_chat/tests/test_views.py index 7c2d0a22..dc9857fd 100644 --- a/marketplace/core/types/channels/weni_web_chat/tests/test_views.py +++ b/marketplace/core/types/channels/weni_web_chat/tests/test_views.py @@ -168,9 +168,7 @@ def setUp(self): def view(self): return self.view_class.as_view({"patch": "configure"}) - @patch( - "marketplace.core.types.channels.weni_web_chat.serializers.ConnectProjectClient" - ) + @patch("marketplace.core.types.channels.weni_web_chat.serializers.FlowsClient") @patch( "marketplace.core.types.channels.weni_web_chat.serializers.AppStorage", MockAppStorage, diff --git a/marketplace/core/types/channels/whatsapp/tasks.py b/marketplace/core/types/channels/whatsapp/tasks.py index 6df19713..42fbe51a 100644 --- a/marketplace/core/types/channels/whatsapp/tasks.py +++ b/marketplace/core/types/channels/whatsapp/tasks.py @@ -9,7 +9,8 @@ from marketplace.celery import app as celery_app from marketplace.core.types import APPTYPES from marketplace.applications.models import App -from marketplace.connect.client import ConnectProjectClient +from marketplace.flows.client import FlowsClient + from .apis import FacebookWABAApi, FacebookPhoneNumbersAPI from ..whatsapp_base.exceptions import FacebookApiException @@ -26,7 +27,7 @@ @celery_app.task(name="sync_whatsapp_apps") def sync_whatsapp_apps(): apptype = APPTYPES.get("wpp") - client = ConnectProjectClient() + client = FlowsClient() channels = client.list_channels(apptype.flows_type_code) redis = get_redis_connection() diff --git a/marketplace/core/types/channels/whatsapp/tests/test_tasks.py b/marketplace/core/types/channels/whatsapp/tests/test_tasks.py index 7f1edb04..ef13f280 100644 --- a/marketplace/core/types/channels/whatsapp/tests/test_tasks.py +++ b/marketplace/core/types/channels/whatsapp/tests/test_tasks.py @@ -72,7 +72,7 @@ def _get_mock_value( ] @patch("marketplace.core.types.channels.whatsapp.tasks.get_redis_connection") - @patch("marketplace.connect.client.ConnectProjectClient.list_channels") + @patch("marketplace.flows.client.FlowsClient.list_channels") def test_create_new_whatsapp_app( self, list_channel_mock: "MagicMock", mock_redis ) -> None: @@ -91,7 +91,7 @@ def test_create_new_whatsapp_app( self.assertTrue(App.objects.filter(project_uuid=project_uuid).exists()) @patch("marketplace.core.types.channels.whatsapp.tasks.get_redis_connection") - @patch("marketplace.connect.client.ConnectProjectClient.list_channels") + @patch("marketplace.flows.client.FlowsClient.list_channels") def test_update_app_auth_token( self, list_channel_mock: "MagicMock", mock_redis ) -> None: @@ -108,7 +108,7 @@ def test_update_app_auth_token( self.assertEqual(app.config.get("auth_token"), "54321") @patch("marketplace.core.types.channels.whatsapp.tasks.get_redis_connection") - @patch("marketplace.connect.client.ConnectProjectClient.list_channels") + @patch("marketplace.flows.client.FlowsClient.list_channels") def test_channel_migration_from_wpp_cloud_to_wpp( self, list_channel_mock: "MagicMock", mock_redis ) -> None: @@ -119,7 +119,7 @@ def test_channel_migration_from_wpp_cloud_to_wpp( sync_whatsapp_apps() @patch("marketplace.core.types.channels.whatsapp.tasks.get_redis_connection") - @patch("marketplace.connect.client.ConnectProjectClient.list_channels") + @patch("marketplace.flows.client.FlowsClient.list_channels") def test_task_that_was_executed( self, list_channel_mock: "MagicMock", mock_redis ) -> None: @@ -130,7 +130,7 @@ def test_task_that_was_executed( sync_whatsapp_apps() @patch("marketplace.core.types.channels.whatsapp.tasks.get_redis_connection") - @patch("marketplace.connect.client.ConnectProjectClient.list_channels") + @patch("marketplace.flows.client.FlowsClient.list_channels") def test_skipping_wpp_demo( self, list_channel_mock: "MagicMock", mock_redis ) -> None: diff --git a/marketplace/core/types/channels/whatsapp_cloud/tasks.py b/marketplace/core/types/channels/whatsapp_cloud/tasks.py index 3bce9e39..862e48b5 100644 --- a/marketplace/core/types/channels/whatsapp_cloud/tasks.py +++ b/marketplace/core/types/channels/whatsapp_cloud/tasks.py @@ -5,7 +5,7 @@ from marketplace.core.types import APPTYPES from marketplace.celery import app as celery_app -from marketplace.connect.client import ConnectProjectClient +from marketplace.flows.client import FlowsClient from marketplace.applications.models import App from marketplace.accounts.models import ProjectAuthorization @@ -21,7 +21,7 @@ @celery_app.task(name="sync_whatsapp_cloud_apps") def sync_whatsapp_cloud_apps(): apptype = APPTYPES.get("wpp-cloud") - client = ConnectProjectClient() + client = FlowsClient() channels = client.list_channels(apptype.flows_type_code) redis = get_redis_connection() @@ -89,7 +89,7 @@ def check_apps_uncreated_on_flow(): wa_phone_number_id = app.config.get("wa_phone_number_id") try: - client = ConnectProjectClient() + client = FlowsClient() channel = client.create_wac_channel( user_creation.email, project_uuid, wa_phone_number_id, app_config ) diff --git a/marketplace/core/types/channels/whatsapp_cloud/tests/test_tasks.py b/marketplace/core/types/channels/whatsapp_cloud/tests/test_tasks.py index 0fd09874..e22bb0bf 100644 --- a/marketplace/core/types/channels/whatsapp_cloud/tests/test_tasks.py +++ b/marketplace/core/types/channels/whatsapp_cloud/tests/test_tasks.py @@ -55,7 +55,7 @@ def _get_mock_value(self, project_uuid: str, flow_object_uuid: str) -> list: ] @patch("marketplace.core.types.channels.whatsapp_cloud.tasks.get_redis_connection") - @patch("marketplace.connect.client.ConnectProjectClient.list_channels") + @patch("marketplace.flows.client.FlowsClient.list_channels") def test_whatsapp_app_that_already_exists_is_migrated_correctly( self, list_channel_mock: "MagicMock", mock_redis ) -> None: @@ -73,7 +73,7 @@ def test_whatsapp_app_that_already_exists_is_migrated_correctly( self.assertIn("have_to_stay", app.config.get("config_before_migration")) @patch("marketplace.core.types.channels.whatsapp_cloud.tasks.get_redis_connection") - @patch("marketplace.connect.client.ConnectProjectClient.list_channels") + @patch("marketplace.flows.client.FlowsClient.list_channels") def test_sync_for_non_migrated_channels( self, list_channel_mock: "MagicMock", mock_redis ) -> None: @@ -91,7 +91,7 @@ def test_sync_for_non_migrated_channels( self.assertIn("have_to_stay", app.config) @patch("marketplace.core.types.channels.whatsapp_cloud.tasks.get_redis_connection") - @patch("marketplace.connect.client.ConnectProjectClient.list_channels") + @patch("marketplace.flows.client.FlowsClient.list_channels") def test_create_new_whatsapp_cloud( self, list_channel_mock: "MagicMock", mock_redis ) -> None: diff --git a/marketplace/core/types/channels/whatsapp_cloud/views.py b/marketplace/core/types/channels/whatsapp_cloud/views.py index 100a74de..dd8c27c5 100644 --- a/marketplace/core/types/channels/whatsapp_cloud/views.py +++ b/marketplace/core/types/channels/whatsapp_cloud/views.py @@ -17,7 +17,6 @@ from marketplace.core.types import views from marketplace.applications.models import App from marketplace.celery import app as celery_app -from marketplace.connect.client import ConnectProjectClient from marketplace.flows.client import FlowsClient from ..whatsapp_base import mixins @@ -141,7 +140,7 @@ def create(self, request, *args, **kwargs): wa_pin=pin, ) - client = ConnectProjectClient() + client = FlowsClient() channel = client.create_wac_channel( request.user.email, project_uuid, phone_number_id, config ) diff --git a/marketplace/core/types/channels/whatsapp_demo/tests/test_views.py b/marketplace/core/types/channels/whatsapp_demo/tests/test_views.py index 72422bb5..6bd67296 100644 --- a/marketplace/core/types/channels/whatsapp_demo/tests/test_views.py +++ b/marketplace/core/types/channels/whatsapp_demo/tests/test_views.py @@ -36,8 +36,8 @@ def view(self): return self.view_class.as_view(APIBaseTestCase.ACTION_CREATE) # @patch("marketplace.celery.app.send_task") - @patch("marketplace.connect.client.WPPRouterChannelClient.get_channel_token") - @patch("marketplace.connect.client.ConnectProjectClient.create_channel") + @patch("marketplace.flows.client.WPPRouterChannelClient.get_channel_token") + @patch("marketplace.flows.client.FlowsClient.create_channel") def test_request_ok(self, create_channel_request, get_channel_token_request): self.view_class.type_class.NUMBER = "+559999998888" channel_uuid = str(uuid.uuid4()) @@ -73,8 +73,8 @@ def test_create_app_without_project_uuid(self): self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - @patch("marketplace.connect.client.WPPRouterChannelClient.get_channel_token") - @patch("marketplace.connect.client.ConnectProjectClient.create_channel") + @patch("marketplace.flows.client.WPPRouterChannelClient.get_channel_token") + @patch("marketplace.flows.client.FlowsClient.create_channel") def test_create_app_platform( self, create_channel_request, get_channel_token_request ): @@ -92,8 +92,8 @@ def test_create_app_platform( response = self.request.post(self.url, self.body) self.assertEqual(response.json["platform"], App.PLATFORM_WENI_FLOWS) - @patch("marketplace.connect.client.WPPRouterChannelClient.get_channel_token") - @patch("marketplace.connect.client.ConnectProjectClient.create_channel") + @patch("marketplace.flows.client.WPPRouterChannelClient.get_channel_token") + @patch("marketplace.flows.client.FlowsClient.create_channel") def test_get_app_with_respective_project_uuid( self, create_channel_request, get_channel_token_request ): diff --git a/marketplace/core/types/channels/whatsapp_demo/views.py b/marketplace/core/types/channels/whatsapp_demo/views.py index 85c2b8a9..f93de9dc 100644 --- a/marketplace/core/types/channels/whatsapp_demo/views.py +++ b/marketplace/core/types/channels/whatsapp_demo/views.py @@ -1,6 +1,8 @@ from marketplace.core.types import views from .serializers import WhatsAppDemoSerializer -from marketplace.connect.client import ConnectProjectClient, WPPRouterChannelClient + +from marketplace.flows.client import FlowsClient +from marketplace.flows.client import WPPRouterChannelClient class WhatsAppDemoViewSet(views.BaseAppTypeViewSet): @@ -26,7 +28,7 @@ def perform_create(self, serializer): facebook_access_token="null", ) - client = ConnectProjectClient() + client = FlowsClient() result = client.create_channel( user.email, str(instance.project_uuid), data, instance.flows_type_code ) diff --git a/marketplace/core/types/views.py b/marketplace/core/types/views.py index ff6a2ce7..3500e720 100644 --- a/marketplace/core/types/views.py +++ b/marketplace/core/types/views.py @@ -11,7 +11,7 @@ from marketplace.applications.models import App from marketplace.accounts.permissions import ProjectManagePermission -from marketplace.connect.client import ConnectProjectClient +from marketplace.flows.client import FlowsClient class BaseAppTypeViewSet( @@ -39,8 +39,7 @@ def create(self, request, *args, **kwargs): def perform_destroy(self, instance): super().perform_destroy(instance) - project_uuid = str(instance.project_uuid) channel_uuid = instance.config.get("channelUuid") if channel_uuid: - client = ConnectProjectClient() - client.release_channel(channel_uuid, project_uuid, self.request.user.email) + client = FlowsClient() + client.release_channel(channel_uuid, self.request.user.email) diff --git a/marketplace/core/validators.py b/marketplace/core/validators.py index c1cd919b..814ed011 100644 --- a/marketplace/core/validators.py +++ b/marketplace/core/validators.py @@ -16,10 +16,10 @@ def validate_generic_app_code_exists(code): Checks if the code exists within the generic channels coming from rapidpro, if it exists, it returns True. """ - from marketplace.connect.client import ConnectProjectClient + from marketplace.flows.client import FlowsClient - client = ConnectProjectClient() - response = client.detail_channel_type(channel_code=code) + client = FlowsClient() + response = client.list_channel_types(channel_code=code) if response.status_code == 200: return True diff --git a/marketplace/flows/client.py b/marketplace/flows/client.py index 8277da13..9259b0fd 100644 --- a/marketplace/flows/client.py +++ b/marketplace/flows/client.py @@ -153,6 +153,89 @@ def get_sent_messagers( ) return response + def list_channels(self, channeltype_code: str) -> list: + params = {"channel_type": channeltype_code} + + url = f"{self.base_url}/api/v2/internals/channel/" + + response = self.make_request( + url, + method="GET", + headers=self.authentication_instance.headers, + params=params, + ) + + def map_org_to_project_uuid(channel: dict) -> dict: + channel["project_uuid"] = channel.pop("org") + return channel + + return list(map(map_org_to_project_uuid, response.json())) + + def create_channel( + self, user: str, project_uuid: str, data: dict, channeltype_code: str + ) -> dict: + payload = { + "user": user, + "org": str(project_uuid), + "data": data, + "channeltype_code": channeltype_code, + } + + url = f"{self.base_url}/api/v2/internals/channel/" + + response = self.make_request( + url, + method="POST", + headers=self.authentication_instance.headers, + data=payload, + ) + + return response.json() + + def create_wac_channel( + self, user: str, project_uuid: str, phone_number_id: str, config: dict + ) -> dict: + payload = { + "user": user, + "org": str(project_uuid), + "config": config, + "phone_number_id": phone_number_id, + } + url = f"{self.base_url}/api/v2/internals/channel/create_wac/" + + response = self.make_request( + url=url, + method="POST", + headers=self.authentication_instance.headers, + data=payload, + ) + return response.json() + + def release_channel(self, channel_uuid: str, user_email: str) -> None: + params = {"user": user_email} + url = f"{self.base_url}/api/v2/internals/channel/{channel_uuid}" + + self.make_request( + url, + method="DELETE", + headers=self.authentication_instance.headers, + params=params, + ) + return None + + def get_user_api_token(self, user: str, project_uuid: str): + params = dict(user=user, project=str(project_uuid)) + url = f"{self.base_url}/api/v2/internals/users/api-token/" + + response = self.make_request( + url, + method="GET", + headers=self.authentication_instance.headers, + params=params, + ) + + return response + def make_request(self, url: str, method: str, headers=None, data=None, params=None): response = requests.request( method=method, @@ -214,3 +297,18 @@ class CustomAPIException(APIException): def __init__(self, detail=None, code=None, status_code=None): super().__init__(detail, code) self.status_code = status_code or self.status_code + + +class WPPRouterChannelClient(FlowsClient): + base_url = settings.ROUTER_BASE_URL + + def get_channel_token(self, uuid: str, name: str) -> str: + payload = {"uuid": uuid, "name": name} + url = f"{self.base_url}/integrations/channel" + response = self.make_request( + url, + method="POST", + headers=self.authentication_instance.headers, + data=payload, + ) + return response.json().get("token", "")