0

I can duplicate an ad and post it. But when I try to use a new video creative ID. It says the parameter is invalid. The video is in fact uploaded. I can also switch it out manually and set the ad live fine.

The bold part is where this takes place. It refuses to use the new creative.

I get this error:

Exception has occurred: FacebookRequestError


  Message: Call was not successful
  Method:  POST
  Path:    https://graph.facebook.com/v17.0/act_1528844027360631/ads
  Params:  {'name': 'yarngc42pk5kms', 'creative': '{"creative_id":"575888971423418"}', 'adset_id': '6375801648255', 'status': 'ACTIVE'}

  Status:  400
  Response:
    {
      "error": {
        "message": "Invalid parameter",
        "type": "OAuthException",
        "code": 100,
        "error_subcode": 1487015,
        "is_transient": false,
        "error_user_title": "Ad Creative Invalid",
        "error_user_msg": "The ad creative is invalid.",
        "fbtrace_id": "A1J-ipZc03WREhijLmuhDBy"
      }
    }
  File "/Users/codykrecicki/Desktop/debtads/admaker/app.py", line 146, in duplicate_ad_with_new_video
    new_ad.remote_create()
  File "/Users/codykrecicki/Desktop/debtads/admaker/app.py", line 170, in create_ads_with_multiple_videos
    new_ad_id = self.duplicate_ad_with_new_video(existing_ad_id, video_path, ad_set_id, set_ad_live=True)
  File "/Users/codykrecicki/Desktop/debtads/admaker/app.py", line 218, in <module>
    ads_manager.create_ads_with_multiple_videos(existing_ad_id, done_folder, ad_set_id)
facebook_business.exceptions.FacebookRequestError: 

  Message: Call was not successful
  Method:  POST
  Path:    https://graph.facebook.com/v17.0/act_1528844027360631/ads
  Params:  {'name': 'yarngc42pk5kms', 'creative': '{"creative_id":"575888971423418"}', 'adset_id': '6375801648255', 'status': 'ACTIVE'}

  Status:  400
  Response:
    {
      "error": {
        "message": "Invalid parameter",
        "type": "OAuthException",
        "code": 100,
        "error_subcode": 1487015,
        "is_transient": false,
        "error_user_title": "Ad Creative Invalid",
        "error_user_msg": "The ad creative is invalid.",
        "fbtrace_id": "A1J-ipZc03WREhijLmuhDBy"
      }
    }

My complete FB class code.


class FacebookAdsManager:
    def __init__(self, access_token, ad_account_id, app_id):
        self.access_token = access_token
        self.ad_account_id = ad_account_id
        self.app_id = app_id
        FacebookAdsApi.init(access_token=self.access_token)

    def upload_video(self, video_path):
        new_video = AdVideo(parent_id=self.ad_account_id)
        new_video[AdVideo.Field.filepath] = video_path
        new_video.remote_create()
        return new_video['id']

    def create_unique_ad_name(self):
        return f"yarn{''.join(random.choices(string.ascii_lowercase + string.digits, k=10))}"

    def get_ad_creative_info(self, ad_id):
        try:
            ad = Ad(ad_id)
            ad.remote_read(fields=[Ad.Field.creative])
            return ad[Ad.Field.creative]
        except FacebookRequestError as e:
            if e.api_error_code() == 100 and 'Ad creative invalid' in e.api_error_message():
                print(f"The ad creative for Ad ID {ad_id} is invalid or missing.")
            else:
                print(f"Error while fetching the ad creative for Ad ID {ad_id}: {e}")
            return None

    def duplicate_ad_with_new_video(self, existing_ad_id, new_video_path, ad_set_id, set_ad_live=True):
        # Retrieve the existing Ad creative information
        existing_creative = self.get_ad_creative_info(existing_ad_id)

        if existing_creative is None:
            print("Skipping duplicate ad creation. The existing ad creative is invalid or missing.")
            return None

        new_video_id = self.upload_video(new_video_path)
        print(f"New Video ID: {new_video_id}")
        **existing_creative['id'] = new_video_id**
        # Wait for a few seconds to ensure that the newly uploaded creative is fully available
        time.sleep(5)

        **new_ad = Ad(parent_id=self.ad_account_id)
        new_ad_name = self.create_unique_ad_name()
        new_ad[Ad.Field.name] = new_ad_name
        new_ad[Ad.Field.creative] = {
            'creative_id': existing_creative['id']
        }**

        # Set the ad set ID to which the new ad belongs
        new_ad[Ad.Field.adset_id] = ad_set_id

        # Set the status field to "PAUSED" (or "ACTIVE" if you prefer the new ad to be active right away)
        new_ad[Ad.Field.status] = 'ACTIVE'

        try:
            print(f"Creating new ad with data: {new_ad.export_data()}")
            new_ad.remote_create()
        except FacebookRequestError as e:
            print(f"Error while creating the new ad: {e.api_error_message()}")
            print(f"Error code: {e.api_error_code()}")
            print(f"Error subcode: {e.api_error_subcode()}")
            return None

        if set_ad_live:
            try:
                new_ad.api_update(params={'status': 'ACTIVE'})
            except FacebookRequestError as e:
                print(f"Error while setting the new ad to ACTIVE: {e.api_error_message()}")
                print(f"Error code: {e.api_error_code()}")
                print(f"Error subcode: {e.api_error_subcode()}")
                return None

        return new_ad['id']
    
    def create_ads_with_multiple_videos(self, existing_ad_id, videos_folder, ad_set_id):
            # Get the list of video files in the specified folder
            video_files_in_folder = [os.path.join(videos_folder, f) for f in os.listdir(videos_folder) if f.endswith('.mp4')]

            for video_path in video_files_in_folder:
                # Duplicate the existing ad with the new video creative
                new_ad_id = self.duplicate_ad_with_new_video(existing_ad_id, video_path, ad_set_id, set_ad_live=True)
                print(f"New ad created with video: {video_path}")

                # Fetch and print the response of the remote_create call
                if new_ad_id:
                    try:
                        # Get an ad and copy it
                        new_ad = Ad(new_ad_id)
                        response = new_ad.remote_read(fields=[Ad.Field.name, Ad.Field.status, Ad.Field.creative])
                        print(f"Response: {response}")

                        # Move the video to the "done_uploaded" folder
                        video_filename = os.path.basename(video_path)
                        done_uploaded_folder = './done_uploaded'
                        os.makedirs(done_uploaded_folder, exist_ok=True)
                        new_video_path = os.path.join(done_uploaded_folder, video_filename)
                        shutil.move(video_path, new_video_path)
                        print(f"Video moved to: {new_video_path}")

                    except FacebookRequestError as e:
                        print(f"Error while fetching the ad information: {e.api_error_message()}")


It should use the new creative video ID. But it refuses. I have even hard coded a video ID in.

All the permissions are checked off when I made the access token. Please help.

0 Answers0