google-ads-php icon indicating copy to clipboard operation
google-ads-php copied to clipboard

Update sitelink asset

Open shobha-procentris opened this issue 2 years ago • 5 comments

Hi,

Using the PHP library when we are trying to update the description of sitelink using PHP library

We are getting the following error

Array ( [type] => 1 [message] => Uncaught TypeError: Argument 1 passed to Google\Ads\GoogleAds\Util\FieldMasks::allSetFieldsOf() must be an instance of Google\Protobuf\Internal\Message, array given, called in /var/www/sites/psmedia/perfectstormmedia/tools/campaign-settings/sitelinks-new/sitelinkSettings.class.php on line 1039 and defined in /var/www/sites/psmedia/perfectstormmedia/tools/includes/api/google-ads-php/src/Google/Ads/GoogleAds/Util/FieldMasks.php:102 Stack trace: #0 /var/www/sites/psmedia/perfectstormmedia/tools/campaign-settings/sitelinks-new/sitelinkSettings.class.php(1039): Google\Ads\GoogleAds\Util\FieldMasks::allSetFieldsOf(Array) #1 /var/www/sites/psmedia/perfectstormmedia/tools/campaign-settings/sitelinks-new/manage-sitelink-feed-submit.php(195): sitelinkSettings->addEditSitelinkFeedItem('3087510920', Array, 'SET') #2 {main} thrown [file] => /var/www/sites/psmedia/perfectstormmedia/tools/includes/api/google-ads-php/src/Google/Ads/GoogleAds/Util/FieldMasks.php [line] => 102 )

$assetId = $itemDetails['feedId']; // Creates an operation to add each asset. $assetOperations = new AssetOperation(); $assetOperations->setUpdate(customers/$adwordsId/assets/$assetId,$assets); $assetOperations->setUpdateMask(customers/$adwordsId/assets/$assetId,FieldMasks::allSetFieldsOf($assets));

Can you please let us know how can we update sitelink asset as we are finding it difficult. We checked that the protobuf installation is fine

Thanks, Anil

shobha-procentris avatar Jul 13 '22 10:07 shobha-procentris

Hi @shobha-procentris. An operation can only update one asset but it looks like you are trying to set a list of assets (the variable name is $assets). Could you try to create one operation per asset instead?

PierrickVoulet avatar Jul 13 '22 15:07 PierrickVoulet

Thank you Pierrick for the reply. We are trying to update only one asset(sitelink here). Not sure if this is the correct way, if you can please guide it would be of great great help..The code which we are using us as mentioned below:

function addEditSitelinkFeedItem($adwordsId, $itemDetails, $action) { parent::setAdwordsClientAccount($adwordsId);

    // Creates some sitelink assets.
    $sitelinkAsset = new SitelinkAsset([
        'description1' => 'test Description 1',
        'description2' => 'test Description 2',
        'link_text' => 'test Headline'
    ]);
    
    // Wraps the sitelinks in an Asset and sets the URLs.
    $assets = [
        new Asset([
            'sitelink_asset' => $sitelinkAsset,
            'final_urls' => 'https://test.com/final', // passed in itemDetails at the top
            'final_mobile_urls' => 'https://test.com/final2', // passed in itemDetails at the top
            'tracking_url_template' => trim($itemDetails['trackingUrl']) // passed in itemDetails at the top
        ]),
    ];
    
    $assetId = $itemDetails['feedId'];
    // Creates an operation to add each asset.
    $assetOperations = new AssetOperation();
    $assetOperations->setUpdate(`customers/$adwordsId/assets/$assetId`,$assets);
    $assetOperations->setUpdateMask(`customers/$adwordsId/assets/$assetId`,FieldMasks::allSetFieldsOf($assets));

}

Please let us know what needs to be corrected so that we can update the sitelink ( description/final url/ etc )

Thanks, Shobha

shobha-procentris avatar Jul 14 '22 10:07 shobha-procentris

Your variable $assets is an array. You should only edit one asset in an operation so you should change the following:

$assets = [
        new Asset([
            ...
        ]),
    ];

to the following:

$assets = new Asset([
    ...
]);

PierrickVoulet avatar Jul 14 '22 11:07 PierrickVoulet

Hi Pierreck,

As per your guidance we modified the code. Can you please take a look

function addEditSitelinkFeedItem($adwordsId, $itemDetails, $action)
{
    parent::setAdwordsClientAccount($adwordsId);

    // Creates some sitelink assets.
    $sitelinkAsset = new SitelinkAsset([
        'description1' => trim($itemDetails['description1']),
        'description2' => trim($itemDetails['description2']),
        'link_text' => trim($itemDetails['headline'])
    ]);
    $assets = new Asset([
        'sitelink_asset' => $sitelinkAsset,
        'final_urls' => [trim($itemDetails['finalUrl'])]
    ]);
    
    $assetId = trim($itemDetails['feedId']);
    $assetOperations = new AssetOperation();
    $assetOperations->setUpdate(`customers/$adwordsId/assets/$assetId`,$assets);
    $assetOperations->setUpdateMask(`customers/$adwordsId/assets/$assetId`,FieldMasks::allSetFieldsOf($assets));
    
    try{
        // Issues a mutate request to add the assets and print its information.
        $assetServiceClient = $this->session->getAssetServiceClient();
        $response = $assetServiceClient->mutateAssets($adwordsId, $assetOperations,[ResponseContentType::MUTABLE_RESOURCE]);
        $createdAssetResourceNames = [];
        
        foreach ($response->getResults() as $result) {
            /* @var MutateAssetResult $result /
            $createdAssetResourceNames[] = $result->getResourceName();
        }
    } catch (Exception $e) {
        $response = array(
            'Status' => 'Error',
            'Content' => $e->getMessage(),
            'Section' => 'Feed Item',
            'Module' => 'Feed Items'
        );
    }
    return json_encode($response);
}

The function throws the error Fatal error: Google\Ads\GoogleAds\V10\Services\MutateAssetsRequest::setOperations(): Must be a repeated field in /var/www/sites/psmedia/perfectstormmedia/tools/includes/api/google-ads-php/src/Google/Ads/GoogleAds/V10/Services/MutateAssetsRequest.php on line 129..

Can you please guide us with the correct code for sitelink update.

Thanks, Shobha

shobha-procentris avatar Jul 27 '22 13:07 shobha-procentris

I found two issues in your code:

  1. The resource name of the element to update should be set in the object itself instead of being provided in the setUpdate and setUpdateMask method calls. You can find an example for a campaign here.
  2. The mutateAssets method takes an array of operations but you provide a single object.

Here is a pseudo code to demonstrate the fixes:

$asset = new Asset([
    'resource_name' => ResourceNames::forAsset($adwordsId, $assetId)
    // You modifications here.
]);

$assetOperation = new AssetOperation();
$assetOperation->setUpdate($asset);
$assetOperation->setUpdateMask(FieldMasks::allSetFieldsOf($asset));

// ...

$response = $this->session->getAssetServiceClient()->mutateAssets(
    $adwordsId,
    [$assetOperation],
    [ResponseContentType::MUTABLE_RESOURCE]
);

PierrickVoulet avatar Jul 27 '22 15:07 PierrickVoulet

Closing due to inactivity. Feel free to reopen this if you still face the issue.

fiboknacky avatar Aug 29 '22 06:08 fiboknacky