from dataclasses import dataclass from campaigns.auth.dtos import User from campaigns.campaigns.enums import CampaignStatus from campaigns.connectors.db import Database, session_context from campaigns.connectors.facebook.base import FacebookClient from campaigns.core.handler import Handler from campaigns.meta.enums import CampaignObjective from campaigns.meta.models import Campaign from campaigns.meta.repositories import CampaignRepository from campaigns.meta.validators import CampaignValidator @dataclass(frozen=True) class CreateCampaignRequest: user: User name: str vendor_id: int subaccount_id: int global_participant_id: str product_id: int | None objective: CampaignObjective facebook_page_id: str @dataclass class CreateCampaignHandler( Handler[CreateCampaignRequest, Campaign], ): db: Database facebook_client: FacebookClient campaign_validator: CampaignValidator campaign_repository: CampaignRepository @session_context(in_transaction=True) async def handle(self, request: CreateCampaignRequest) -> Campaign: campaign = Campaign() campaign.name = request.name campaign.vendor_id = request.vendor_id campaign.subaccount_id = request.subaccount_id campaign.global_participant_id = request.global_participant_id campaign.product_id = request.product_id campaign.facebook_page_id = request.facebook_page_id campaign.objective = request.objective campaign.status = CampaignStatus.DRAFT campaign.created_by = request.user.id.identity_id campaign.updated_by = request.user.id.identity_id campaign.images = [] campaign.videos = [] await self.campaign_validator.validate_account(campaign, user=request.user) product = await self.campaign_validator.validate_product_id( campaign, user=request.user ) campaign.product_upc = product.upc if product else None facebook_page = await self.campaign_validator.validate_facebook_page_id( campaign, user=request.user ) instagram_account = ( await self.facebook_client.get_instagram_business_account_for_page( page_id=facebook_page.external_id, page_access_token=facebook_page.plain_token, ) ) if instagram_account: campaign.instagram_account_external_id = instagram_account.id else: campaign.instagram_account_external_id = None instagram_user = await self.facebook_client.get_instagram_user_for_page( page_id=facebook_page.external_id, page_access_token=facebook_page.plain_token, ) if instagram_user: campaign.instagram_user_external_id = instagram_user.id else: campaign.instagram_user_external_id = None self.campaign_repository.add(campaign) return campaign