Edit

Ad Extensions Code Example

This example demonstrates how to add, get, and delete extensions for an account's ad extension library, set, get, and delete the extension associations with a campaign, and determine why an extension failed editorial reviews.

Tip

Use the language selector in the documentation header to choose C#, Java, Php, or Python.

To get access and refresh tokens for your Microsoft Advertising user and make your first service call using the Bing Ads API, see the Quick Start guide. You'll want to review the Get Started guide and walkthroughs for your preferred language e.g., C#, Java, Php, and Python.

Supporting files for C#, Java, Php, and Python examples are available at GitHub. You can clone each repository or repurpose snippets as needed.

using System;
using System.Drawing;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Threading.Tasks;
using Microsoft.BingAds.V13.CampaignManagement;
using Microsoft.BingAds;

namespace BingAdsExamplesLibrary.V13
{
    /// <summary>
    /// How to manage ad extensions for an account's ad extension library, 
    /// associate the extensions with a campaign, and determine why an extension failed 
    /// editorial review.
    /// </summary>
    public class AdExtensions : ExampleBase
    {
        // To run this example you'll need to provide your own image.  
        // For required aspect ratios and recommended dimensions please see 
        // Image remarks at https://go.microsoft.com/fwlink/?linkid=872754.

        private const string MediaFilePath = "c:\\dev\\media\\";
        private const string ImageAdExtensionMediaFileName = "imageadextension300x200.png";

        public override string Description
        {
            get { return "Ad Extensions | Campaign Management V13"; }
        }

        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment;

                CampaignManagementExampleHelper CampaignManagementExampleHelper = new CampaignManagementExampleHelper(
                    OutputStatusMessageDefault: this.OutputStatusMessage);
                CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient<ICampaignManagementService>(
                    authorizationData: authorizationData,
                    environment: environment);

                // Add a campaign to associate with ad extensions. 

                var campaigns = new[] {
                    new Campaign
                    {
                        BudgetType = BudgetLimitType.DailyBudgetStandard,
                        DailyBudget = 50,
                        Languages = new string[] { "All" },
                        Name = "Everyone's Shoes " + DateTime.UtcNow,
                        TimeZone = "PacificTimeUSCanadaTijuana",
                    }
                };

                OutputStatusMessage("-----\nAddCampaigns:");
                AddCampaignsResponse addCampaignsResponse = await CampaignManagementExampleHelper.AddCampaignsAsync(
                    accountId: authorizationData.AccountId,
                    campaigns: campaigns);
                long?[] campaignIds = addCampaignsResponse.CampaignIds.ToArray();
                BatchError[] campaignErrors = addCampaignsResponse.PartialErrors.ToArray();
                OutputStatusMessage("CampaignIds:");
                CampaignManagementExampleHelper.OutputArrayOfLong(campaignIds);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(campaignErrors);
                
                // Create media for the image ad extension that we'll add later. 

                var imageAdExtensionMedia = GetImageMedia(
                    "Image15x10",
                    MediaFilePath + ImageAdExtensionMediaFileName,
                    System.Drawing.Imaging.ImageFormat.Png);

                var media = new Media[]
                {
                    imageAdExtensionMedia
                };

                // Add the media to the account's library.

                OutputStatusMessage("-----\nAddMedia:");
                AddMediaResponse addMediaResponse = await CampaignManagementExampleHelper.AddMediaAsync(
                    accountId: authorizationData.AccountId,
                    media: media);
                long[] mediaIds = addMediaResponse.MediaIds.ToArray();
                OutputStatusMessage("MediaIds:");
                CampaignManagementExampleHelper.OutputArrayOfLong(mediaIds);

                // Add the extensions to the account's library.

                var adExtensions = new AdExtension[] {
                    new ActionAdExtension
                    {
                        ActionType = ActionAdExtensionActionType.ActNow,
                        FinalUrls = new string[]
                        {
                            "https://www.contoso.com/womenshoesale"
                        },
                        Language = "English",
                        Status = AdExtensionStatus.Active,
                    },
                    //new AppAdExtension
                    //{
                    //    AppPlatform = "Windows",
                    //    AppStoreId = "AppStoreIdGoesHere",
                    //    DestinationUrl = "DestinationUrlGoesHere",
                    //    DisplayText = "Contoso",
                    //},
                    new CallAdExtension {
                        CountryCode = "US",
                        PhoneNumber = "2065550100",
                        IsCallOnly = false,
                        // Include the call extension Monday - Friday from 9am - 9pm
                        // in the account's time zone.
                        Scheduling = new Schedule {
                            UseSearcherTimeZone = false,
                            DayTimeRanges = new[]
                            {
                                new DayTime
                                {
                                    Day = Day.Monday,
                                    StartHour = 9,
                                    StartMinute = Minute.Zero,
                                    EndHour = 21,
                                    EndMinute = Minute.Zero,
                                },
                                new DayTime
                                {
                                    Day = Day.Tuesday,
                                    StartHour = 9,
                                    StartMinute = Minute.Zero,
                                    EndHour = 21,
                                    EndMinute = Minute.Zero,
                                },
                                new DayTime
                                {
                                    Day = Day.Wednesday,
                                    StartHour = 9,
                                    StartMinute = Minute.Zero,
                                    EndHour = 21,
                                    EndMinute = Minute.Zero,
                                },
                                new DayTime
                                {
                                    Day = Day.Thursday,
                                    StartHour = 9,
                                    StartMinute = Minute.Zero,
                                    EndHour = 21,
                                    EndMinute = Minute.Zero,
                                },
                                new DayTime
                                {
                                    Day = Day.Friday,
                                    StartHour = 9,
                                    StartMinute = Minute.Zero,
                                    EndHour = 21,
                                    EndMinute = Minute.Zero,
                                },
                            },
                            StartDate = null,
                            EndDate = new Microsoft.BingAds.V13.CampaignManagement.Date {
                                Month = 12,
                                Day = 31,
                                Year = DateTime.UtcNow.Year + 1
                            },
                        }
                    },
                    new CalloutAdExtension
                    {
                        Text = "Callout Text"
                    },
                    new ImageAdExtension
                    {
                        AlternativeText = "Image Extension Alt Text",
                        ImageMediaIds = mediaIds,
                        Images = new AssetLink[]
                        {
                            new AssetLink
                            {
                                Asset = new ImageAsset
                                {
                                    Id = 12345, // 1.91 aspect ratio image id. This type of image is required for Images
                                    SubType = "LandscapeImageMedia",
                                }
                            }
                        }
                    },
                    new LocationAdExtension {
                        PhoneNumber = "206-555-0100",
                        CompanyName = "Contoso Shoes",
                        Address = new Microsoft.BingAds.V13.CampaignManagement.Address {
                            StreetAddress = "1234 Washington Place",
                            StreetAddress2 = "Suite 1210",
                            CityName = "Woodinville",
                            ProvinceName = "WA",
                            CountryCode = "US",
                            PostalCode = "98608"
                        },
                        // Include the location extension every Saturday morning
                        // in the search user's time zone.
                        Scheduling = new Schedule {
                            UseSearcherTimeZone = true,
                            DayTimeRanges = new[]
                            {
                                new DayTime
                                {
                                    Day = Day.Saturday,
                                    StartHour = 9,
                                    StartMinute = Minute.Zero,
                                    EndHour = 12,
                                    EndMinute = Minute.Zero,
                                },
                            },
                            StartDate = null,
                            EndDate = new Microsoft.BingAds.V13.CampaignManagement.Date {
                                Month = 12,
                                Day = 31,
                                Year = DateTime.UtcNow.Year + 1
                            },
                        }
                    },
                    new PriceAdExtension
                    {
                        Language = "English",
                        PriceExtensionType = PriceExtensionType.Events,
                        TableRows = new PriceTableRow[]
                        {
                            new PriceTableRow
                            {
                                CurrencyCode = "USD",
                                Description = "Come to the event",
                                FinalUrls = new string[]
                                {
                                    "https://contoso.com"
                                },
                                Header = "New Event",
                                Price = 9.99,
                                PriceQualifier = PriceQualifier.From,
                                PriceUnit = PriceUnit.PerDay,
                            },
                            new PriceTableRow
                            {
                                CurrencyCode = "USD",
                                Description = "Come to the next event",
                                FinalUrls = new string[]
                                {
                                    "https://contoso.com"
                                },
                                Header = "Next Event",
                                Price = 9.99,
                                PriceQualifier = PriceQualifier.From,
                                PriceUnit = PriceUnit.PerDay,
                            },
                            new PriceTableRow
                            {
                                CurrencyCode = "USD",
                                Description = "Come to the final event",
                                FinalUrls = new string[]
                                {
                                    "https://contoso.com"
                                },
                                Header = "Final Event",
                                Price = 9.99,
                                PriceQualifier = PriceQualifier.From,
                                PriceUnit = PriceUnit.PerDay,
                            },
                        },
                    },
                    new ReviewAdExtension
                    {
                        IsExact = true,
                        Source = "Review Source Name",
                        Text = "Review Text",
                        // The Url of the third-party review. This is not your business Url.
                        Url = "https://review.contoso.com" 
                    },
                    new SitelinkAdExtension {
                        Description1 = "Simple & Transparent.",
                        Description2 = "No Upfront Cost.",
                        DisplayText = "Everyone's Shoe Sale",
                        FinalUrls = new[] {
                            "https://www.contoso.com/womenshoesale"
                        },
                    },
                    new StructuredSnippetAdExtension
                    {
                        Header = "Brands",
                        Values = new [] { "Windows", "Xbox", "Skype"}
                    }
                };

                OutputStatusMessage("-----\nAddAdExtensions:");
                var addAdExtensionsResponse = await CampaignManagementExampleHelper.AddAdExtensionsAsync(
                    accountId: authorizationData.AccountId,
                    adExtensions: adExtensions);
                OutputStatusMessage("AdExtensionIdentities:");
                var adExtensionIdentities = addAdExtensionsResponse?.AdExtensionIdentities;
                OutputStatusMessage("NestedPartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchErrorCollection(addAdExtensionsResponse?.NestedPartialErrors);
                
                // DeleteAdExtensionsAssociations, SetAdExtensionsAssociations, and GetAdExtensionsEditorialReasons 
                // operations each require a list of type AdExtensionIdToEntityIdAssociation.
                var adExtensionIdToEntityIdAssociations = new List<AdExtensionIdToEntityIdAssociation>();

                // GetAdExtensionsByIds requires a list of type long.
                var adExtensionIds = new List<long>();

                // Loop through the list of extension IDs and build any required data structures
                // for subsequent operations. 

                foreach (var adExtensionIdentity in adExtensionIdentities)
                {
                    if (adExtensionIdentity != null)
                    {
                        adExtensionIdToEntityIdAssociations.Add(new AdExtensionIdToEntityIdAssociation
                        {
                            AdExtensionId = adExtensionIdentity.Id,
                            EntityId = (long)campaignIds[0]
                        });

                        adExtensionIds.Add(adExtensionIdentity.Id);
                    }
                }

                // Associate the ad extensions with the campaign. 

                OutputStatusMessage("-----\nSetAdExtensionsAssociations:");
                var setAdExtensionsAssociationsResponse = await CampaignManagementExampleHelper.SetAdExtensionsAssociationsAsync(
                    accountId: authorizationData.AccountId,
                    adExtensionIdToEntityIdAssociations: adExtensionIdToEntityIdAssociations,
                    associationType: AssociationType.Campaign);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(setAdExtensionsAssociationsResponse?.PartialErrors);

                // Get editorial rejection reasons for the ad extension and entity associations.

                OutputStatusMessage("-----\nGetAdExtensionsEditorialReasons:");
                var getAdExtensionsEditorialReasonsResponse = await CampaignManagementExampleHelper.GetAdExtensionsEditorialReasonsAsync(
                        accountId: authorizationData.AccountId,
                        adExtensionIdToEntityIdAssociations: adExtensionIdToEntityIdAssociations,
                        associationType: AssociationType.Campaign);
                OutputStatusMessage("EditorialReasons:");
                var adExtensionEditorialReasonCollection =
                    (AdExtensionEditorialReasonCollection[])getAdExtensionsEditorialReasonsResponse?.EditorialReasons;
                CampaignManagementExampleHelper.OutputArrayOfAdExtensionEditorialReasonCollection(adExtensionEditorialReasonCollection);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(getAdExtensionsEditorialReasonsResponse?.PartialErrors);
                
                // Get only the location ad extensions and then remove scheduling.

                AdExtensionsTypeFilter adExtensionsTypeFilter = AdExtensionsTypeFilter.LocationAdExtension;

                // In this example partial errors will be returned for indices where the ad extensions 
                // are not location ad extensions.
                // This is an example, and ideally you would only send the required ad extension IDs.

                OutputStatusMessage("-----\nGetAdExtensionsByIds:");
                var getAdExtensionsByIdsResponse = (await CampaignManagementExampleHelper.GetAdExtensionsByIdsAsync(
                    accountId: authorizationData.AccountId,
                    adExtensionIds: adExtensionIds,
                    adExtensionType: adExtensionsTypeFilter,
                    returnAdditionalFields: AdExtensionAdditionalField.DisplayText | AdExtensionAdditionalField.Images));
                adExtensions = getAdExtensionsByIdsResponse?.AdExtensions.ToArray();
                BatchError[] getAdExtensionErrors = getAdExtensionsByIdsResponse?.PartialErrors.ToArray();
                OutputStatusMessage("AdExtensions:");
                CampaignManagementExampleHelper.OutputArrayOfAdExtension(adExtensions);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(getAdExtensionErrors);
                
                var updateExtensions = new List<AdExtension>();
                var updateExtensionIds = new List<long>();

                foreach (var extension in adExtensions)
                {
                    // GetAdExtensionsByIds will return a nil element if the request conditions were not met.
                    if (extension != null && extension.Id != null)
                    {
                        // Remove read-only elements that would otherwise cause the update operation to fail.
                        var updateExtension = SetReadOnlyAdExtensionElementsToNull(extension);

                        // If you set the Scheduling element null, any existing scheduling set for the ad extension will remain unchanged. 
                        // If you set this to any non-null Schedule object, you are effectively replacing existing scheduling 
                        // for the ad extension. In this example, we will remove any existing scheduling by setting this element  
                        // to an empty Schedule object.
                        updateExtension.Scheduling = new Schedule { };
                        updateExtensions.Add(updateExtension);
                        updateExtensionIds.Add((long)updateExtension.Id);
                    }
                }

                OutputStatusMessage("-----\nUpdateAdExtensions:");                
                await CampaignManagementExampleHelper.UpdateAdExtensionsAsync(
                    accountId: authorizationData.AccountId, 
                    adExtensions: updateExtensions);
                OutputStatusMessage("Removed scheduling from the location ad extensions.");

                // Get only the location extensions to output the result.

                OutputStatusMessage("-----\nGetAdExtensionsByIds:");
                getAdExtensionsByIdsResponse = await CampaignManagementExampleHelper.GetAdExtensionsByIdsAsync(
                    accountId: authorizationData.AccountId,
                    adExtensionIds: updateExtensionIds,
                    adExtensionType: adExtensionsTypeFilter,
                    returnAdditionalFields: AdExtensionAdditionalField.DisplayText | AdExtensionAdditionalField.Images);
                adExtensions = getAdExtensionsByIdsResponse?.AdExtensions.ToArray();
                getAdExtensionErrors = getAdExtensionsByIdsResponse?.PartialErrors.ToArray();
                OutputStatusMessage("AdExtensions:");
                CampaignManagementExampleHelper.OutputArrayOfAdExtension(adExtensions);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(getAdExtensionErrors);

                // Delete the ad extension associations, ad extensions, and campaign, that were previously added.  
                // At this point the ad extensions are still available in the account's ad extensions library. 

                OutputStatusMessage("-----\nDeleteAdExtensionsAssociations:");
                await CampaignManagementExampleHelper.DeleteAdExtensionsAssociationsAsync(
                    authorizationData.AccountId,
                    adExtensionIdToEntityIdAssociations,
                    AssociationType.Campaign);
                OutputStatusMessage("Deleted ad extension associations.");

                // Delete the ad extensions from the account's ad extension library.

                OutputStatusMessage("-----\nDeleteAdExtensions:");
                await CampaignManagementExampleHelper.DeleteAdExtensionsAsync(
                    authorizationData.AccountId,
                    adExtensionIds);
                OutputStatusMessage("Deleted ad extensions.");

                // Delete the account's media that was used for the image ad extension.

                OutputStatusMessage("-----\nDeleteMedia:");
                await CampaignManagementExampleHelper.DeleteMediaAsync(
                    accountId: authorizationData.AccountId,
                    mediaIds: mediaIds);

                foreach (var id in mediaIds)
                {
                    OutputStatusMessage(string.Format("Deleted Media Id {0}", id));
                }

                // Delete the campaign and everything it contains e.g., ad groups and ads.

                OutputStatusMessage("-----\nDeleteCampaigns:");
                await CampaignManagementExampleHelper.DeleteCampaignsAsync(
                    accountId: authorizationData.AccountId,
                    campaignIds: new[] { (long)campaignIds[0] });
                OutputStatusMessage(string.Format("Deleted Campaign Id {0}", campaignIds[0]));
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Campaign Management service exceptions
            catch (FaultException<Microsoft.BingAds.V13.CampaignManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException<Microsoft.BingAds.V13.CampaignManagement.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException<Microsoft.BingAds.V13.CampaignManagement.EditorialApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            // Catch Customer Management service exceptions
            catch (FaultException<Microsoft.BingAds.V13.CustomerManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException<Microsoft.BingAds.V13.CustomerManagement.ApiFault> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }

        /// <summary>
        /// Get image media that can be managed with the Campaign Management API.
        /// </summary>
        /// <param name="mediaType">The media type reflects the aspect ratio.</param>
        /// <param name="imageFileName">The file name and path.</param>
        /// <param name="imageFormat">For supported image formats see <see href="https://go.microsoft.com/fwlink/?linkid=872754">Image remarks</see>.</param>
        /// <returns>A Campaign Management Image object.</returns>
        private Microsoft.BingAds.V13.CampaignManagement.Image GetImageMedia(
            string mediaType,
            string imageFileName,
            System.Drawing.Imaging.ImageFormat imageFormat)
        {
            var image = new Microsoft.BingAds.V13.CampaignManagement.Image();
            image.Data = GetBmpBase64String(imageFileName, imageFormat);
            image.MediaType = mediaType;
            image.Type = "Image";

            return image;
        }

        /// <summary>
        /// Get the image media as base64 string.
        /// </summary>
        /// <param name="imageFileName">The file name and path.</param>
        /// <param name="imageFormat">For supported image formats see <see href="https://go.microsoft.com/fwlink/?linkid=872754">Image remarks</see>.</param>
        /// <returns></returns>
        private string GetBmpBase64String(
            string imageFileName,
            System.Drawing.Imaging.ImageFormat imageFormat)
        {
            var bmp = new Bitmap(imageFileName);
            using (MemoryStream ms = new MemoryStream())
            {
                bmp.Save(ms, imageFormat);
                byte[] imageBytes = ms.ToArray();
                string base64String = Convert.ToBase64String(imageBytes);
                return base64String;
            }
        }        
    }
}
package com.microsoft.bingads.examples.v13;

import com.microsoft.bingads.*;
import com.microsoft.bingads.v13.campaignmanagement.*;

import java.util.ArrayList;
import java.util.Calendar;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.util.Base64;

public class AdExtensions extends ExampleBase {

    public static void main(java.lang.String[] args) {
        
    // To run this example you'll need to provide your own image.  
        // For required aspect ratios and recommended dimensions please see 
        // Image remarks at https://go.microsoft.com/fwlink/?linkid=872754.

        java.lang.String MEDIA_FILE_PATH = "c:\\dev\\media\\";
        java.lang.String IMAGE_AD_EXTENSION_MEDIA_FILE_NAME = "imageadextension300x200.png";
        
        try
        {
            authorizationData = getAuthorizationData();

            CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient<ICampaignManagementService>(
                    authorizationData,
                    API_ENVIRONMENT,
                    ICampaignManagementService.class);
                        
            Calendar calendar = Calendar.getInstance();
                                      
            // Add a campaign to associate with ad extensions. 

            ArrayOfCampaign campaigns = new ArrayOfCampaign();
            Campaign campaign = new Campaign();
            campaign.setBudgetType(BudgetLimitType.DAILY_BUDGET_STANDARD);
            campaign.setDailyBudget(50.00);
            ArrayOfstring languages = new ArrayOfstring();
            languages.getStrings().add("All");
            campaign.setLanguages(languages);
            campaign.setName("Everyone's Shoes " + System.currentTimeMillis());
            campaign.setTimeZone("PacificTimeUSCanadaTijuana");
            campaigns.getCampaigns().add(campaign);

            outputStatusMessage("-----\nAddCampaigns:");
            AddCampaignsResponse addCampaignsResponse = CampaignManagementExampleHelper.addCampaigns(
                authorizationData.getAccountId(), 
                campaigns
            );            
            ArrayOfNullableOflong campaignIds = addCampaignsResponse.getCampaignIds();
            ArrayOfBatchError campaignErrors = addCampaignsResponse.getPartialErrors();
            outputStatusMessage("CampaignIds:");
            CampaignManagementExampleHelper.outputArrayOfNullableOflong(campaignIds);
            outputStatusMessage("PartialErrors:");
            CampaignManagementExampleHelper.outputArrayOfBatchError(campaignErrors);
            
            // Create media for the image ad extension that we'll add later. 
            
            Image imageAdExtensionMedia = getImageMedia(
                "Image15x10",
                MEDIA_FILE_PATH + IMAGE_AD_EXTENSION_MEDIA_FILE_NAME);

            ArrayOfMedia addMedia = new ArrayOfMedia();
            addMedia.getMedias().add(imageAdExtensionMedia);
            CampaignManagementExampleHelper.outputArrayOfMedia(addMedia);

            outputStatusMessage("-----\nAddMedia:");
            ArrayOflong mediaIds = CampaignManagementExampleHelper.addMedia(
                authorizationData.getAccountId(),
                addMedia).getMediaIds();
            outputStatusMessage("MediaIds:");
            CampaignManagementExampleHelper.outputArrayOflong(mediaIds);

            // Add the extensions to the account's library.

            ArrayOfAdExtension adExtensions = new ArrayOfAdExtension();
            
            ActionAdExtension actionAdExtension = new ActionAdExtension();
            actionAdExtension.setActionType(ActionAdExtensionActionType.ACT_NOW);
            com.microsoft.bingads.v13.campaignmanagement.ArrayOfstring finalUrls = new com.microsoft.bingads.v13.campaignmanagement.ArrayOfstring();
            finalUrls.getStrings().add("https://www.contoso.com/womenshoesale");
            actionAdExtension.setFinalUrls(finalUrls);
            actionAdExtension.setLanguage("English");
            actionAdExtension.setStatus(AdExtensionStatus.ACTIVE);
            adExtensions.getAdExtensions().add(actionAdExtension);

            AppAdExtension appAdExtension = new AppAdExtension();
            appAdExtension.setAppPlatform("Windows");
            appAdExtension.setAppStoreId("AppStoreIdGoesHere");
            appAdExtension.setDestinationUrl("DestinationUrlGoesHere");
            appAdExtension.setDisplayText("Contoso");
            // If you supply the AppAdExtension properties above, then you can add this line.
            //adExtensions.getAdExtensions().add(appAdExtension);

            CallAdExtension callAdExtension = new CallAdExtension();
            callAdExtension.setCountryCode("US");
            callAdExtension.setPhoneNumber("2065550100");
            callAdExtension.setIsCallOnly(false);
            // Include the call extension Monday - Friday from 9am - 9pm
            // in the account's time zone.
            Schedule callScheduling = new Schedule();
            ArrayOfDayTime callDayTimeRanges = new ArrayOfDayTime();
            DayTime callMonday = new DayTime();
            callMonday.setDay(Day.MONDAY);
            callMonday.setStartHour(9);
            callMonday.setStartMinute(Minute.ZERO);
            callMonday.setEndHour(21);
            callMonday.setEndMinute(Minute.ZERO);
            callDayTimeRanges.getDayTimes().add(callMonday);
            DayTime callTuesday = new DayTime();
            callTuesday.setDay(Day.TUESDAY);
            callTuesday.setStartHour(9);
            callTuesday.setStartMinute(Minute.ZERO);
            callTuesday.setEndHour(21);
            callTuesday.setEndMinute(Minute.ZERO);
            callDayTimeRanges.getDayTimes().add(callTuesday);
            DayTime callWednesday = new DayTime();
            callWednesday.setDay(Day.WEDNESDAY);
            callWednesday.setStartHour(9);
            callWednesday.setStartMinute(Minute.ZERO);
            callWednesday.setEndHour(21);
            callWednesday.setEndMinute(Minute.ZERO);
            callDayTimeRanges.getDayTimes().add(callWednesday);
            DayTime callThursday = new DayTime();
            callThursday.setDay(Day.THURSDAY);
            callThursday.setStartHour(9);
            callThursday.setStartMinute(Minute.ZERO);
            callThursday.setEndHour(21);
            callThursday.setEndMinute(Minute.ZERO);
            callDayTimeRanges.getDayTimes().add(callThursday);
            DayTime callFriday = new DayTime();
            callFriday.setDay(Day.FRIDAY);
            callFriday.setStartHour(9);
            callFriday.setStartMinute(Minute.ZERO);
            callFriday.setEndHour(21);
            callFriday.setEndMinute(Minute.ZERO);
            callDayTimeRanges.getDayTimes().add(callFriday);
            callScheduling.setDayTimeRanges(callDayTimeRanges);
            callScheduling.setEndDate(new com.microsoft.bingads.v13.campaignmanagement.Date());
            callScheduling.getEndDate().setDay(31);
            callScheduling.getEndDate().setMonth(12);
            callScheduling.getEndDate().setYear(calendar.get(Calendar.YEAR) + 1);
            callScheduling.setStartDate(null);
            callAdExtension.setScheduling(callScheduling);
            adExtensions.getAdExtensions().add(callAdExtension);

            CalloutAdExtension calloutAdExtension = new CalloutAdExtension();
            calloutAdExtension.setText("Callout text");
            adExtensions.getAdExtensions().add(calloutAdExtension);

            LocationAdExtension locationAdExtension = new LocationAdExtension();
            locationAdExtension.setPhoneNumber("206-555-0100");
            locationAdExtension.setCompanyName("Contoso Shoes");
            com.microsoft.bingads.v13.campaignmanagement.Address address = 
                    new com.microsoft.bingads.v13.campaignmanagement.Address();
            address.setStreetAddress("1234 Washington Place");
            address.setStreetAddress2("Suite 1210");
            address.setCityName("Woodinville");
            address.setProvinceName("WA"); 
            address.setCountryCode("US");
            address.setPostalCode("98608");
            locationAdExtension.setAddress(address);
            // Include the location extension every Saturday morning
            // in the search user's time zone.
            Schedule locationScheduling = new Schedule();
            ArrayOfDayTime locationDayTimeRanges = new ArrayOfDayTime();
            DayTime locationDayTime = new DayTime();
            locationDayTime.setDay(Day.SATURDAY);
            locationDayTime.setStartHour(9);
            locationDayTime.setStartMinute(Minute.ZERO);
            locationDayTime.setEndHour(12);
            locationDayTime.setEndMinute(Minute.ZERO);
            locationDayTimeRanges.getDayTimes().add(locationDayTime);
            locationScheduling.setDayTimeRanges(locationDayTimeRanges);
            locationScheduling.setEndDate(new com.microsoft.bingads.v13.campaignmanagement.Date());
            locationScheduling.getEndDate().setDay(31);
            locationScheduling.getEndDate().setMonth(12);
            locationScheduling.getEndDate().setYear(calendar.get(Calendar.YEAR) + 1);
            locationScheduling.setStartDate(null);
            locationAdExtension.setScheduling(locationScheduling);
            adExtensions.getAdExtensions().add(locationAdExtension);
            
            PriceAdExtension priceAdExtension = new PriceAdExtension();
            priceAdExtension.setLanguage("English");
            priceAdExtension.setPriceExtensionType(PriceExtensionType.EVENTS);
            ArrayOfPriceTableRow tableRows = new ArrayOfPriceTableRow();
            PriceTableRow tableRowA = new PriceTableRow();
            tableRowA.setCurrencyCode("USD");
            tableRowA.setDescription("Come to the event");
            tableRowA.setFinalUrls(finalUrls);
            tableRowA.setHeader("New Event");
            tableRowA.setPrice(9.99D);
            tableRowA.setPriceQualifier(PriceQualifier.FROM);
            tableRowA.setPriceUnit(PriceUnit.PER_DAY);
            tableRows.getPriceTableRows().add(tableRowA);
            PriceTableRow tableRowB = new PriceTableRow();
            tableRowB.setCurrencyCode("USD");
            tableRowB.setDescription("Come to the next event");
            tableRowB.setFinalUrls(finalUrls);
            tableRowB.setHeader("Next Event");
            tableRowB.setPrice(9.99D);
            tableRowB.setPriceQualifier(PriceQualifier.FROM);
            tableRowB.setPriceUnit(PriceUnit.PER_DAY);
            tableRows.getPriceTableRows().add(tableRowB);
            PriceTableRow tableRowC = new PriceTableRow();
            tableRowC.setCurrencyCode("USD");
            tableRowC.setDescription("Come to the final event");
            tableRowC.setFinalUrls(finalUrls);
            tableRowC.setHeader("Final Event");
            tableRowC.setPrice(9.99D);
            tableRowC.setPriceQualifier(PriceQualifier.FROM);
            tableRowC.setPriceUnit(PriceUnit.PER_DAY);
            tableRows.getPriceTableRows().add(tableRowC);
            priceAdExtension.setTableRows(tableRows);
            adExtensions.getAdExtensions().add(priceAdExtension);

            ReviewAdExtension reviewAdExtension = new ReviewAdExtension();
            reviewAdExtension.setIsExact(true);
            reviewAdExtension.setSource("Review Source Name");
            reviewAdExtension.setText("Review Text");
            // The Url of the third-party review. This is not your business Url.
            reviewAdExtension.setUrl("https://review.contoso.com"); 
            adExtensions.getAdExtensions().add(reviewAdExtension);
            
            SitelinkAdExtension sitelinkAdExtension = new SitelinkAdExtension();
            sitelinkAdExtension.setDescription1("Simple & Transparent.");
            sitelinkAdExtension.setDescription2("No Upfront Cost.");
            sitelinkAdExtension.setDisplayText("Everyone's Shoe Sale");
            sitelinkAdExtension.setFinalUrls(finalUrls);
            adExtensions.getAdExtensions().add(sitelinkAdExtension);
                        
            StructuredSnippetAdExtension structuredSnippetAdExtension = new StructuredSnippetAdExtension();
            structuredSnippetAdExtension.setHeader("Brands");
            com.microsoft.bingads.v13.campaignmanagement.ArrayOfstring values = new com.microsoft.bingads.v13.campaignmanagement.ArrayOfstring();
            values.getStrings().add("Windows");
            values.getStrings().add("Xbox");
            values.getStrings().add("Skype");
            structuredSnippetAdExtension.setValues(values);
            adExtensions.getAdExtensions().add(structuredSnippetAdExtension);            
            
            outputStatusMessage("-----\nAddAdExtensions:");
            AddAdExtensionsResponse addAdExtensionsResponse = CampaignManagementExampleHelper.addAdExtensions(
                authorizationData.getAccountId(),
                adExtensions);
            outputStatusMessage("AdExtensionIdentities:");
            ArrayOfAdExtensionIdentity adExtensionIdentities = addAdExtensionsResponse.getAdExtensionIdentities();
            outputStatusMessage("NestedPartialErrors:");
            CampaignManagementExampleHelper.outputArrayOfBatchErrorCollection(addAdExtensionsResponse.getNestedPartialErrors());
            
            // DeleteAdExtensionsAssociations, SetAdExtensionsAssociations, and GetAdExtensionsEditorialReasons 
            // operations each require a list of type AdExtensionIdToEntityIdAssociation.
            ArrayOfAdExtensionIdToEntityIdAssociation adExtensionIdToEntityIdAssociations = new ArrayOfAdExtensionIdToEntityIdAssociation();

            // GetAdExtensionsByIds requires a list of type long.
            ArrayOflong adExtensionIds = new ArrayOflong();

            // Loop through the list of extension IDs and build any required data structures
            // for subsequent operations. 

            for (AdExtensionIdentity adExtensionIdentity : adExtensionIdentities.getAdExtensionIdentities()) {
                AdExtensionIdToEntityIdAssociation adExtensionIdToEntityIdAssociation = new AdExtensionIdToEntityIdAssociation();
                adExtensionIdToEntityIdAssociation.setAdExtensionId(adExtensionIdentity.getId());
                adExtensionIdToEntityIdAssociation.setEntityId(campaignIds.getLongs().get(0));
                adExtensionIdToEntityIdAssociations.getAdExtensionIdToEntityIdAssociations().add(adExtensionIdToEntityIdAssociation);

                adExtensionIds.getLongs().add(adExtensionIdentity.getId());
            }

            // Associate the ad extensions with the campaign. 
            
            outputStatusMessage("-----\nSetAdExtensionsAssociations:");
            SetAdExtensionsAssociationsResponse setAdExtensionsAssociationsResponse = CampaignManagementExampleHelper.setAdExtensionsAssociations(
                authorizationData.getAccountId(), 
                adExtensionIdToEntityIdAssociations, 
                AssociationType.CAMPAIGN);
            outputStatusMessage("PartialErrors:");
            CampaignManagementExampleHelper.outputArrayOfBatchError(setAdExtensionsAssociationsResponse.getPartialErrors());
            
            // Get editorial rejection reasons for the ad extension and entity associations.
            
            outputStatusMessage("-----\nGetAdExtensionsEditorialReasons:");
            GetAdExtensionsEditorialReasonsResponse getAdExtensionsEditorialReasonsResponse = CampaignManagementExampleHelper.getAdExtensionsEditorialReasons(
                authorizationData.getAccountId(), 
                adExtensionIdToEntityIdAssociations, 
                AssociationType.CAMPAIGN);
            outputStatusMessage("EditorialReasons:");
            ArrayOfAdExtensionEditorialReasonCollection adExtensionEditorialReasonCollection = getAdExtensionsEditorialReasonsResponse.getEditorialReasons();
            CampaignManagementExampleHelper.outputArrayOfAdExtensionEditorialReasonCollection(adExtensionEditorialReasonCollection);
            outputStatusMessage("PartialErrors:");
            CampaignManagementExampleHelper.outputArrayOfBatchError(getAdExtensionsEditorialReasonsResponse.getPartialErrors());
            
            // Get only the location extensions and remove scheduling.

            ArrayList<AdExtensionsTypeFilter> adExtensionsTypeFilter = new ArrayList<AdExtensionsTypeFilter>();
            adExtensionsTypeFilter.add(AdExtensionsTypeFilter.LOCATION_AD_EXTENSION);
            
            ArrayList<AdExtensionAdditionalField> returnAdditionalFields = new ArrayList<AdExtensionAdditionalField>();
            returnAdditionalFields.add(AdExtensionAdditionalField.DISPLAY_TEXT);
            returnAdditionalFields.add(AdExtensionAdditionalField.IMAGES);

            // In this example partial errors will be returned for indices where the ad extensions 
            // are not location ad extensions.
            // This is an example, and ideally you would only send the required ad extension IDs.
            
            outputStatusMessage("-----\nGetAdExtensionsByIds:");
            GetAdExtensionsByIdsResponse getAdExtensionsByIdsResponse = CampaignManagementExampleHelper.getAdExtensionsByIds(
                authorizationData.getAccountId(),
                adExtensionIds,
                adExtensionsTypeFilter,
                returnAdditionalFields);
            adExtensions = getAdExtensionsByIdsResponse.getAdExtensions();
            outputStatusMessage("AdExtensions:");
            CampaignManagementExampleHelper.outputArrayOfAdExtension(adExtensions);
            outputStatusMessage("PartialErrors:");
            CampaignManagementExampleHelper.outputArrayOfBatchError(getAdExtensionsByIdsResponse.getPartialErrors());     

            ArrayOfAdExtension updateExtensions = new ArrayOfAdExtension();
            ArrayOflong updateExtensionIds = new ArrayOflong();

            for (AdExtension extension : adExtensions.getAdExtensions())
            {
                // GetAdExtensionsByIds will return a nil element if the request conditions were not met.
                if(extension != null && extension.getId() != null)
                {
                    // Remove read-only elements that would otherwise cause the update operation to fail.
                    AdExtension updateExtension = setReadOnlyAdExtensionElementsToNull(extension);

                    // If you set the Scheduling element null, any existing scheduling set for the ad extension will remain unchanged. 
                    // If you set this to any non-null Schedule object, you are effectively replacing existing scheduling 
                    // for the ad extension. In this example, we will remove any existing scheduling by setting this element  
                    // to an empty Schedule object.
                    updateExtension.setScheduling(new Schedule());
                    updateExtensions.getAdExtensions().add(updateExtension);
                    updateExtensionIds.getLongs().add((long)updateExtension.getId());
                }
            }

            outputStatusMessage("-----\nUpdateAdExtensions:"); 
            CampaignManagementExampleHelper.updateAdExtensions(
                    authorizationData.getAccountId(), 
                    updateExtensions);
            outputStatusMessage("Removed scheduling from the location ad extensions.");

            // Get only the location extension to output the result.
            
            outputStatusMessage("-----\nGetAdExtensionsByIds:");
            getAdExtensionsByIdsResponse = CampaignManagementExampleHelper.getAdExtensionsByIds(
                authorizationData.getAccountId(),
                adExtensionIds,
                adExtensionsTypeFilter,
                returnAdditionalFields);
            adExtensions = getAdExtensionsByIdsResponse.getAdExtensions();
            outputStatusMessage("AdExtensions:");
            CampaignManagementExampleHelper.outputArrayOfAdExtension(adExtensions);
            outputStatusMessage("PartialErrors:");
            CampaignManagementExampleHelper.outputArrayOfBatchError(getAdExtensionsByIdsResponse.getPartialErrors());  

            // Delete the ad extension associations, ad extensions, and campaign, that were previously added.  
            // At this point the ad extensions are still available in the account's ad extensions library. 
            
            outputStatusMessage("-----\nDeleteAdExtensionsAssociations:");
            CampaignManagementExampleHelper.deleteAdExtensionsAssociations(
                authorizationData.getAccountId(),
                adExtensionIdToEntityIdAssociations,
                AssociationType.CAMPAIGN);
            outputStatusMessage("Deleted ad extension associations.");

            // Delete the ad extensions from the account’s ad extension library.

            outputStatusMessage("-----\nDeleteAdExtensions:");
            CampaignManagementExampleHelper.deleteAdExtensions(
                authorizationData.getAccountId(),
                adExtensionIds);
            outputStatusMessage("Deleted ad extensions.");
            
            // Delete the account's media that was used for the image ad extension.
            
            outputStatusMessage("-----\nDeleteMedia:");
            CampaignManagementExampleHelper.deleteMedia(
                    authorizationData.getAccountId(), 
                    mediaIds);

            for (java.lang.Long id : mediaIds.getLongs())
            {
                outputStatusMessage(String.format("Deleted Media Id %s", id));
            }

            // Delete the campaign and everything it contains e.g., ad groups and ads.

            outputStatusMessage("-----\nDeleteCampaigns:");
            ArrayOflong deleteCampaignIds = new ArrayOflong();
            deleteCampaignIds.getLongs().add(campaignIds.getLongs().get(0));
            CampaignManagementExampleHelper.deleteCampaigns(
                    authorizationData.getAccountId(), 
                    deleteCampaignIds);
            outputStatusMessage(String.format("Deleted CampaignId %d", deleteCampaignIds.getLongs().get(0)));        
        } 
        catch (Exception ex) {
            String faultXml = ExampleExceptionHelper.getBingAdsExceptionFaultXml(ex, System.out);
            outputStatusMessage(faultXml);
            String message = ExampleExceptionHelper.handleBingAdsSDKException(ex, System.out);
            outputStatusMessage(message);
        }
    }        
    
    // Get image media that can be managed with the Campaign Management API.

    static Image getImageMedia(
        java.lang.String mediaType, 
        java.lang.String imageFileName) throws UnsupportedEncodingException, IOException
    {
        Image image = new Image();
        image.setData(getBmpBase64String(imageFileName));
        image.setMediaType(mediaType);
        image.setType("Image");

        return image;
    }

    // Get the image media as base64 string.

    static java.lang.String getBmpBase64String(
        java.lang.String imageFileName) throws UnsupportedEncodingException, IOException
    {
        File fi = new File(imageFileName);
        byte[] imageBytes = Files.readAllBytes(fi.toPath());
        java.lang.String base64String = new java.lang.String(Base64.getEncoder().encode(imageBytes), "UTF-8");
        return base64String;
    }
}

Warning

It looks like the sample you are looking for has moved! Rest assured we are working on resolving this.

import uuid
from auth_helper import *
from openapi_client.models.campaign import *

# Media file path - update with your own image
MEDIA_FILE_PATH = "c:\\dev\\media\\"
IMAGE_AD_EXTENSION_FILE_NAME = "imageadextension300x200.png"

def main(authorization_data):
    try:
        # Create a search campaign
        print("Creating campaign...")
        
        campaign = Campaign(
            name="Women's Shoes " + str(uuid.uuid4()),
            budget_type=BudgetLimitType.DAILYBUDGETSTANDARD,
            daily_budget=50.00,
            languages=['All'],
            time_zone='PacificTimeUSCanadaTijuana',
            campaign_type=CampaignType.SEARCH
        )
        
        add_campaigns_request = AddCampaignsRequest(
            account_id=authorization_data.account_id,
            campaigns=[campaign]
        )
        
        add_campaigns_response = campaign_service.add_campaigns(
            add_campaigns_request=add_campaigns_request
        )
        
        campaign_ids = add_campaigns_response.CampaignIds
        print(f"Created Campaign ID: {campaign_ids[0]}")
        
        # Create ad extensions
        print("\nCreating ad extensions...")
        
        ad_extensions = []
        
        # Action Ad Extension
        action_extension = ActionAdExtension(
            action_type=ActionAdExtensionActionType.ACTNOW,
            final_urls=["http://www.contoso.com/womenshoesale"],
            language="English",
            status=AdExtensionStatus.ACTIVE
        )
        ad_extensions.append(action_extension)
        
        # Call Ad Extension with scheduling
        call_extension = CallAdExtension(
            country_code="US",
            phone_number="2065550100",
            is_call_only=False
        )
        
        # Schedule for Monday-Friday 9am-9pm
        call_day_time_ranges = []
        for day in [Day.MONDAY, Day.TUESDAY, Day.WEDNESDAY, Day.THURSDAY, Day.FRIDAY]:
            day_time = DayTime(
                day=day,
                start_hour=9,
                start_minute=Minute.ZERO,
                end_hour=21,
                end_minute=Minute.ZERO
            )
            call_day_time_ranges.append(day_time)
        
        from datetime import datetime
        current_year = datetime.now().year
        
        call_scheduling = Schedule(
            day_time_ranges=call_day_time_ranges,
            use_searcher_time_zone=False,
            start_date=None,
            end_date=Date(day=31, month=12, year=current_year)
        )
        call_extension.Scheduling = call_scheduling
        ad_extensions.append(call_extension)
        
        # Callout Ad Extension
        callout_extension = CalloutAdExtension(
            text="Callout Text"
        )
        ad_extensions.append(callout_extension)
        
        # Location Ad Extension
        location_extension = LocationAdExtension(
            phone_number="206-555-0100",
            company_name="Alpine Ski House",
            address=Address(
                street_address="1234 Washington Place",
                street_address2="Suite 1210",
                city_name="Woodinville",
                province_name="WA",
                country_code="US",
                postal_code="98608"
            )
        )
        
        # Schedule for Saturday morning
        location_day_time = DayTime(
            day=Day.SATURDAY,
            start_hour=9,
            start_minute=Minute.ZERO,
            end_hour=12,
            end_minute=Minute.ZERO
        )
        
        location_scheduling = Schedule(
            day_time_ranges=[location_day_time],
            use_searcher_time_zone=False,
            start_date=None,
            end_date=Date(day=31, month=12, year=current_year)
        )
        location_extension.Scheduling = location_scheduling
        ad_extensions.append(location_extension)
        
        # Price Ad Extension
        price_extension = PriceAdExtension(
            language="English",
            price_extension_type="Events",
            table_rows=[
                PriceTableRow(
                    currency_code="USD",
                    description="Come to the event",
                    final_urls=["http://www.contoso.com/womenshoesale"],
                    header="New Event",
                    price=9.99,
                    price_qualifier="From",
                    price_unit="PerDay"
                ),
                PriceTableRow(
                    currency_code="USD",
                    description="Come to the next event",
                    final_urls=["http://www.contoso.com/womenshoesale"],
                    header="Next Event",
                    price=9.99,
                    price_qualifier="From",
                    price_unit="PerDay"
                ),
                PriceTableRow(
                    currency_code="USD",
                    description="Come to the final event",
                    final_urls=["http://www.contoso.com/womenshoesale"],
                    header="Final Event",
                    price=9.99,
                    price_qualifier="From",
                    price_unit="PerDay"
                )
            ]
        )
        ad_extensions.append(price_extension)
        
        # Review Ad Extension
        review_extension = ReviewAdExtension(
            is_exact=True,
            source="Review Source Name",
            text="Review Text",
            url="http://review.contoso.com"
        )
        ad_extensions.append(review_extension)
        
        # Sitelink Ad Extension
        sitelink_extension = SitelinkAdExtension(
            description1="Simple & Transparent.",
            description2="No Upfront Cost.",
            display_text="Women's Shoe Sale",
            final_urls=["http://www.contoso.com/womenshoesale"]
        )
        ad_extensions.append(sitelink_extension)
        
        # Structured Snippet Ad Extension
        structured_snippet_extension = StructuredSnippetAdExtension(
            header="Brands",
            values=["Windows", "Xbox", "Skype"]
        )
        ad_extensions.append(structured_snippet_extension)
        
        # Add all extensions to the account's ad extension library
        add_extensions_request = AddAdExtensionsRequest(
            account_id=authorization_data.account_id,
            ad_extensions=ad_extensions
        )
        
        add_extensions_response = campaign_service.add_ad_extensions(
            add_ad_extensions_request=add_extensions_request
        )
        
        ad_extension_identities = add_extensions_response.AdExtensionIdentities
        print(f"Added {len(ad_extension_identities)} ad extensions")
        
        if add_extensions_response.NestedPartialErrors:
            print(f"Nested Partial Errors: {add_extensions_response.NestedPartialErrors}")
        
        # Build associations
        ad_extension_id_to_entity_id_associations = []
        ad_extension_ids = []
        
        for identity in ad_extension_identities:
            if identity and identity.Id:
                association = AdExtensionIdToEntityIdAssociation(
                    ad_extension_id=identity.Id,
                    entity_id=campaign_ids[0]
                )
                ad_extension_id_to_entity_id_associations.append(association)
                ad_extension_ids.append(identity.Id)
        
        # Associate the ad extensions with the campaign
        print("\nAssociating ad extensions with campaign...")
        
        set_associations_request = SetAdExtensionsAssociationsRequest(
            account_id=authorization_data.account_id,
            ad_extension_id_to_entity_id_associations=ad_extension_id_to_entity_id_associations,
            association_type=AssociationType.CAMPAIGN
        )
        
        set_associations_response = campaign_service.set_ad_extensions_associations(
            set_ad_extensions_associations_request=set_associations_request
        )
        
        if set_associations_response.PartialErrors:
            print(f"Partial Errors: {set_associations_response.PartialErrors}")
        else:
            print("Ad extensions successfully associated with campaign")
        
        # Get editorial rejection reasons
        print("\nGetting editorial reasons...")
        
        get_editorial_request = GetAdExtensionsEditorialReasonsRequest(
            account_id=authorization_data.account_id,
            ad_extension_id_to_entity_id_associations=ad_extension_id_to_entity_id_associations,
            association_type=AssociationType.CAMPAIGN
        )
        
        editorial_response = campaign_service.get_ad_extensions_editorial_reasons(
            get_ad_extensions_editorial_reasons_request=get_editorial_request
        )
        
        if editorial_response.EditorialReasons:
            print(f"Editorial Reasons: {editorial_response.EditorialReasons}")
        
        # Get location and call extensions
        print("\nGetting location and call extensions...")
        
        get_extensions_request = GetAdExtensionsByIdsRequest(
            account_id=authorization_data.account_id,
            ad_extension_ids=ad_extension_ids,
            ad_extension_type= AdExtensionsTypeFilter.LOCATIONADEXTENSION | AdExtensionsTypeFilter.CALLADEXTENSION
            ,
            return_additional_fields=None
        )
        
        get_extensions_response = campaign_service.get_ad_extensions_by_ids(
            get_ad_extensions_by_ids_request=get_extensions_request
        )
        
        extensions_to_update = []
        
        for extension in get_extensions_response.AdExtensions:
            if extension and extension.Id:
                # Remove scheduling
                extension.Scheduling = Schedule()
                extensions_to_update.append(extension)
        
        # Update extensions to remove scheduling
        if extensions_to_update:
            print("\nUpdating extensions to remove scheduling...")
            
            update_request = UpdateAdExtensionsRequest(
                account_id=authorization_data.account_id,
                ad_extensions=extensions_to_update
            )
            
            update_response = campaign_service.update_ad_extensions(
                update_ad_extensions_request=update_request
            )
            
            if update_response.NestedPartialErrors:
                print(f"Nested Partial Errors: {update_response.NestedPartialErrors}")
            else:
                print("Removed scheduling from extensions")
        
        # Clean up - delete associations
        print("\nDeleting ad extension associations...")
        
        delete_associations_request = DeleteAdExtensionsAssociationsRequest(
            account_id=authorization_data.account_id,
            ad_extension_id_to_entity_id_associations=ad_extension_id_to_entity_id_associations,
            association_type=AssociationType.CAMPAIGN
        )
        
        delete_associations_response = campaign_service.delete_ad_extensions_associations(
            delete_ad_extensions_associations_request=delete_associations_request
        )
        
        if delete_associations_response.PartialErrors:
            print(f"Partial Errors: {delete_associations_response.PartialErrors}")
        
        # Delete ad extensions
        print("Deleting ad extensions...")
        
        delete_extensions_request = DeleteAdExtensionsRequest(
            account_id=authorization_data.account_id,
            ad_extension_ids=ad_extension_ids
        )
        
        delete_extensions_response = campaign_service.delete_ad_extensions(
            delete_ad_extensions_request=delete_extensions_request
        )
        
        if delete_extensions_response.PartialErrors:
            print(f"Partial Errors: {delete_extensions_response.PartialErrors}")
        else:
            print("Deleted ad extensions")
        
        # Delete campaign
        print("Deleting campaign...")
        
        delete_campaigns_request = DeleteCampaignsRequest(
            account_id=authorization_data.account_id,
            campaign_ids=campaign_ids
        )
        
        campaign_service.delete_campaigns(
            delete_campaigns_request=delete_campaigns_request
        )
        
        print(f"Deleted Campaign ID {campaign_ids[0]}")
        
    except Exception as ex:
        print(f"Error occurred: {str(ex)}")

if __name__ == '__main__':
    print("Loading the web service client...")
    
    authorization_data = AuthorizationData(
        account_id=None,
        customer_id=None,
        developer_token=DEVELOPER_TOKEN,
        authentication=None,
    )
    
    authenticate(authorization_data)
    
    campaign_service = ServiceClient(
        service='CampaignManagementService',
        version=13,
        authorization_data=authorization_data,
        environment=ENVIRONMENT,
    )
    
    main(authorization_data)

See Also

Get Started with the Bing Ads API