Skip to content

Commit

Permalink
update tasks call to receive user_token
Browse files Browse the repository at this point in the history
  • Loading branch information
lucaslinhares committed Jan 23, 2024
1 parent e5e9e43 commit f78aebc
Show file tree
Hide file tree
Showing 13 changed files with 153 additions and 86 deletions.
97 changes: 61 additions & 36 deletions marketplace/clients/facebook/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,16 @@ class FacebookAuthorization:
def __init__(self):
self.access_token = ACCESS_TOKEN

def _get_headers(self):
headers = {"Authorization": f"Bearer {self.access_token}"}
def _get_user_token(self, app):
if app.config.get("wa_user_token"):
return app.config.get("wa_user_token")
return None

def _get_headers(self, user_token):
if user_token:
headers = {"Authorization": f"Bearer {user_token}"}
else:
headers = {"Authorization": f"Bearer {self.access_token}"}
return headers

@property
Expand All @@ -26,38 +34,42 @@ def get_url(self):

class FacebookClient(FacebookAuthorization, RequestClient):
# Product Catalog
def create_catalog(self, business_id, name, category=None):
def create_catalog(self, app, business_id, name, category=None):
url = self.get_url + f"{business_id}/owned_product_catalogs"
data = {"name": name}
if category:
data["vertical"] = category

headers = self._get_headers()
user_token = self._get_user_token(app)
headers = self._get_headers(user_token)
response = self.make_request(url, method="POST", headers=headers, data=data)

return response.json()

def destroy_catalog(self, catalog_id):
def destroy_catalog(self, app, catalog_id):
url = self.get_url + f"{catalog_id}"

headers = self._get_headers()
user_token = self._get_user_token(app)
headers = self._get_headers(user_token)
response = self.make_request(url, method="DELETE", headers=headers)

return response.json().get("success")

def create_product_feed(self, product_catalog_id, name):
def create_product_feed(self, app, product_catalog_id, name):
url = self.get_url + f"{product_catalog_id}/product_feeds"

data = {"name": name}
headers = self._get_headers()
user_token = self._get_user_token(app)
headers = self._get_headers(user_token)
response = self.make_request(url, method="POST", headers=headers, data=data)

return response.json()

def upload_product_feed(self, feed_id, file):
def upload_product_feed(self, app, feed_id, file):
url = self.get_url + f"{feed_id}/uploads"

headers = self._get_headers()
user_token = self._get_user_token(app)
headers = self._get_headers(user_token)
files = {
"file": (
file.name,
Expand All @@ -69,19 +81,20 @@ def upload_product_feed(self, feed_id, file):
return response.json()

def create_product_feed_via_url(
self, product_catalog_id, name, feed_url, file_type, interval, hour
self, app, product_catalog_id, name, feed_url, file_type, interval, hour
): # TODO: adjust this method
url = self.get_url + f"{product_catalog_id}/product_feeds"

schedule = {"interval": interval, "url": feed_url, "hour": str(hour)}

data = {"name": name, "schedule": json.dumps(schedule), "file_type": file_type}

headers = self._get_headers()
user_token = self._get_user_token(app)
headers = self._get_headers(user_token)
response = self.make_request(url, method="POST", headers=headers, data=data)
return response.json()

def get_upload_status(self, feed_id, max_attempts=10, wait_time=30):
def get_upload_status(self, app, feed_id, max_attempts=10, wait_time=30):
"""
Checks the upload status using long polling.
Expand All @@ -94,7 +107,8 @@ def get_upload_status(self, feed_id, max_attempts=10, wait_time=30):
bool or str: True if 'end_time' is found, otherwise a formatted error message.
"""
url = self.get_url + f"{feed_id}/uploads"
headers = self._get_headers()
user_token = self._get_user_token(app)
headers = self._get_headers(user_token)

attempts = 0
while attempts < max_attempts:
Expand All @@ -113,17 +127,19 @@ def get_upload_status(self, feed_id, max_attempts=10, wait_time=30):
f"Waited for a total of {total_wait_time} seconds."
)

def list_products_by_feed(self, feed_id):
def list_products_by_feed(self, app, feed_id):
url = self.get_url + f"{feed_id}/products"

headers = self._get_headers()
user_token = self._get_user_token(app)
headers = self._get_headers(user_token)
response = self.make_request(url, method="GET", headers=headers)

return response.json()

def list_all_products_by_feed(self, feed_id):
def list_all_products_by_feed(self, app, feed_id):
url = self.get_url + f"{feed_id}/products"
headers = self._get_headers()
user_token = self._get_user_token(app)
headers = self._get_headers(user_token)
all_products = []

while url:
Expand All @@ -133,9 +149,10 @@ def list_all_products_by_feed(self, feed_id):

return all_products

def list_all_catalogs(self, wa_business_id):
def list_all_catalogs(self, app, wa_business_id):
url = self.get_url + f"{wa_business_id}/owned_product_catalogs"
headers = self._get_headers()
user_token = self._get_user_token(app)
headers = self._get_headers(user_token)
all_catalog_ids = []
all_catalogs = []

Expand All @@ -150,45 +167,51 @@ def list_all_catalogs(self, wa_business_id):

return all_catalog_ids, all_catalogs

def destroy_feed(self, feed_id):
def destroy_feed(self, app, feed_id):
url = self.get_url + f"{feed_id}"

headers = self._get_headers()
user_token = self._get_user_token(app)
headers = self._get_headers(user_token)
response = self.make_request(url, method="DELETE", headers=headers)

return response.json().get("success")

def get_connected_catalog(self, waba_id):
def get_connected_catalog(self, app, waba_id):
url = self.get_url + f"{waba_id}/product_catalogs"
headers = self._get_headers()
user_token = self._get_user_token(app)
headers = self._get_headers(user_token)
response = self.make_request(url, method="GET", headers=headers)
return response.json()

def enable_catalog(self, waba_id, catalog_id):
def enable_catalog(self, app, waba_id, catalog_id):
url = self.get_url + f"{waba_id}/product_catalogs"
data = {"catalog_id": catalog_id}
headers = self._get_headers()
user_token = self._get_user_token(app)
headers = self._get_headers(user_token)
response = self.make_request(url, method="POST", headers=headers, data=data)
return response.json()

def disable_catalog(self, waba_id, catalog_id):
def disable_catalog(self, app, waba_id, catalog_id):
url = self.get_url + f"{waba_id}/product_catalogs"
data = {"catalog_id": catalog_id, "method": "delete"}
headers = self._get_headers()
user_token = self._get_user_token(app)
headers = self._get_headers(user_token)
response = self.make_request(url, method="POST", headers=headers, data=data)
return response.json()

def get_catalog_details(self, catalog_id):
def get_catalog_details(self, app, catalog_id):
url = self.get_url + f"{catalog_id}"
params = {"fields": "name,vertical"}
headers = self._get_headers()
user_token = self._get_user_token(app)
headers = self._get_headers(user_token)
response = self.make_request(url, method="GET", headers=headers, params=params)

return response.json()

def _update_commerce_settings(self, wa_phone_number_id, **settings):
def _update_commerce_settings(self, app, wa_phone_number_id, **settings):
url = self.BASE_URL + f"{wa_phone_number_id}/whatsapp_commerce_settings"
headers = self._get_headers()
user_token = self._get_user_token(app)
headers = self._get_headers(user_token)
response = self.make_request(url, method="POST", headers=headers, data=settings)
return response.json()

Expand All @@ -202,7 +225,7 @@ def toggle_catalog_visibility(self, wa_phone_number_id, make_visible=True):
wa_phone_number_id, is_catalog_visible=make_visible
)

def get_wpp_commerce_settings(self, wa_phone_number_id):
def get_wpp_commerce_settings(self, app, wa_phone_number_id):
"""
Returns:
"data": [
Expand All @@ -217,13 +240,15 @@ def get_wpp_commerce_settings(self, wa_phone_number_id):
"""
url = self.BASE_URL + f"{wa_phone_number_id}/whatsapp_commerce_settings"

headers = self._get_headers()
user_token = self._get_user_token(app)
headers = self._get_headers(user_token)
response = self.make_request(url, method="GET", headers=headers)
return response.json()

# Whatsapp Templates
def get_template_analytics(self, waba_id, fields):
def get_template_analytics(self, app, waba_id, fields):
url = self.BASE_URL + f"{waba_id}/template_analytics"
headers = self._get_headers()
user_token = self._get_user_token(app)
headers = self._get_headers(user_token)
response = self.make_request(url, method="GET", headers=headers, params=fields)
return response.json()
16 changes: 10 additions & 6 deletions marketplace/core/types/channels/whatsapp/apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from requests.models import Response
from django.conf import settings

from marketplace.applications.models import App

from ..whatsapp_base.exceptions import FacebookApiException, UnableProcessProfilePhoto

WHATSAPP_VERSION = settings.WHATSAPP_VERSION
Expand Down Expand Up @@ -157,8 +159,10 @@ class FacebookWABAApi(BaseFacebookBaseApi):
def __init__(self, access_token: str) -> None:
self._access_token = access_token

@property
def _headers(self) -> dict:
def _headers(self, app) -> dict:
user_token = app.config.get("wa_user_token")
if user_token:
return {"Authorization": f"Bearer {user_token}"}
return {"Authorization": f"Bearer {self._access_token}"}

def get_waba(self, waba_id: str) -> dict:
Expand All @@ -174,15 +178,15 @@ class FacebookPhoneNumbersAPI(BaseFacebookBaseApi):
def _get_url(self, endpoint: str) -> str:
return f"{settings.WHATSAPP_API_URL}/{endpoint}"

def get_phone_numbers(self, waba_id: str) -> list:
def get_phone_numbers(self, app: App, waba_id: str) -> list:
url = self._get_url(f"{waba_id}/phone_numbers")
response = self._request(url, headers=self._headers)
response = self._request(url, headers=self._headers(app))

return response.json().get("data", [])

def get_phone_number(self, phone_number_id: str):
def get_phone_number(self, app: App, phone_number_id: str):
url = self._get_url(phone_number_id)
response = self._request(url, headers=self._headers)
response = self._request(url, headers=self._headers(app))

return response.json()

Expand Down
16 changes: 12 additions & 4 deletions marketplace/core/types/channels/whatsapp/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,11 @@ def sync_whatsapp_cloud_wabas():

logger.info(f"Syncing app WABA. UUID: {app.uuid}")

api = FacebookWABAApi(settings.WHATSAPP_SYSTEM_USER_ACCESS_TOKEN)
api = (
FacebookWABAApi(app.config.get("wa_user_token"))
if app.config.get("wa_user_token")
else FacebookWABAApi(settings.WHATSAPP_SYSTEM_USER_ACCESS_TOKEN)
)

try:
waba = api.get_waba(wa_waba_id)
Expand Down Expand Up @@ -268,7 +272,7 @@ def config_app_phone_number(app: App, phone_number: dict):
)
continue

phone_numbers = api.get_phone_numbers(business_id)
phone_numbers = api.get_phone_numbers(app, business_id)

for phone_number in phone_numbers:
display_phone_number = phone_number.get("display_phone_number")
Expand Down Expand Up @@ -312,8 +316,12 @@ def sync_whatsapp_cloud_phone_numbers():
continue

try:
api = FacebookPhoneNumbersAPI(
settings.WHATSAPP_SYSTEM_USER_ACCESS_TOKEN
api = (
FacebookPhoneNumbersAPI(app.config.get("wa_user_token"))
if app.config.get("wa_user_token")
else FacebookPhoneNumbersAPI(
settings.WHATSAPP_SYSTEM_USER_ACCESS_TOKEN
)
)
phone_number = api.get_phone_number(phone_number_id)

Expand Down
10 changes: 5 additions & 5 deletions marketplace/core/types/channels/whatsapp_cloud/facades.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ class CloudProfileFacade(object): # TODO: Interface
"Other": "OTHER",
}

def __init__(self, phone_number_id: "str") -> None:
self._profile_api = CloudProfileRequest(phone_number_id)
self._photo_api = PhotoAPIRequest(phone_number_id)
def __init__(self, app, phone_number_id: "str") -> None:
self._profile_api = CloudProfileRequest(app, phone_number_id)
self._photo_api = PhotoAPIRequest(app, phone_number_id)

def get_profile(self):
profile = self._profile_api.get_profile()
Expand Down Expand Up @@ -61,8 +61,8 @@ def delete_profile_photo(self):


class CloudProfileContactFacade(object): # TODO: Interface
def __init__(self, phone_number_id: "str") -> None:
self._profile_api = CloudProfileRequest(phone_number_id)
def __init__(self, app, phone_number_id: "str") -> None:
self._profile_api = CloudProfileRequest(app, phone_number_id)

def get_profile(self):
return self._profile_api.get_profile()
Expand Down
Loading

0 comments on commit f78aebc

Please sign in to comment.