Retreiving structural data for sitelinks

165 views
Skip to first unread message

Visar

unread,
Nov 26, 2014, 6:23:50 AM11/26/14
to adwor...@googlegroups.com
Hi,

I'm having a little trouble using the API to retrieve structural data on sitelinks within an account. What I'm looking to do is to construct a list of which sitelinks belong to which campaigns (this is unavailable in the reports due to the lack of Zero Impressions support).

Ideally data which could be placed into a table of the form:

CampaignID   SitelinkID
0000000001   1123412
0000000001   1232349
0000000002   2342342
etc..

Given that I have an exhaustive list of all the campaign IDs and sitelink IDs (as placeholder feed item IDs), could someone please illustrate how this could be done, i.e which services to use and how to actually use them. Please be as detailed as possible. I'm currently using PHP but can work with any language.

Cheers

Anash P. Oommen (AdWords API Team)

unread,
Nov 26, 2014, 6:53:00 AM11/26/14
to adwor...@googlegroups.com
Hi Visar,

You need to use the CampaignFeedService to retrieve the MatchingFunction and then parse it to identify the FeedItems that are associated with a campaign. The C# code to do this looks :

private CampaignFeed[] GetCampaignFeeds(AdWordsUser user, Feed feed) {
 
CampaignFeedService campaignFeedService = (CampaignFeedService) user.GetService(
     
AdWordsService.v201409.CampaignFeedService);
 
 
CampaignFeedPage page = campaignFeedService.query(string.Format(
     
"SELECT CampaignId, MatchingFunction where " +
     
"Status='ENABLED'and FeedId = '{0}' and PlaceholderTypes=1", feed.id));
  return page.entries;
}

private List<long> GetFeedItemsForCampaign(CampaignFeed campaignFeed) {
 
List<long> feedItems = new List<long>();
 
if (campaignFeed.matchingFunction.lhsOperand.Length == 1 &&
      campaignFeed
.matchingFunction.lhsOperand[0] is RequestContextOperand &&
     
(campaignFeed.matchingFunction.lhsOperand[0] as
           
RequestContextOperand).contextType ==
           
RequestContextOperandContextType.FEED_ITEM_ID &&
      campaignFeed
.matchingFunction.@operator == FunctionOperator.IN) {
   
foreach (ConstantOperand argument in campaignFeed.matchingFunction.rhsOperand) {
      feedItems
.Add(argument.longValue);
   
}
 
}
 
return feedItems;
}


GetFeedItemsForCampaign only handles the simplest of the cases (FEEDITEM_ID IN [id1, id2, id3]). In theory, the matchingfunction can be an arbitrary expression tree, but if you stick to what the UI can do, then it is restricted to (FEEDITEM_ID IN [id1, id2, id3]) and DEVICE_PLATFORM = 'Mobile'

Cheers,
Anash P. Oommen,
AdWords API Advisor.

Visar

unread,
Nov 26, 2014, 12:21:30 PM11/26/14
to adwor...@googlegroups.com
Hi Anash,

That's exactly what I needed, thanks.

Visar

Visar

unread,
Dec 1, 2014, 6:08:34 AM12/1/14
to adwor...@googlegroups.com
Hi Anash, 

I just have a couple more questions.

1) Usually in the example API scripts, when entries in a get request are cycled through they are done so with the use of the AdWords recommend page size stuff. Is there a reason you left this out in your C# example, and more importantly should I include this myself in my own code?

2) As far as I can tell there's no way to get the FeedID for just site-links because in the PLACEHOLDER_FEED_ITEM_REPORT report the "ClickType" field does not support zero impressions. Is there any way to get the FeedID for sitelinkes without the other FeedID values returned by the PLACEHOLDER_FEED_ITEM_REPORT?

Visar

Anash P. Oommen (AdWords API Team)

unread,
Dec 1, 2014, 2:39:42 PM12/1/14
to adwor...@googlegroups.com
Hi Visar,

1. Nope, The code snippet is to illustrate how the API call is to be made; you should be using paging in your production code.
2. Not from the report directly, but you could modify the GetCampaignFeeds method so as to not filter by FeedId and you'd get all the FeedIds of a specific type back.

Cheers,
Anash

Visar

unread,
Dec 2, 2014, 5:09:22 AM12/2/14
to adwor...@googlegroups.com
Anash,

Thanks for your response. If I modify the GetCampaignFeeds method to return all the FeedIDs (i.e not filtering on FeedID) is there anyway to know which FeedIDs correspond to sitelinks?

Visar

Anash P. Oommen (AdWords API Team)

unread,
Dec 4, 2014, 9:39:41 AM12/4/14
to adwor...@googlegroups.com
Hi Visar,

Yes, if you don't filter by feedId, then GetCampaignFeeds will give you ALL the campaign feeds where placeholdertype = 1 (i.e. sitelinks). Just pick the FeedId from the CampaignFeed.

There's a caveat to this: By definition, a Feed doesn't have an extension type associated with it, so you could in theory add columns for different extension types to a Feed, and then reuse the same feed for different extension types by mapping the right columns. Not that it's an efficient way to do things, but you might eventually come across such a case if you process lots of accounts.

Cheers,
Anash

Visar

unread,
Dec 4, 2014, 9:46:13 AM12/4/14
to adwor...@googlegroups.com
Hi Anash, 

I don't really understand what you mean. How could I go about doing that?

Visar

On Wednesday, November 26, 2014 11:23:50 AM UTC, Visar wrote:

Anash P. Oommen (AdWords API Team)

unread,
Dec 4, 2014, 10:06:31 AM12/4/14
to adwor...@googlegroups.com
Hi Visar,

Since you are looking for feed ids only, the caveat I mentioned on the previous message shouldn't apply to you.

private CampaignFeed[] GetSitelinkFeeds(AdWordsUser user) {

 
CampaignFeedService campaignFeedService = (CampaignFeedService) user.GetService(
     
AdWordsService.v201409.CampaignFeedService);
 
 
CampaignFeedPage page = campaignFeedService.query(string.Format(

     
"SELECT CampaignId, FeedId, MatchingFunction where " +
     
"Status='ENABLED'and FeedId = '{0}' and PlaceholderTypes=1", feed.id));

 
List<long> feedIds = new List<long>();
 
foreach (CampaignFeed campaignFeed in page.entries) {
    feedIds
.Add(campaignFeed.feedId);
 
}
 
return feedIds.ToArray();;
}

Cheers,
Anash

Visar

unread,
Feb 11, 2015, 6:41:20 AM2/11/15
to adwor...@googlegroups.com
Hi again Anash,

I've been trying to implement the code you've illustrated but I'm having a few problems. 

Problem 1) When you use: campaignFeed.matchingFunction.@operator == FunctionOperator.IN this only picks out those campaigns with more than one sitelink ad extension. Those with only one sitelink ad extension have an "EQUALS" FunctionOperator rather than an "IN". Is it safe to remove this condition, in order to pick up those campaigns matched with one sitelink ad extension only?

Problem 2) There is a bigger problem. The matching function does indeed return all active site link ad extensions associated with campaigns. However, if one removes the all the site links from a campaign (so that the campaign is left with no site links), the previously associated site link group is still returned by the matching function. I.e there seems to be a residue when removing the site links from the campaign wholesale. This maybe be illustrated better as follows:

If we start with an account with the following state
CampaignA => [SitelinkA, SitelinkB]

The matching function returns:
CampaignA => [SitelinkA, SitelinkB]
 
If we remove the site links so that there are no associated site links for the campaign 
CampaignA => []

The residue of the old grouping of site links will still show up in the matching function as follows
CampaignA => [SitelinkA, SitelinkB]

If, however, one removes just a single site link from the original state of affairs, so that in the account it looks like 
CampaignA => [SitelinkA]

The matching function will correctly return 
CampaignA => [SitelinkA]

If we were to now further remove SitelinkA the matching function will incorrectly report that SitelinkA is associated with CampaignA. Therefore when completely removing site links, there is a residue in the corresponding matching function.

Is this a bug?

Is there any way to produce a list of all current and active sitelink-campaign associations?

Visar

Josh Radcliff (AdWords API Team)

unread,
Feb 11, 2015, 9:01:29 AM2/11/15
to adwor...@googlegroups.com
Hi Visar,

When you removed all sitelinks from CampaignA, did you do so using the UI? I ask because it may be that the UI may be simply setting the CampaignFeed.status to REMOVED in that case. If so, you can add a predicate in your CampaignFeedService.get request on STATUS = ENABLED to exclude such CampaignFeeds.

Cheers,
Josh, AdWords API Team

Visar

unread,
Feb 12, 2015, 4:37:27 AM2/12/15
to adwor...@googlegroups.com
Josh,

Adding  Status = 'ENABLED' sorted it. 

Thanks
Reply all
Reply to author
Forward
0 new messages