|
|
Contents
Summary
GemBox.Ppc component is an advanced AdWords API for .NET platform. Using GemBox.Ppc developers can easily download,
upload, synchronize, aggregate, filter, copy, serialize, deserialize and data bind entire hierarchies of AdWords objects.
GemBox.Ppc requires only .NET Framework and is much more powerful than Google AdWords API.
GemBox.Ppc Free is free of charge
while GemBox.Ppc Professional is a commercial version (licensed per developer).
We regularly update GemBox.Ppc and synchronize it with the latest version of AdWords API as we internally
use is for our pay-per-click management application.
Features
GemBox.Ppc extends Google AdWords API by adding advanced features that are listed below.
"Expand" link next to each feature will open detailed description and show sample C# and VB.NET code
(click here to expand all features):
-
Extremely simple download and upload methods. Expand
Download/upload all required AdWords objects in one method call.
All specified descendant objects will be automatically transferred.
Transfer entire account with all objects using one line of code.
account.Download(AwTypes.AdGroups, true);
var campaign = account.Campaigns[0];
// Edit EndDate of first Campaign to January 20, 2012.
campaign.EndDate = DateUtilities.ToAwDate(new DateTime(2012, 1, 20));
// Pause first AdGroup of first Campaign.
campaign.AdGroups[0].Status = AdGroupStatus.PAUSED;
// Uploads all changes.
account.UploadChanges();
account.Download(AwTypes.AdGroups, True)
Dim campaign = account.Campaigns(0)
' Edit EndDate of first Campaign to January 20, 2012.
campaign.EndDate = DateUtilities.ToAwDate(New DateTime(2012, 1, 20))
' Pause first AdGroup of first Campaign.
campaign.AdGroups(0).Status = AdGroupStatus.PAUSED
' Uploads all changes.
account.UploadChanges()
-
Lazy download mode gets data automatically when needed. Expand
In lazy download mode you don't have to explicitly call download method,
as it will be automatically called when you access child collections for the first time or when child collection is older than DownloadLazyDelay.
Therefore, if you set DownloadLazyDelay to 10 minutes, our API guarantees that every child collection you get is not older than 10 minutes.
// Enables lazy download mode.
account.DownloadLazy = true;
// Next line of code will execute two downloads:
// - Lazy Campaigns download.
// - Lazy AdGroups download (only from first Campaign).
var adGroup = account.Campaigns[0].AdGroups[0];
// Again, this will execute lazy Criterions download (from previous AdGroup).
int criterionCount = adGroup.Criterions.Count;
' Enables lazy download mode.
account.DownloadLazy = True
' Next line of code will execute two downloads:
' - Lazy Campaigns download.
' - Lazy AdGroups download (only from first Campaign).
adGroup = account.Campaigns(0).AdGroups(0)
' Again, this will execute lazy Criterions download (from previous AdGroup).
Dim criterionCount As Integer = adGroup.Criterions.Count
-
Hierarchical, tree-like representation of AdWords objects. Expand
Our API model respects AdWords hierarchy we are all familiar with; account contains campaigns, campaign contains ad groups, ad group contains criterions and ads.
All operations are hierarchy- aware (for example, when you download/upload parent object you can specify to download/upload all child objects also).
foreach (var campaign in account.Campaigns)
{
Console.WriteLine("\tCampaign Name: " + campaign.Name);
foreach (var adGroup in campaign.AdGroups)
{
Console.WriteLine("\t\tAdGroup Name: " + adGroup.Name);
foreach (var criterion in adGroup.Criterions)
Console.WriteLine("\t\t\tCriterion Id: " + criterion.Id + ", Type: "
+ criterion.Criterion.GetType().Name);
foreach (var ad in adGroup.Ads)
Console.WriteLine("\t\t\tAd Id: " + ad.Id + ", Type: " + ad.Ad.GetType().Name);
}
}
For Each campaign In account.Campaigns
Console.WriteLine(vbTab & "Campaign Name: " & campaign.Name)
For Each adGroup In campaign.AdGroups
Console.WriteLine(vbTab & vbTab & "AdGroup Name: " & adGroup.Name)
For Each criterion In adGroup.Criterions
Console.WriteLine(vbTab & vbTab & vbTab & "Criterion Id: " & _
criterion.Id & ", Type: " & criterion.Criterion.GetType().Name)
Next
For Each ad In adGroup.Ads
Console.WriteLine(vbTab & vbTab & vbTab & "Ad Id: " & ad.Id & ", Type: " & _
ad.Ad.GetType().Name)
Next
Next
Next
-
Flat representation of AdWords objects (using aggregate collections). Expand
Although primary data model is hierarchical, you have aggregate methods that return collections of all objects of some type.
For example, using aggregate methods you can get all criterions in an account, or all criterions in a campaign.
var accountCriterions = account.GetAllCriterions();
Console.WriteLine("Account criterions (count=" + accountCriterions.Count + "):");
foreach (AdGroupCriterion criterion in accountCriterions)
Console.WriteLine("\tCriterion Id: " + criterion.Id + ", Type: "
+ criterion.Criterion.GetType().Name);
var campaignAds = account.Campaigns[0].GetAllAds();
Console.WriteLine("First Campaign ads (count=" + campaignAds.Count + "):");
foreach (AdGroupAd ad in campaignAds)
Console.WriteLine("\tAd Id: " + ad.Id + ", Type: " + ad.Ad.GetType().Name);
Dim accountCriterions = account.GetAllCriterions()
Console.WriteLine("Account criterions (count=" & accountCriterions.Count & "):")
For Each criterion As AdGroupCriterion In accountCriterions
Console.WriteLine(vbTab & "Criterion Id: " & criterion.Id & ", Type: " & _
criterion.Criterion.GetType().Name)
Next
Dim campaignAds = account.Campaigns(0).GetAllAds()
Console.WriteLine("First Campaign ads (count=" & campaignAds.Count & "):")
For Each ad As AdGroupAd In campaignAds
Console.WriteLine(vbTab & "Ad Id: " & ad.Id & ", Type: " & ad.Ad.GetType().Name)
Next
-
Easy, dynamic filtering of AdWords objects (using aggregate collections). Expand
Using aggregate collections you perform dynamic filtering of any collection(s) using custom filter function.
Unlike LINQ, aggregate collection will dynamically update when source collection(s) change.
// Gets all Criterions under this account.
var allCriterions = account.GetAllChildren<AdGroupCriterion>(AwTypes.Criterions);
// Filter only Keyword Criterions.
var filteredKeywords = new AggregateCollection<AdGroupCriterion>(x => x.Criterion is Keyword, null, allCriterions);
' Gets all Criterions under this account.
Dim allCriterions = account.GetAllChildren(Of AdGroupCriterion)(AwTypes.Criterions)
' Filter only Keyword Criterions.
Dim filteredKeywords = new AggregateCollection(Of AdGroupCriterion)(Function(x) TypeOf x.Criterion is Keyword, Nothing, allCriterions)
-
Full data binding support on objects (IPropertyChanged) and collections (ICollectionChanged). Expand
You get data binding out-of-the box as all classes representing AdWords objects implement
IPropertyChanged interface and all collections implement ICollectionChanged interface.
// Set INotifyPropertyChanged event handler.
account.PropertyChanged +=
(sender, e) => Console.WriteLine("Changed property name: " + e.PropertyName);
// Set INotifyCollectionChanged event handler.
account.Campaigns.CollectionChanged +=
(sender, e) => Console.WriteLine("Collection changed with action: " + e.Action);
// This will fire PropertyChanged event.
account.DownloadDeletedItems = true;
// This will fire CollectionChanged event.
account.Download(AwTypes.Campaigns, true);
' Set INotifyPropertyChanged event handler.
AddHandler account.PropertyChanged, _
Function(sender, e) WriteLine("Changed property name: " & e.PropertyName)
' Set INotifyCollectionChanged event handler.
AddHandler account.Campaigns.CollectionChanged, _
Function(sender, e) WriteLine("Collection changed with action: " & e.Action.ToString())
' This will fire PropertyChanged event.
account.DownloadDeletedItems = True
' This will fire CollectionChanged event.
account.Download(AwTypes.Campaigns, True)
-
Minimal API unit usage. Expand
Upload/download methods use minimum amount of AdWords API units.
In addition to that lazy download enables to download only object that you actually need,
upload method uploads only changes, and downloading of deleted objects is optional.
// Default is false (to save API units).
Console.WriteLine("Download deleted items: " + account.DownloadDeletedItems);
// Set allowed API units to be spend to 1000.
// This will throw GemBoxPpcException if limit is exceeded.
UnitCounters.SafetyLimit = 1000;
// Download only items that will be accessed.
account.DownloadLazy = true;
// Only campaigns will be downloaded.
foreach (var campaign in account.Campaigns)
if (campaign.Status == CampaignStatus.ACTIVE)
campaign.Budget.Amount.MicroAmount += MoneyUtilities.CurrencyToMicros(0.05);
// Will only upload campaigns that changed.
account.UploadChanges();
' Default is false (to save API units).
Console.WriteLine("Download deleted items: " & account.DownloadDeletedItems)
' Set allowed API units to be spend to 1000.
' This will throw GemBoxPpcException if limit is exceeded.
UnitCounters.SafetyLimit = 1000
' Download only items that will be accessed.
account.DownloadLazy = True
' Only campaigns will be downloaded.
For Each campaign In account.Campaigns
If campaign.Status = CampaignStatus.ACTIVE Then
campaign.Budget.Amount.MicroAmount += MoneyUtilities.CurrencyToMicros(0.05)
End If
Next
' Will only upload campaigns that changed.
account.UploadChanges()
-
Nullable properties (no xxxIsSpecified flags). Expand
Google AdWords API for .NET forces you to set/get xxxIsSpecified flags for optional value type properties.
Avoid bugs and write shorter code using our API where optional properties are nullable.
-
Uploadable objects. Expand
In Google AdWords API for .NET you need to reset read-only properties before uploading previously downloaded objects.
Our API doesn’t serialize read only properties so downloaded objects are directly uploadable.
-
Disconnected data model (work on cached local data and upload when needed). Expand
After initial download you work with cached local data, which is extremely fast.
After making changes, you upload all changes (but only changes) in bulk, which is fast and uses minimum amount of API units.
Preservation enables you to save cached data and upload it sometime in the future.
-
Advanced synchronization of local and server data. Expand
Properties of AdWords objects are versionable, meaning that we internally track original, server and local values.
Advanced synchronization scenarios become possible because if data on the server changes,
you will be able to download that changes and compare them to local and original values.
var localVal = item.GetValue(desc, DataVersion.Local);
var serverVal = item.GetValue(desc, DataVersion.Server);
if (!object.Equals(localVal, serverVal))
Console.WriteLine("Difference for " + desc.Name +
" property (Local=" + localVal + ", Server=" + serverVal + ")");
Dim localVal = item.GetValue(desc, DataVersion.Local)
Dim serverVal = item.GetValue(desc, DataVersion.Server)
If Not Object.Equals(localVal, serverVal) Then
Console.WriteLine("Difference for " & desc.Name & _
" property (Local=" & localVal & ", Server=" & serverVal & ")")
End If
-
Ability to resolve synchronization conflicts. Expand
Synchronization conflict is when same value changes on both server and locally.
Default synchronization protocol prefers local changes over server changes.
However, you can easily iterate all conflicts and revert to server change on any item.
// Collection syncChanges will contain all campaigns whose value on server has changed.
foreach (var syncChange in account.GetSyncChanges(AwTypes.Campaigns))
// Also, campaign will be in conflict if local changes are different from server changes.
if (syncChange.HasConflict)
{
var item = syncChange.Item;
foreach (var desc in item.PropertyDescriptors)
{
var localVal = item.GetValue(desc, DataVersion.Local);
var serverVal = item.GetValue(desc, DataVersion.Server);
if (!object.Equals(localVal, serverVal))
Console.WriteLine("Difference for " + desc.Name +
" property (Local=" + localVal + ", Server=" + serverVal + ")");
}
Console.Write("Keep (L)ocal or revert to (S)erver? ");
if (Console.ReadLine().ToUpper() == "S")
{
Console.WriteLine("Reverting to server values.");
item.Revert();
}
else
Console.WriteLine("Keeping local values.");
// Accept current state to finish conflict resolution for this item.
item.Accept();
}
' Collection syncChanges will contain all campaigns whose value on server has changed.
For Each syncChange In account.GetSyncChanges(AwTypes.Campaigns)
' Also, campaign will be in conflict if local changes are different from server changes.
If syncChange.HasConflict Then
Dim item = syncChange.Item
For Each desc In item.PropertyDescriptors
Dim localVal = item.GetValue(desc, DataVersion.Local)
Dim serverVal = item.GetValue(desc, DataVersion.Server)
If Not Object.Equals(localVal, serverVal) Then
Console.WriteLine("Difference for " & desc.Name & _
" property (Local=" & localVal & ", Server=" & serverVal & ")")
End If
Next
Console.Write("Keep (L)ocal or revert to (S)erver? ")
If Console.ReadLine().ToUpper() = "S" Then
Console.WriteLine("Reverting to server values.")
item.Revert()
Else
Console.WriteLine("Keeping local values.")
End If
' Accept current state to finish conflict resolution for this item.
item.Accept()
End If
Next
-
Ability to undo local changes. Expand
Internally we track all local changes, so you can iterate changed items and undo (revert to original values) on any of them.
// Mark all AdGroups for deletion.
adGroups.Clear();
// All AdGroups are marked for deletion.
foreach (var adGroup in adGroups)
Console.WriteLine("AdGroup '" + adGroup.Name + "' is " +
adGroup.LocalVsServerState);
// Revert all AdGroups to previous state.
foreach (var adGroup in adGroups)
adGroup.Revert();
// None of the AdGroups is marked for deletion.
foreach (var adGroup in adGroups)
Console.WriteLine("AdGroup '" + adGroup.Name + "' is " +
adGroup.LocalVsServerState);
' Mark all AdGroups for deletion.
adGroups.Clear()
' All AdGroups are marked for deletion.
For Each adGroup In adGroups
Console.WriteLine("AdGroup '" & adGroup.Name & "' is " & _
adGroup.LocalVsServerState.ToString())
Next
' Revert all AdGroups to previous state.
For Each adGroup In adGroups
adGroup.Revert()
Next
' None of the AdGroups is marked for deletion.
For Each adGroup In adGroups
Console.WriteLine("AdGroup '" & adGroup.Name & "' is " & _
adGroup.LocalVsServerState.ToString())
Next
-
Preservation - load/save entire model to an XML file. Expand
Load/save methods deserialize/serialize entire data model to an XML file.
You can use that file to backup, retrieve data at later time or process with some other tool.
using (var stream = new FileStream("account.xml", FileMode.Create))
{
// Save account's data to a file.
account.Save(stream);
}
AwAccount loadedAccount;
using (var stream = new FileStream("account.xml", FileMode.Open))
{
// Load account's data from a file.
loadedAccount = AwAccount.Load(stream, account.User);
}
Using stream As New FileStream("account.xml", FileMode.Create)
' Save account's data to a file.
account.Save(stream)
End Using
Dim loadedAccount As AwAccount
Using stream As New FileStream("account.xml", FileMode.Open)
' Load account's data from a file.
loadedAccount = AwAccount.Load(stream, account.User)
End Using
-
API errors handling. Expand
Upload methods are smart about API errors. Items that cause API errors (for example, items with disallowed words or invalid bids)
will be marked, while correct items will be uploaded.
You can easily iterate all items with API errors check error details and remove errors.
// Set EndDate to some past value e.g. 12th of October, 2008. This will produce API Error.
account.Campaigns[0].EndDate = DateUtilities.ToAwDate(new DateTime(2008, 10, 12));
ApiErrorObjectCollection errors;
account.UploadChanges(out errors);
Console.WriteLine("Error: " + errors[0].ApiErrors[0].Reason);
' Set EndDate to some past value e.g. 12th of October, 2008. This will produce API Error.
account.Campaigns(0).EndDate = DateUtilities.ToAwDate(New DateTime(2008, 10, 12))
Dim errors As ApiErrorObjectCollection = Nothing
account.UploadChanges(errors)
Console.WriteLine("Error: " & errors(0).ApiErrors(0).Reason)
-
API unit counting. Expand
You can track total used API units and units used per specific service.
You can also set safety limit, so if your application gets into endless loop, it will not spend endless amounts of money.
// Default is true.
Console.WriteLine("Unit counters enabled: " + UnitCounters.Enabled);
// Set allowed API units to be spend to 1000.
// This will throw GemBoxPpcException if limit is exceeded.
UnitCounters.SafetyLimit = 1000;
// Download and accept all AdWords objects.
account.Download(AwTypes.All, true);
foreach (KeyValuePair<string, long> serviceUnits in UnitCounters.ServiceUnits)
Console.WriteLine(serviceUnits.Key + " has spent " + serviceUnits.Value + " unit(s).");
Console.WriteLine("Total spend units: " + UnitCounters.TotalUnits);
' Default is true.
Console.WriteLine("Unit counters enabled: " & UnitCounters.Enabled)
' Set allowed API units to be spend to 1000.
' This will throw GemBoxPpcException if limit is exceeded.
UnitCounters.SafetyLimit = 1000
' Download and accept all AdWords objects.
account.Download(AwTypes.All, True)
For Each serviceUnits As KeyValuePair(Of String, Long) In UnitCounters.ServiceUnits
Console.WriteLine(serviceUnits.Key & " has spent " & serviceUnits.Value & " unit(s).")
Next
Console.WriteLine("Total spend units: " & UnitCounters.TotalUnits)
-
XML SOAP logging. Expand
Logs SOAP messages to nicely formatted XML log file. You can also hook to SOAP trace event and make any kind of log for yourself.
// Enable logging of SOAP messages.
using (SoapLogger.Output = new FileStream("SOAPlog.xml", FileMode.Create))
{
// Download and accept all AdWords objects.
account.Download(AwTypes.All, true);
}
' Enable logging of SOAP messages.
Using fs As New FileStream("SOAPlog.xml", FileMode.Create)
SoapLogger.Output = fs
' Download and accept all AdWords objects.
account.Download(AwTypes.All, True)
End Using
-
Smart (partial) copying of AdWords objects. Expand
Partial copying is used to create new items from existing ones.
It copies settable properties and ignores read-only properties (like statistics, approval status and ID) that wouldn’t make sense in the copied object.
// Create a copy of the first Campaign.
// Partial copy doesn't copy read-only properties and Id.
var campaignCopy = account.Campaigns[0].Clone(true) as Campaign;
' Create a copy of the first Campaign.
'Partial copy doesn't copy read-only properties and Id.
Dim campaignCopy = TryCast(account.Campaigns(0).Clone(True), Campaign)
-
Generic iteration over hierarchies and object properties. Expand
You can write generic code that iterates all nodes of AdWords hierarchy; account, campaigns and ad groups.
You can also iterate values of some AdWords object without using reflection, by using fast and safe property descriptors architecture.
// Iterate through all AdWords objects.
foreach (var descendant in account.GetDescendants(AwTypes.All))
{
Console.WriteLine("Type: " + descendant.GetType().Name + ". Id: " + descendant.Id);
// Iterate through all properties of specified AdWords object.
foreach (var desc in descendant.PropertyDescriptors)
Console.WriteLine("\tName: " + desc.Name + ". Value: " +
descendant.GetValue(desc));
}
' Iterate through all AdWords objects.
For Each descendant In account.GetDescendants(AwTypes.All)
Console.WriteLine("Type: " & descendant.GetType().Name & ". Id: " & descendant.Id)
' Iterate through all properties of specified AdWords object.
For Each desc In descendant.PropertyDescriptors
Dim value = descendant.GetValue(desc)
Console.WriteLine(vbTab & "Name: " & desc.Name & ". Value: " & _
If(value IsNot Nothing, value.ToString(), "Nothing"))
Next
Next
-
Requires minimal security permissions. Expand
GemBox.Ppc.Dll requires Medium Trust security permissions and Unrestricted WebPermission in order to connect to web servers.
Entire API is written in managed code and uses only .NET Framework.
GemBox.Ppc on-line help contains
additional information about API and supported features.
For frequently asked licensing and technical questions, consult our
FAQ section.
Reference application
Reference Application demonstrates basic concepts of a typical application that uses our
GemBox.Ppc component to access and modify data from AdWords servers (click thumbnail to see larger screenshot).
Reference Application executes as zero-deployment ClickOnce application. To launch it, your computer needs to have
Windows Installer 3.1 and .NET Framework 3.5 SP1. If these components are
already installed (most new XP and Vista machines), click here:
If above link doesn't work, click here to
install the prerequisites and run the application.
More information is available on
GemBox.Ppc Reference Application page.
AdWords custom programming
We also offer consulting services and custom AdWords programming. If you need additional
features in GemBox.Ppc component or if you need development of completely
customized AdWords solution, we are here for you.
For example, we can:
|
|
Integrate your business back-end with Google AdWords system.
|
|
|
Automate management of complex AdWords campaigns.
|
|
|
Synchronize multiple pay-per-click (PPC) systems.
|
|
|
Build rich GUIs for AdWords management.
|
|
|
Implement advanced bidding strategies.
|
For more information on AdWords consulting and custom development,
contact us directly.
|
|
|
© GemBox Software. All rights reserved.
|
|
|