Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Campaign Targeting Soap Client Error (Unmarshalling Error: cvc-elt.4.3) #473

Closed
james-waring opened this issue Mar 26, 2018 · 4 comments
Closed
Assignees
Labels

Comments

@james-waring
Copy link

Hello,

I am trying to add a radius location to a campaign using the api and i am getting a soap error.

Fault String: Unmarshalling Error: cvc-elt.4.3: Type 'ns1:ConstantOperand' is not validly derived from the type definition, 'string', of element 'ns1:FunctionArgumentOperand.Type'.
Fault Code: soap:Client

googleads/googleads-php-lib/src/Google/AdsApi/Common/AdsSoapClient.php
Line 152

I have used the code from Add Campaign Targeting Criteria as an example but i still get the error.

My Code

$radius = new ConstantOperand();
$radius->setType(ConstantOperandConstantType::DOUBLE);
$radius->setUnit(ConstantOperandUnit::MILES);
$radius->setDoubleValue(5.0);

$distance = new LocationExtensionOperand($radius);

$locationGroup = new LocationGroups();
$locationGroup->setFeedId(1006539);
$locationGroup->setMatchingFunction(new MatchingFunction(FunctionOperator::IDENTITY, [$distance]));

$campaignCriteria[] =
    new CampaignCriterion($campaign->google_campagin_id, null, $locationGroup);

$operations = [];
foreach ($campaignCriteria as $campaignCriterion) {
    $operation = new CampaignCriterionOperation();
    $operation->setOperator(Operator::ADD);
    $operation->setOperand($campaignCriterion);
    $operations[] = $operation;
}

$result = $campaignCriterionService->mutate($operations);

I know my campaign criterion service is correct because i can set languages, ad schedules and ip blocks using the same service.

I have tried this code in both v201710 and v201802 and i get the same error. I am unsure if it is my code that is at fault our something at your end.

Any help would be amazing.

James

@fiboknacky fiboknacky self-assigned this Mar 27, 2018
@fiboknacky fiboknacky added the P2 label Mar 27, 2018
@fiboknacky
Copy link
Member

Hi James,

Could you please post your full code snippet so I can reproduce?

Best,
Knack

@james-waring
Copy link
Author

Hello,

I have took the example from AddCampaignTargetingCriteria.php and slimmed it down to what i want it to do. All i have done to this example is removed some of the parts i didnt want. I haven't edited any of the location code.

I have ran this script and it still gives me the same error.

SoapFault with message 'Unmarshalling Error: cvc-elt.4.3: Type 'ns1:ConstantOperand' is not validly derived from the type definition, 'string', of element 'ns1:FunctionArgumentOperand.Type'. '

I because i ran this in the console it has given me a soap log i think. see below. I have removed my client id from the log and replaced it with ##CLIENT_ID_REMOVED## ;

[2018-03-28 19:26:50] AW_SOAP.WARNING: clientCustomerId=##CLIENT_ID_REMOVED## operations= service=CampaignCriterionService method=mutate responseTime= requestId= server=adwords.google.com isFault=1 faultMessage=Unmarshalling Error: cvc-elt.4.3: Type 'ns1:ConstantOperand' is not validly derived from the type definition, 'string', of element 'ns1:FunctionArgumentOperand.Type'.
[2018-03-28 19:26:50] AW_SOAP.NOTICE: POST /api/adwords/cm/v201802/CampaignCriterionService?wsdl HTTP/1.1
Host: adwords.google.com
Connection: close
User-Agent: PHP-SOAP/7.1.7
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Content-Length: 1249
Authorization: REDACTED

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="https://adwords.google.com/api/adwords/cm/v201802" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Header><ns1:RequestHeader><ns1:clientCustomerId>##CLIENT_ID_REMOVED##</ns1:clientCustomerId><ns1:developerToken>REDACTED</ns1:developerToken><ns1:userAgent>unknown (AwApi-PHP, googleads-php-lib/33.1.0, PHP/7.1.7)</ns1:userAgent><ns1:validateOnly>false</ns1:validateOnly><ns1:partialFailure>false</ns1:partialFailure></ns1:RequestHeader></SOAP-ENV:Header><SOAP-ENV:Body><ns1:mutate><ns1:operations><ns1:operator>ADD</ns1:operator><ns1:operand><ns1:campaignId>1336314653</ns1:campaignId><ns1:criterion xsi:type="ns1:LocationGroups"><ns1:feedId>1006539</ns1:feedId><ns1:matchingFunction><ns1:operator>IDENTITY</ns1:operator><ns1:lhsOperand xsi:type="ns1:LocationExtensionOperand"><ns1:FunctionArgumentOperand.Type xsi:type="ns1:ConstantOperand"><ns1:type>DOUBLE</ns1:type><ns1:unit>MILES</ns1:unit><ns1:doubleValue>5</ns1:doubleValue></ns1:FunctionArgumentOperand.Type></ns1:lhsOperand></ns1:matchingFunction></ns1:criterion></ns1:operand></ns1:operations></ns1:mutate></SOAP-ENV:Body></SOAP-ENV:Envelope>

HTTP/1.1 500 Internal Server Error
Content-Type: text/xml; charset=UTF-8
Date: Wed, 28 Mar 2018 19:26:50 GMT
Expires: Wed, 28 Mar 2018 19:26:50 GMT
Cache-Control: private, max-age=0
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Alt-Svc: hq=":443"; ma=2592000; quic=51303432; quic=51303431; quic=51303339; quic=51303335,quic=":443"; ma=2592000; v="42,41,39,35"
Accept-Ranges: none
Vary: Accept-Encoding
Connection: close

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><soap:Fault><faultcode>soap:Client</faultcode><faultstring>Unmarshalling Error: cvc-elt.4.3: Type 'ns1:ConstantOperand' is not validly derived from the type definition, 'string', of element 'ns1:FunctionArgumentOperand.Type'. </faultstring></soap:Fault></soap:Body></soap:Envelope>

The full code i ran, with the soap error.

<?php

// namespace Google\AdsApi\Examples\AdWords\v201802\Targeting;
namespace App\Models\Automation;

use Google\AdsApi\Common\OAuth2TokenBuilder;
use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201802\cm\CampaignCriterion;
use Google\AdsApi\AdWords\v201802\cm\CampaignCriterionOperation;
use Google\AdsApi\AdWords\v201802\cm\CampaignCriterionService;
use Google\AdsApi\AdWords\v201802\cm\ConstantOperand;
use Google\AdsApi\AdWords\v201802\cm\ConstantOperandConstantType;
use Google\AdsApi\AdWords\v201802\cm\ConstantOperandUnit;
use Google\AdsApi\AdWords\v201802\cm\FunctionOperator;
use Google\AdsApi\AdWords\v201802\cm\Keyword;
use Google\AdsApi\AdWords\v201802\cm\KeywordMatchType;
use Google\AdsApi\AdWords\v201802\cm\Language;
use Google\AdsApi\AdWords\v201802\cm\Location;
use Google\AdsApi\AdWords\v201802\cm\LocationExtensionOperand;
use Google\AdsApi\AdWords\v201802\cm\LocationGroups;
use Google\AdsApi\AdWords\v201802\cm\MatchingFunction;
use Google\AdsApi\AdWords\v201802\cm\NegativeCampaignCriterion;
use Google\AdsApi\AdWords\v201802\cm\Operator;

/**
 * This example adds various types of targeting criteria to a campaign.
 * To get campaigns, run BasicOperations/GetCampaigns.php.
 */
class AddCampaignTargetingCrtieria
{
    const CAMPAIGN_ID = 'CAMPAIGN_ID';
    // Replace the value below with the ID of a feed that has been configured for
    // location targeting, meaning it has an ENABLED FeedMapping with
    // criterionType of 77. Feeds linked to a GMB account automatically have this
    // FeedMapping. If you don't have such a feed, set this value to null.
    const LOCATION_FEED_ID = '1006539';

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        $campaignId,
        $locationFeedId
    ) {
        $campaignCriterionService = $adWordsServices->get($session, CampaignCriterionService::class);
        $campaignCriteria = [];

        if ($locationFeedId !== null) {
            // Distance targeting. Area of 10 miles around targets above.
            $radius = new ConstantOperand();
            $radius->setType(ConstantOperandConstantType::DOUBLE);
            $radius->setUnit(ConstantOperandUnit::MILES);
            $radius->setDoubleValue(5.0);
            $distance = new LocationExtensionOperand($radius);
            $locationGroup = new LocationGroups();
            $locationGroup->setFeedId(intval($locationFeedId));
            $locationGroup->setMatchingFunction(
                new MatchingFunction(FunctionOperator::IDENTITY, [$distance])
            );
            $campaignCriteria[] = new CampaignCriterion($campaignId, null, $locationGroup);
        }

        $operations = [];
        foreach ($campaignCriteria as $campaignCriterion) {
            $operation = new CampaignCriterionOperation();
            $operation->setOperator(Operator::ADD);
            $operation->setOperand($campaignCriterion);
            $operations[] = $operation;
        }

        $result = $campaignCriterionService->mutate($operations);
        // Print out some information about added campaign criteria.
        foreach ($result->getValue() as $campaignCriterion) {
            printf(
                "Campaign targeting criterion with ID %d and type '%s' was added.\n",
                $campaignCriterion->getCriterion()->getId(),
                $campaignCriterion->getCriterion()->getType()
            );
        }
    }
    public static function main()
    {
        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new OAuth2TokenBuilder())
            ->fromFile(base_path() . '/config/google/engaged_adsapi_php.ini')
            ->build();

        $session = (new AdWordsSessionBuilder())
            ->fromFile(base_path() . '/config/google/engaged_adsapi_php.ini')
            ->withOAuth2Credential($oAuth2Credential)
            ->withClientCustomerId('ClientCustomerId')
            ->build();

        self::runExample(
            new AdWordsServices(),
            $session,
            intval(self::CAMPAIGN_ID),
            self::LOCATION_FEED_ID
        );
    }
}

James

@fiboknacky
Copy link
Member

Hello James,

I found that there is a mistake in our code, which I will push the change in the later release.
For now, you can change the line that instantiates LocationExtensionOperand like this:

    $distance = new LocationExtensionOperand();
    $distance->setRadius($radius);

Best,
Knack

@fiboknacky
Copy link
Member

Fixed with release v35.0.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants