from typing import Any from fastapi import APIRouter, Body, Depends, Path from pyxdi.ext.fastapi import Inject from starlette import status from campaigns.api import auth, query_params, schemas from campaigns.auth.dtos import User from campaigns.connectors.facebook.base import FacebookClient from campaigns.connectors.facebook.models import TargetingGeolocation, TargetingInterest from campaigns.meta import handlers from campaigns.meta.dtos import FacebookConnection from campaigns.meta.handlers import ( ConnectFacebookUserHandler, ConnectFacebookUserRequest, DisconnectFacebookUserHandler, DisconnectFacebookUserRequest, GetFacebookConnectionStatusHandler, GetFacebookConnectionStatusRequest, GetFacebookUserPageForLabelHandler, GetFacebookUserPageForLabelRequest, GetFacebookUserPagesForLabelHandler, GetFacebookUserPagesForLabelRequest, GetFacebookUserPagesHandler, GetInstagramAccountForFacebookPageHandler, GetInstagramAccountForFacebookPageRequest, ) from campaigns.meta.models import FacebookPage router = APIRouter(prefix="/facebook", tags=["facebook"]) @router.get( "/connection", operation_id="getFacebookConnectionStatus", response_model=schemas.FacebookConnection, response_model_by_alias=True, ) async def get_facebook_connection_status( identity_id: str = Depends(auth.get_identity_id), handler: GetFacebookConnectionStatusHandler = Inject(), ) -> FacebookConnection: return await handler.handle( GetFacebookConnectionStatusRequest(identity_id=identity_id) ) @router.post( "/connection", operation_id="connectFacebookUser", response_model=schemas.FacebookConnection, response_model_by_alias=True, ) async def connect_facebook_user( identity_id: str = Depends(auth.get_identity_id), profile_id: int = Depends(auth.get_profile_id), data: schemas.ConnectFacebookUserInput = Body(), handler: ConnectFacebookUserHandler = Inject(), ) -> FacebookConnection: return await handler.handle( ConnectFacebookUserRequest( identity_id=identity_id, profile_id=profile_id, user_id=data.user_id, access_token=data.access_token, ) ) @router.delete( "/connection", operation_id="disconnectFacebookUser", response_model=schemas.FacebookConnection, response_model_by_alias=True, ) async def disconnect_facebook_user( identity_id: str = Depends(auth.get_identity_id), handler: DisconnectFacebookUserHandler = Inject(), ) -> FacebookConnection: return await handler.handle(DisconnectFacebookUserRequest(identity_id=identity_id)) @router.get( "/connection/pages", operation_id="getFacebookUserPages", response_model=list[schemas.FacebookPage], response_model_by_alias=True, ) async def get_facebook_user_pages( user: User = Depends(auth.get_user), handler: GetFacebookUserPagesHandler = Inject(), ) -> list[FacebookPage]: return await handler.handle(handlers.GetFacebookUserPagesRequest(user=user)) @router.get( "/pages", operation_id="getFacebookUserPagesForLabel", description=( "Returns Facebook Pages shared with the given Label by the User or " "their colleagues" ), response_model=list[schemas.FacebookPage], response_model_by_alias=True, ) async def get_facebook_user_pages_for_label( user: User = Depends(auth.get_user), params: query_params.AccountQueryParams = Depends(), handler: GetFacebookUserPagesForLabelHandler = Inject(), ) -> list[FacebookPage]: return await handler.handle( GetFacebookUserPagesForLabelRequest(user=user, account=params.account) ) @router.get( "/pages/{pageId}", operation_id="getFacebookUserPageForLabel", response_model=schemas.FacebookPage, response_model_by_alias=True, responses={ status.HTTP_404_NOT_FOUND: {"model": schemas.Error}, }, ) async def get_facebook_user_page_for_label( user: User = Depends(auth.get_user), page_id: str = Path(alias="pageId"), params: query_params.AccountQueryParams = Depends(), handler: GetFacebookUserPageForLabelHandler = Inject(), ) -> FacebookPage: return await handler.handle( GetFacebookUserPageForLabelRequest( user=user, page_id=page_id, account=params.account ) ) @router.get( "/pages/{pageId}/instagram/account", operation_id="getInstagramAccountForFacebookPage", response_model=schemas.InstagramAccountResponse, response_model_by_alias=True, responses={ status.HTTP_404_NOT_FOUND: {"model": schemas.Error}, }, ) async def get_instagram_account_for_facebook_page( user: User = Depends(auth.get_user), page_id: str = Path(alias="pageId"), params: query_params.AccountQueryParams = Depends(), handler: GetInstagramAccountForFacebookPageHandler = Inject(), ) -> dict[str, Any]: instagram_account = await handler.handle( GetInstagramAccountForFacebookPageRequest( user=user, page_id=page_id, account=params.account ), ) return {"instagramAccount": instagram_account} @router.get( "/geolocations", operation_id="getFacebookTargetingGeolocations", response_model=list[schemas.FacebookTargetingGeolocation], response_model_by_alias=True, ) async def get_facebook_geolocations( params: query_params.FacebookTargetingGeolocationQueryParams = Depends(), facebook_client: FacebookClient = Inject(), ) -> list[TargetingGeolocation]: return await facebook_client.get_targeting_geolocations( query=params.search, limit=params.limit ) @router.get( "/interests", operation_id="getFacebookTargetingInterests", response_model=list[schemas.FacebookTargetingInterest], response_model_by_alias=True, ) async def get_facebook_interests( params: query_params.FacebookTargetingInterestQueryParams = Depends(), facebook_client: FacebookClient = Inject(), ) -> list[TargetingInterest]: return await facebook_client.get_targeting_interests( query=params.search, limit=params.limit )