Export (0) Print
Expand All

Keywords in C#

This example shows how to create a keyword, set the keyword's destination URL, and get the keyword and destination URL using the following Campaign Management service operations. If the keyword is disapproved, this example also shows how to get the reasons of why it failed editorial review.

This example has been developed and run within the environment described in Getting Started Using C# and Visual Basic with Bing Ads Services.

System_CLiX_note Note

This example uses the UserName and Password elements for authentication. For Managing User Authentication with OAuth, replace the UserName and Password elements with the AuthenticationToken, which is your OAuth access token.


using System;
using System.Globalization;
using System.ServiceModel;

using Keywords.BingAds.CampaignManagement;

namespace Keywords
{
    class Program
    {
        private static CampaignManagementServiceClient _service;

        // Specify your credentials.

        private const string UserName = "<UserNameGoesHere>";
        private const string Password = "<PasswordGoesHere>";
        private const string DeveloperToken = "<DeveloperTokenGoesHere>";
        private const long CustomerId = <CustomerIdGoesHere>;
        private const long AccountId = <AccountIdGoesHere>;
        private const long AdGroupId = <AdGroupIdGoesHere>;


        static void Main()
        {
            const string destinationUrl = "http://AlpineSkiHouse.com/GloveSale/";

            try
            {
                _service = new CampaignManagementServiceClient();

                long[] keywordIds = AddKeywords(AccountId, AdGroupId);
                SetKeywordDestinationUrl(AccountId, AdGroupId, keywordIds, destinationUrl);
                PrintKeywords(CustomerId, AccountId, AdGroupId, keywordIds);

                _service.Close();
            }
            catch (CommunicationException e)
            {
                Console.WriteLine(e.Message);

                if (e.InnerException != null)
                {
                    Console.WriteLine("\n" + e.InnerException.Message);
                }

                if (_service != null)
                {
                    _service.Abort();
                }
            }
            catch (TimeoutException e)
            {
                Console.WriteLine(e.Message);

                if (_service != null)
                {
                    _service.Abort();
                }
            }
            catch (Exception e)
            {
                // Ignore fault exceptions that we already caught.

                if (!(e.InnerException is FaultException))
                {
                    Console.WriteLine(e.Message);
                }

                if (_service != null)
                {
                    _service.Abort();
                }
            }
        }


        // Add keywords to the specified ad group. 

        static long[] AddKeywords(long accountId, long adGroupId)
        {
            var request = new AddKeywordsRequest();

            // Specify the keywords. This example creates objects for the
            // Brand-A Gloves keyword and specifies an exact match bid for
            // one and a phrase match bid for the other. Neither keyword
            // bid on the broad match type.

            var keywords = new[] {
                new Keyword {
                    BroadMatchBid = null,
                    ExactMatchBid = new Bid { Amount = .47 },
                    Param2 = "10% Off",
                    PhraseMatchBid = null,
                    Text = "Brand-A Gloves"
                },
                new Keyword {
                    BroadMatchBid = null,
                    ExactMatchBid = null,
                    Param2 = "10% Off",
                    PhraseMatchBid = new Bid { Amount = null }, // Use the ad group's default bid value
                    Text = "Brand-A Gloves"
                }
            };

            // Set the header information.

            request.UserName = UserName;
            request.Password = Password;
            request.DeveloperToken = DeveloperToken;
            request.CustomerAccountId = accountId.ToString(CultureInfo.InvariantCulture);

            // Set the request information.

            request.AdGroupId = adGroupId;
            request.Keywords = keywords; 

            try
            {
                return _service.AddKeywords(request).KeywordIds;
            }
            // Campaign Management service operations can throw AdApiFaultDetail.
            catch (FaultException<AdApiFaultDetail> fault)
            {
                // Log this fault.

                Console.WriteLine("The operation failed with the following faults:\n");

                // If the AdApiError array is not null, the following are examples of error codes that may be found.
                foreach (AdApiError error in fault.Detail.Errors)
                {
                    Console.WriteLine("AdApiError");
                    Console.WriteLine("Code: {0}\nError Code: {1}\nMessage: {2}\n", error.Code, error.ErrorCode, error.Message);

                    switch (error.Code)
                    {
                        case 0:     // InternalError
                            break;
                        case 105:   // InvalidCredentials
                            break;
                        case 117:   // CallRateExceeded
                            break;
                        default:
                            Console.WriteLine("Please see MSDN documentation for more details about the error code output above.");
                            break;
                    }
                }

                throw new Exception("", fault);
            }
            // Some Campaign Management service operations such as AddKeywords can throw EditorialApiFaultDetail.
            catch (FaultException<EditorialApiFaultDetail> fault)
            {
                // Log this fault.

                Console.WriteLine("The operation failed with the following faults:\n");

                // If the BatchError array is not null, the following are examples of error codes that may be found.
                foreach (BatchError error in fault.Detail.BatchErrors)
                {
                    Console.WriteLine("BatchError at Index: {0}", error.Index);
                    Console.WriteLine("Code: {0}\nError Code: {1}\nMessage: {2}\n", error.Code, error.ErrorCode, error.Message);
                    
                    switch (error.Code)
                    {
                        case 0:     // InternalError
                            break;
                        case 1515:  // CampaignServiceBidAmountsLessThanFloorPrice
                            break;
                        case 1516:  // CampaignServiceBidAmountsGreaterThanCeilingPrice
                            break;
                        case 1541:  // CampaignServiceMultipleKeywordBidTypesNotAllowed
                            break;
                        case 1542:  // CampaignServiceKeywordAndMatchTypeCombinationAlreadyExists
                            break;
                        case 1543:  // CampaignServiceKeywordBidRequired
                            break;
                        case 1544:  // CampaignServiceKeywordZeroBidAmountNotAllowed
                            break;
                        default:
                            Console.WriteLine("Please see MSDN documentation for more details about the error code output above.");
                            break;
                    }
                }

                // If the EditorialError array is not null, the following are examples of error codes that may be found.
                foreach (EditorialError error in fault.Detail.EditorialErrors)
                {
                    Console.WriteLine("EditorialError at Index: {0}", error.Index);
                    Console.WriteLine("Code: {0}\nError Code: {1}\nMessage: {2}\n", error.Code, error.ErrorCode, error.Message);
                    Console.WriteLine("Appealable: {0}\nDisapproved Text: {1}\nCountry: {2}\n", error.Appealable, error.DisapprovedText, error.PublisherCountry);

                    switch (error.Code)
                    {
                        case 0:     // InternalError
                            break;
                        default:
                            Console.WriteLine("Please see MSDN documentation for more details about the error code output above.");
                            break;
                    }
                }

                // If the OperationError array is not null, the following are examples of error codes that may be found.
                foreach (OperationError error in fault.Detail.OperationErrors)
                {
                    Console.WriteLine("OperationError");
                    Console.WriteLine("Code: {0}\nError Code: {1}\nMessage: {2}\n", error.Code, error.ErrorCode, error.Message);

                    switch (error.Code)
                    {
                        case 0:     // InternalError
                            break;
                        case 106:   // UserIsNotAuthorized
                            break;
                        case 1102:  // CampaignServiceInvalidAccountId
                            break;
                        case 1030:  // CampaignServiceAccountIdHasToBeSpecified
                            break;
                        case 1201:  // CampaignServiceInvalidAdGroupId
                            break;
                        case 1505:  // CampaignServiceKeywordsArrayShouldNotBeNullOrEmpty
                            break;
                        default:
                            Console.WriteLine("Please see MSDN documentation for more details about the error code output above.");
                            break;
                    }
                }

                throw new Exception("", fault);
            }
        }

        // A keyword object can specify only one match-type bid value.
        // Figure out which bid is set and return the match type and 
        // bid value. 
        
        // If the bid Amount is null, that indicates that the ad group's 
        // bid value is used. To catch this case in the calling method, 
        // we're setting the bid to 0.0 which is not a valid bid value.

        private static string GetBidType(Keyword keyword, out double bid)
        {
            string bidType;

            if (keyword.ExactMatchBid != null)
            {
                bidType = "Exact";
                bid = keyword.ExactMatchBid.Amount ?? 0.0;
            }
            else if (keyword.PhraseMatchBid != null)
            {
                bidType = "Phrase";
                bid = keyword.PhraseMatchBid.Amount ?? 0.0;
            }
            else if (keyword.BroadMatchBid != null)
            {
                bidType = "Broad";
                bid = keyword.BroadMatchBid.Amount ?? 0.0;
            }
            else
            {
                bidType = "Content";
                bid = keyword.ContentMatchBid.Amount ?? 0.0;
            }

            return bidType;
        }

        // Specify the keyword's destination URL. The keyword's destination URL
        // overrides the destination URL specified at the ad level. Using the
        // keyword's destination URL is preferred to using Keyword.Param1.

        static void SetKeywordDestinationUrl(long accountId, long adGroupId, long[] keywordIds, string destinationUrl)
        {
            var request = new SetDestinationUrlToKeywordsRequest();

            // Loop through the list of keyword IDs and build
            // the keyword destination URL objects.

            var keywordUrls = new KeywordDestinationUrl[keywordIds.Length];

            for (int i = 0; i < keywordIds.Length; i++)
            {
                keywordUrls[i] = new KeywordDestinationUrl
                {
                    KeywordId = keywordIds[i],
                    DestinationUrl = destinationUrl
                };
            }

            // Set the header information.

            request.UserName = UserName;
            request.Password = Password;
            request.DeveloperToken = DeveloperToken;
            request.CustomerAccountId = accountId.ToString(CultureInfo.InvariantCulture);
            
            
            // Set the request information.

            request.AdGroupId = adGroupId;
            request.KeywordDestinationUrls = keywordUrls;

            try
            {
                _service.SetDestinationUrlToKeywords(request);
            }
            // Campaign Management service operations can throw AdApiFaultDetail.
            catch (FaultException<AdApiFaultDetail> fault)
            {
                // Log this fault.

                Console.WriteLine("The operation failed with the following faults:\n");

                // If the AdApiError array is not null, the following are examples of error codes that may be found.
                foreach (AdApiError error in fault.Detail.Errors)
                {
                    Console.WriteLine("AdApiError");
                    Console.WriteLine("Code: {0}\nError Code: {1}\nMessage: {2}\n", error.Code, error.ErrorCode, error.Message);

                    switch (error.Code)
                    {
                        case 0:     // InternalError
                            break;
                        case 105:   // InvalidCredentials
                            break;
                        default:
                            Console.WriteLine("Please see MSDN documentation for more details about the error code output above.");
                            break;
                    }
                }

                throw new Exception("", fault);
            }
            // Some Campaign Management service operations such as SetDestinationUrlToKeywords can throw EditorialApiFaultDetail.
            catch (FaultException<EditorialApiFaultDetail> fault)
            {
                // Log this fault.

                Console.WriteLine("The operation failed with the following faults:\n");

                foreach (BatchError error in fault.Detail.BatchErrors)
                {
                    Console.WriteLine("BatchError at Index: {0}", error.Index);
                    Console.WriteLine("Code: {0}\nError Code: {1}\nMessage: {2}\n", error.Code, error.ErrorCode, error.Message);

                    switch (error.Code)
                    {
                        case 0:     // InternalError
                            break;
                        case 1501:  // CampaignServiceInvalidKeywordId
                            break;
                        case 1502:  // CampaignServiceDuplicateInKeywordIds
                            break;
                        case 1534:  // CampaignServiceUpdateKeywordEmpty
                            break;
                        default:
                            Console.WriteLine("Please see MSDN documentation for more details about the error code output above.");
                            break;
                    }
                }

                foreach (EditorialError error in fault.Detail.EditorialErrors)
                {
                    Console.WriteLine("EditorialError at Index: {0}", error.Index);
                    Console.WriteLine("Code: {0}\nError Code: {1}\nMessage: {2}\n", error.Code, error.ErrorCode, error.Message);
                    Console.WriteLine("Appealable: {0}\nDisapproved Text: {1}\nCountry: {2}\n", error.Appealable, error.DisapprovedText, error.PublisherCountry);

                    switch (error.Code)
                    {
                        case 0:     // InternalError
                            break;
                        default:
                            Console.WriteLine("Please see MSDN documentation for more details about the error code output above.");
                            break;
                    }
                }

                foreach (OperationError error in fault.Detail.OperationErrors)
                {
                    Console.WriteLine("OperationError");
                    Console.WriteLine("Code: {0}\nError Code: {1}\nMessage: {2}\n", error.Code, error.ErrorCode, error.Message);

                    switch (error.Code)
                    {
                        case 0:     // InternalError
                            break;
                        case 106:   // UserIsNotAuthorized
                            break;
                        case 1102:  // CampaignServiceInvalidAccountId
                            break;
                        case 1030:  // CampaignServiceAccountIdHasToBeSpecified
                            break;
                        case 1201:  // CampaignServiceInvalidAdGroupId
                            break;
                        case 1549:  // CampaignServiceKeywordDestinationUrlsArrayShouldNotBeNullOrEmpty
                            break;
                        default:
                            Console.WriteLine("Please see MSDN documentation for more details about the error code output above.");
                            break;
                    }
                }

                throw new Exception("", fault);
            }
        }

        // Print the details of the keywords that were added. 

        static void PrintKeywords(long customerId, long accountId, long adGroupId, long[] keywordIds)
        {
            EditorialReasonCollection[] editorialCollection = null;

            var request = new GetKeywordsByIdsRequest
                {
                    // Set the header information.
                    UserName = UserName,
                    Password = Password,
                    DeveloperToken = DeveloperToken,
                    CustomerAccountId = accountId.ToString(CultureInfo.InvariantCulture),

                    // Set the request information.
                    AdGroupId = adGroupId,
                    KeywordIds = keywordIds
                };

            try
            {
                GetKeywordsByIdsResponse response = _service.GetKeywordsByIds(request);

                for (int i = 0; i < response.Keywords.Length; i++)
                {
                    Keyword keyword = response.Keywords[i];

                    if (keyword != null)
                    {
                        Console.WriteLine("Keyword: " + keyword.Text);
                        Console.WriteLine("Id: " + keyword.Id);
                        double bid;
                        Console.WriteLine("Match type: " + GetBidType(keyword, out bid));

                        // GetBidType sets the bid to 0.0 if the match type's
                        // bid amount is set to null, which indicates to 
                        // use the ad group's default bid for that match type.

                        if (bid > 0.0)
                        {
                            Console.WriteLine("Bid: {0:C} ", bid);
                        }
                        else
                        {
                            Console.WriteLine("Bid: Ad group default bid");
                        }

                        if (keyword.Id != null)
                            Console.WriteLine("Destination URL: " + GetKeywordDestinationUrl(accountId, adGroupId, (long)keyword.Id));
                        Console.WriteLine("Status: " + keyword.Status);
                        Console.WriteLine("Editorial Status: {0}",
                            (keyword.EditorialStatus == KeywordEditorialStatus.Inactive) ?
                                "Under review" : keyword.EditorialStatus.ToString()
                            );

                        // If the keyword failed editorial review, find out why and which 
                        // publisher countries were affected.

                        if (keyword.EditorialStatus == KeywordEditorialStatus.Disapproved)
                        {
                            if (keyword.Id != null)
                                editorialCollection = GetEditorialReasons(
                                    customerId,
                                    accountId,
                                    new[] { (long)keyword.Id },
                                    EntityType.Keyword);

                            if (editorialCollection != null)
                            {
                                Console.WriteLine("  Appeal status: " + editorialCollection[0].AppealStatus);

                                foreach (EditorialReason editorialReason in editorialCollection[0].Reasons)
                                {
                                    Console.WriteLine("  Reason code: " + editorialReason.ReasonCode);
                                    Console.WriteLine("  Term : " + editorialReason.Term);
                                    Console.WriteLine("  Location : " + editorialReason.Location);
                                    Console.Write("  Publisher countries: ");

                                    int j = 1;
                                    int length = editorialReason.PublisherCountries.Length;
                                    foreach (string country in editorialReason.PublisherCountries)
                                    {
                                        Console.Write("{0}{1}", country, (j++ < length) ? ", " : "\n");
                                    }
                                }
                            }
                        }

                        Console.WriteLine();
                    }
                    else
                    {
                        Console.WriteLine("Keyword {0} is not valid.\n", keywordIds[i]);
                    }
                }
            }
            // Campaign Management service operations can throw AdApiFaultDetail.
            catch (FaultException<AdApiFaultDetail> fault)
            {
                // Log this fault.

                Console.WriteLine("The operation failed with the following faults:\n");

                // If the AdApiError array is not null, the following are examples of error codes that may be found.
                foreach (AdApiError error in fault.Detail.Errors)
                {
                    Console.WriteLine("AdApiError");
                    Console.WriteLine("Code: {0}\nError Code: {1}\nMessage: {2}\n", error.Code, error.ErrorCode, error.Message);

                    switch (error.Code)
                    {
                        case 0:     // InternalError
                            break;
                        case 105:   // InvalidCredentials
                            break;
                        default:
                            Console.WriteLine("Please see MSDN documentation for more details about the error code output above.");
                            break;
                    }
                }

                throw new Exception("", fault);
            }
            // Campaign Management service operations can throw ApiFaultDetail.
            catch (FaultException<ApiFaultDetail> fault)
            {
                // Log this fault.

                Console.WriteLine("The operation failed with the following faults:\n");

                // If the BatchError array is not null, the following are examples of error codes that may be found.
                foreach (BatchError error in fault.Detail.BatchErrors)
                {
                    Console.WriteLine("BatchError at Index: {0}", error.Index);
                    Console.WriteLine("Code: {0}\nError Code: {1}\nMessage: {2}\n", error.Code, error.ErrorCode, error.Message);

                    switch (error.Code)
                    {
                        case 0:     // InternalError
                            break;
                        default:
                            Console.WriteLine("Please see MSDN documentation for more details about the error code output above.");
                            break;
                    }
                }

                // If the OperationError array is not null, the following are examples of error codes that may be found.
                foreach (OperationError error in fault.Detail.OperationErrors)
                {
                    Console.WriteLine("OperationError");
                    Console.WriteLine("Code: {0}\nError Code: {1}\nMessage: {2}\n", error.Code, error.ErrorCode, error.Message);

                    switch (error.Code)
                    {
                        case 0:     // InternalError
                            break;
                        case 106:   // UserIsNotAuthorized
                            break;
                        case 1102:  // CampaignServiceInvalidAccountId
                            break;
                        default:
                            Console.WriteLine("Please see MSDN documentation for more details about the error code output above.");
                            break;
                    }
                }

                throw new Exception("", fault);
            }
        }

        // Get the keyword's destination URL. 

        static string GetKeywordDestinationUrl(long accountId, long adGroupId, long keywordId)
        {
            var request = new GetDestinationUrlByKeywordIdsRequest
                {
                    // Set the header information.
                    UserName = UserName,
                    Password = Password,
                    DeveloperToken = DeveloperToken,
                    CustomerAccountId = accountId.ToString(CultureInfo.InvariantCulture),

                    // Set the request information.
                    AdGroupId = adGroupId,
                    KeywordIds = new[] {keywordId}
                };

            try
            {
                // Because we requested the destination URL of a single keyword,
                // return only the first item.

                return _service.GetDestinationUrlByKeywordIds(request).DestinationUrls[0];
            }
                // Campaign Management service operations can throw AdApiFaultDetail.
            catch (FaultException<AdApiFaultDetail> fault)
            {
                // Log this fault.

                Console.WriteLine("The operation failed with the following faults:\n");

                // If the AdApiError array is not null, the following are examples of error codes that may be found.
                foreach (AdApiError error in fault.Detail.Errors)
                {
                    Console.WriteLine("AdApiError");
                    Console.WriteLine("Code: {0}\nError Code: {1}\nMessage: {2}\n", error.Code, error.ErrorCode, error.Message);

                    switch (error.Code)
                    {
                        case 0:     // InternalError
                            break;
                        case 105:   // InvalidCredentials
                            break;
                        default:
                            Console.WriteLine("Please see MSDN documentation for more details about the error code output above.");
                            break;
                    }
                }

                throw new Exception("", fault);
            }
            // Campaign Management service operations can throw ApiFaultDetail.
            catch (FaultException<ApiFaultDetail> fault)
            {
                // Log this fault.

                Console.WriteLine("The operation failed with the following faults:\n");

                // If the BatchError array is not null, the following are examples of error codes that may be found.
                foreach (BatchError error in fault.Detail.BatchErrors)
                {
                    Console.WriteLine("BatchError at Index: {0}", error.Index);
                    Console.WriteLine("Code: {0}\nError Code: {1}\nMessage: {2}\n", error.Code, error.ErrorCode, error.Message);

                    switch (error.Code)
                    {
                        case 0:     // InternalError
                            break;
                        default:
                            Console.WriteLine("Please see MSDN documentation for more details about the error code output above.");
                            break;
                    }
                }

                // If the OperationError array is not null, the following are examples of error codes that may be found.
                foreach (OperationError error in fault.Detail.OperationErrors)
                {
                    Console.WriteLine("OperationError");
                    Console.WriteLine("Code: {0}\nError Code: {1}\nMessage: {2}\n", error.Code, error.ErrorCode, error.Message);

                    switch (error.Code)
                    {
                        case 0:     // InternalError
                            break;
                        case 106:   // UserIsNotAuthorized
                            break;
                        case 1102:  // CampaignServiceInvalidAccountId
                            break;
                        default:
                            Console.WriteLine("Please see MSDN documentation for more details about the error code output above.");
                            break;
                    }
                }

                throw new Exception("", fault);
            }
        }

        // Gets the reasons why the specified keyword failed editorial review.

        private static EditorialReasonCollection[] GetEditorialReasons(
            long customerId,
            long accountId,
            long[] keywordIds,
            EntityType entityType)
        {
            var request = new GetEditorialReasonsByIdsRequest
                {
                    // Set the header information.
                    UserName = UserName,
                    Password = Password,
                    DeveloperToken = DeveloperToken,
                    CustomerId = customerId.ToString(CultureInfo.InvariantCulture),
                    CustomerAccountId = accountId.ToString(CultureInfo.InvariantCulture),

                    // Set the request information.
                    AccountId = accountId,
                    EntityIds = keywordIds,
                    EntityType = entityType
                };

            try
            {
                return _service.GetEditorialReasonsByIds(request).EditorialReasons;
            }
            // Campaign Management service operations can throw AdApiFaultDetail.
            catch (FaultException<AdApiFaultDetail> fault)
            {
                // Log this fault.

                Console.WriteLine("The operation failed with the following faults:\n");

                // If the AdApiError array is not null, the following are examples of error codes that may be found.
                foreach (AdApiError error in fault.Detail.Errors)
                {
                    Console.WriteLine("AdApiError");
                    Console.WriteLine("Code: {0}\nError Code: {1}\nMessage: {2}\n", error.Code, error.ErrorCode, error.Message);

                    switch (error.Code)
                    {
                        case 0:     // InternalError
                            break;
                        case 105:   // InvalidCredentials
                            break;
                        default:
                            Console.WriteLine("Please see MSDN documentation for more details about the error code output above.");
                            break;
                    }
                }

                throw new Exception("", fault);
            }
            // Campaign Management service operations can throw ApiFaultDetail.
            catch (FaultException<ApiFaultDetail> fault)
            {
                // Log this fault.

                Console.WriteLine("The operation failed with the following faults:\n");

                // If the BatchError array is not null, the following are examples of error codes that may be found.
                foreach (BatchError error in fault.Detail.BatchErrors)
                {
                    Console.WriteLine("BatchError at Index: {0}", error.Index);
                    Console.WriteLine("Code: {0}\nError Code: {1}\nMessage: {2}\n", error.Code, error.ErrorCode, error.Message);

                    switch (error.Code)
                    {
                        case 0:     // InternalError
                            break;
                        default:
                            Console.WriteLine("Please see MSDN documentation for more details about the error code output above.");
                            break;
                    }
                }

                // If the OperationError array is not null, the following are examples of error codes that may be found.
                foreach (OperationError error in fault.Detail.OperationErrors)
                {
                    Console.WriteLine("OperationError");
                    Console.WriteLine("Code: {0}\nError Code: {1}\nMessage: {2}\n", error.Code, error.ErrorCode, error.Message);

                    switch (error.Code)
                    {
                        case 0:     // InternalError
                            break;
                        case 106:   // UserIsNotAuthorized
                            break;
                        case 212:   // CampaignServiceEntityTypeNotSupported
                            break;
                        case 1029:  // CampaignServiceCustomerIdHasToBeSpecified
                            break;
                        case 1030:  // CampaignServiceAccountIdHasToBeSpecified
                            break;
                        case 1102:  // CampaignServiceInvalidAccountId
                            break;
                        default:
                            Console.WriteLine("Please see MSDN documentation for more details about the error code output above.");
                            break;
                    }
                }

                throw new Exception("", fault);
            }
        }
    }
}

Community Additions

Show:
© 2014 Microsoft