Editorial Review and Appeals in Java

The following example shows how to find keywords that have been editorially rejected, print the reasons for the rejections, and then appeal the rejections using the following Campaign Management service operations.

This example has been developed and run within the environment described in Getting Started Using Java 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.

// This example shows how to find keywords that have been editorially
// rejected, print the reasons for the rejections, and then appeal the
// rejections.

package campaign;

import java.rmi.*;

import bingads.campaignmanagement.*;
import bingads.campaignmanagement.adapi.*;
//import bingads.campaignmanagement.datacontracts.*;

/**
 *
 */
public class AppealKeywordRejections {

    private static String _namespace = null;
    private static BasicHttpBinding_ICampaignManagementServiceStub _service = null;

    // API credentials.

    private static String m_password = "<passwordgoeshere>";
    private static String m_username = "<usernamegoeshere>";
    private static String m_token = "<devtokengoeshere>";

    // Advertiser's account ID and customer ID.

    private static long m_accountId = <accountidgoeshere>;
    private static long m_customerId = <customeridgoeshere>;

    // The ID of the ad group that contains the keywords to appeal.

    private static long m_adGroupId = <adgroupidgoeshere>;


    /**
     *
     */
    public static void main(String[] args) {
        CampaignManagementServiceLocator locator = null;
        long[] ids = null;
        EditorialReasonCollection[] collections = null;

        try
        {
            locator = new CampaignManagementServiceLocator();
            _namespace = locator.getServiceName().getNamespaceURI();
            _service = (BasicHttpBinding_ICampaignManagementServiceStub) locator.getBasicHttpBinding_ICampaignManagementService();

            // Set the header properties.

            _service.clearHeaders();
            _service.setHeader(_namespace, "CustomerId", m_customerId);
            _service.setHeader(_namespace, "CustomerAccountId", m_accountId);
            _service.setHeader(_namespace, "DeveloperToken", m_token);
            _service.setHeader(_namespace, "UserName", m_username);
            _service.setHeader(_namespace, "Password", m_password);

            ids = GetKeywordsThatFailedReview(m_adGroupId);

            if (null == ids)
            {
                System.out.printf("Ad group %d does not contain keywords that failed editorial review.\n",
                    m_adGroupId);
            }
            else
            {
                collections = GetReasonsForFailures(m_accountId, ids);

                for (EditorialReasonCollection collection : collections)
                {
                    System.out.printf("Keyword %d failed editorial review for the following reasons.\n",
                        collection.getAdOrKeywordId());

                    for (EditorialReason reason : collection.getReasons())
                    {
                        System.out.println("  Reason code: " + reason.getReasonCode());
                        System.out.println("  Flagged keyword component: " + reason.getLocation());
                        System.out.println("  Flagged term: " + reason.getTerm());
                        System.out.print("  Publisher countries: ");

                        int j = 1;
                        int length = reason.getPublisherCountries().length;
                        for (String country : reason.getPublisherCountries())
                        {
                            System.out.printf("%s%s", country, (j++ < length) ? ", " : "\n");
                        }
                    }

                    if (collection.getAppealStatus().equals(AppealStatus.Appealable))
                    {
                        System.out.println("Appealing review.");
                        String justification = "My justification text.";
                        AppealReview(new long[] { collection.getAdOrKeywordId() }, justification);
                    }
                    else if (collection.getAppealStatus().equals(AppealStatus.AppealPending))
                    {
                        System.out.println("Review is being appealed.");
                    }
                    else
                    {
                        System.out.println("Review cannot be appealed.");
                    }

                    System.out.println();
                }
            }
        }
        catch (RemoteException e)
        {
            System.out.println("Service communication error encountered: ");
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
        catch (Exception e)
        {
            // Ignore fault exceptions that we already caught.

            if ( e.getCause() instanceof AdApiFaultDetail ||
                 e.getCause() instanceof EditorialApiFaultDetail ||
                 e.getCause() instanceof ApiFaultDetail )
            {
                ;
            }
            else
            {
                System.out.println("Error encountered: ");
                System.out.println(e.getMessage());
                e.printStackTrace();
            }
        }
    }

    // Gets the IDs of the keywords that failed editorial review.

    private static long[] GetKeywordsThatFailedReview(long adGroupId)  throws RemoteException, Exception
    {
        GetKeywordsByEditorialStatusRequest request = new GetKeywordsByEditorialStatusRequest();
        GetKeywordsByEditorialStatusResponse response = null;
        long[] ids = null;
        int count = 0;

        // Set the request information.

        request.setAdGroupId(adGroupId);
        request.setEditorialStatus(KeywordEditorialStatus.Disapproved);

        try
        {
            response = _service.getKeywordsByEditorialStatus(request);

            // Just need to return the IDs.

            if ((count = response.getKeywords().length) > 0)
            {
                ids = new long[count];

                for (int i = 0; i < count; i++)
                {
                    ids[i] = (long)response.getKeywords()[i].getId();
                }
            }
        }
        catch (AdApiFaultDetail fault)
        {
            // Log this fault.

            System.out.println("GetKeywordsByEditorialStatus failed with the following faults:\n");

            for (AdApiError error : fault.getErrors())
            {
                if (105 == error.getCode()) //  InvalidCredentials
                {
                    System.out.println("The specified credentials are not valid " +
                        "or the account is inactive.\n");
                }
                else
                {
                    System.out.printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n\n",
                        error.getErrorCode(), error.getCode(), error.getMessage(), error.getDetail());
                }
            }

            throw new Exception("", fault);
        }
        catch (ApiFaultDetail fault)
        {
            // Log this fault.

            System.out.println("GetKeywordsByEditorialStatus failed with the following faults:\n");

            for (OperationError error : fault.getOperationErrors())
            {
                switch (error.getCode())
                {
                    case 1201: //  CampaignServiceInvalidAdGroupId
                        System.out.println("The ad group ID is not valid.\n");
                        break;

                    default:
                        System.out.printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n\n",
                            error.getErrorCode(), error.getCode(), error.getMessage(), error.getDetails());
                        break;
                }
            }

            for (BatchError error : fault.getBatchErrors())
            {
                switch (error.getCode())
                {
                    default:
                        System.out.printf("Error code: %s (%d)\nIndex: %d\nMessage: %s\nDetail: %s\n\n",
                                error.getErrorCode(), error.getCode(), error.getIndex(), error.getMessage(), error.getDetails());
                        break;
                }
            }

            throw new Exception("", fault);
        }

        return ids;
    }

    // Gets the reasons why the keywords failed editorial review.

    private static EditorialReasonCollection[] GetReasonsForFailures(long accountId, long[] ids)  throws RemoteException, Exception
    {
        GetEditorialReasonsByIdsRequest request = new GetEditorialReasonsByIdsRequest();
        GetEditorialReasonsByIdsResponse response = null;

        // Set the request information.

        request.setAccountId(accountId);
        request.setEntityIds(ids);
        request.setEntityType(EntityType.Keyword);

        try
        {
            response = _service.getEditorialReasonsByIds(request);
        }
        catch (AdApiFaultDetail fault)
        {
            // Log this fault.

            System.out.println("GetEditorialReasonsByIds failed with the following faults:\n");

            for (AdApiError error : fault.getErrors())
            {
                if (105 == error.getCode()) //  InvalidCredentials
                {
                    System.out.println("The specified credentials are not valid " +
                        "or the account is inactive.\n");
                }
                else
                {
                    System.out.printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n\n",
                        error.getErrorCode(), error.getCode(), error.getMessage(), error.getDetail());
                }
            }

            throw new Exception("", fault);
        }
        catch (ApiFaultDetail fault)
        {
            // Log this fault.

            System.out.println("GetEditorialReasonsByIds failed with the following faults:\n");

            for (OperationError error : fault.getOperationErrors())
            {
                switch (error.getCode())
                {
                    case 1029: //
                        System.out.println("The customer ID header element cannot be null or empty.\n");
                        break;

                    default:
                        System.out.printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n\n",
                            error.getErrorCode(), error.getCode(), error.getMessage(), error.getDetails());
                        break;
                }
            }

            for (BatchError error : fault.getBatchErrors())
            {
                switch (error.getCode())
                {
                    default:
                        System.out.printf("Error code: %s (%d)\nIndex: %d\nMessage: %s\nDetail: %s\n\n",
                                error.getErrorCode(), error.getCode(), error.getIndex(), error.getMessage(), error.getDetails());
                        break;
                }
            }

            throw new Exception("", fault);
        }

        return response.getEditorialReasons();
    }

    // Appeals the editorial rejections.

    private static void AppealReview(long[] ids, String justification)  throws RemoteException, Exception
    {
        AppealEditorialRejectionsRequest request = new AppealEditorialRejectionsRequest();
        AppealEditorialRejectionsResponse response = null;

        // Set the request information.

        request.setEntityIds(ids);
        request.setEntityType(EntityType.Keyword);
        request.setJustificationText(justification);

        try
        {
            response = _service.appealEditorialRejections(request);
        }
        catch (AdApiFaultDetail fault)
        {
            // Log this fault.

            System.out.println("AppealEditorialRejections failed with the following faults:\n");

            for (AdApiError error : fault.getErrors())
            {
                if (105 == error.getCode()) //  InvalidCredentials
                {
                    System.out.println("The specified credentials are not valid " +
                        "or the account is inactive.\n");
                }
                else
                {
                    System.out.printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n\n",
                        error.getErrorCode(), error.getCode(), error.getMessage(), error.getDetail());
                }
            }

            throw new Exception("", fault);
        }
        catch (ApiFaultDetail fault)
        {
            // Log this fault.

            System.out.println("AppealEditorialRejections failed with the following faults:\n");

            for (OperationError error : fault.getOperationErrors())
            {
                switch (error.getCode())
                {
                    default:
                        System.out.printf("Error code: %s (%d)\nMessage: %s\nDetail: %s\n\n",
                            error.getErrorCode(), error.getCode(), error.getMessage(), error.getDetails());
                        break;
                }
            }

            for (BatchError error : fault.getBatchErrors())
            {
                switch (error.getCode())
                {
                    default:
                        System.out.printf("Error code: %s (%d)\nIndex: %d\nMessage: %s\nDetail: %s\n\n",
                                error.getErrorCode(), error.getCode(), error.getIndex(), error.getMessage(), error.getDetails());
                        break;
                }
            }

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

Community Additions

Show: