Inleiding Google Adwords

Wil je geautomatiseerd (vanuit je CMS bijvoorbeeld) adwords campagnes genereren dan biedt Google Adwords API een oplossing. Is een bepaald product niet meer leverbaar, dan wordt dit direct doorgevoerd in je Adwords campagne. Met Google Adwords API bespaart u niet alleen tijd maar ook geld van kliks naar producten of diensten die niet meer leverbaar zijn. Naast adverteerders met duizenden producten is de tool ook geschikt voor affiliates met veel producten op de site.

SOAP

De Google Adwords API werkt via SOAP. SOAP (Simple Object Access Protocol) is een protocol waarmee gemakkelijk informatie uitgewisseld kan worden. SOAP is mogelijk in tal van programmeertalen, in dit artikel zullen we PHP gebruiken.
Let op: er zijn wel kosten verbonden aan het gebruik van de API. Zie ook: link
Tip: Bespaar op de kosten van Google Adwords API door CSV bestanden in Google Adwords Editors in te laden. Je gebruikt dan de Google Adwords Api niet en voorkomt zo de kosten voor toevoegen en wijzigen van campagnes via de API.

Technische vereisten

PHP met SOAP, curl en open_ssl ondersteuning. Enige ervaring met SOAP is een pre. Een adwords account is uiteraard ook nodig. Indien je deze nog niet hebt, maak deze aan op adwords.google.com.
Zorgen dat je API toegang krijgt
Om aan de slag te gaan met de API, moet je jezelf registeren bij bij Google als Adwords Api gebruiker. Dit gaat alsvolgt:

  • Meld je aan met Adwords account op link . Indien Google er melding van maakt dat het account al onder een Klantencentrum valt registreer dan een MCC account. Maak een MCC-account aan op link en zorg dat je toegang krijgt om het account te beheren.
  • Meld je vervolgens op https://adwords.google.com/select/ApiWelcome aan als Developer. Google zal je op de hoogte stellen wanneer je aanvraag wordt goedgekeurd. Dit kan 1 tot 2 weken duren. Dan krijg je een developertoken.
  • Als je als developer bent ‘goedkgekeurd’, moet je vervolgens een token krijgen voor applicatieontwikkeling. Ook dit kan weer tot 2 weken duren. Ervaring is dat het vaak sneller gebeurt.
  • Met de tokens kunnen we aan de slag. Dit doen we in eerste instantie in de sandbox.

Sandbox

De sandbox is een veilige omgeving om te testen. Dit kost je geen API punten en campagnes worden niet live gezet. Ook niet te bekijken via grafische interface, maar alleen te benaderen via API-calls. Zet namespace op https://adwords-sandbox.google.com/api/adwords/cm/v200909 om in de sandbox te werken. Voor iedere sandbox worden automatisch 5 test-klantaccounts aangemaakt. Deze zijn te benaderen via client_1+mmc-account-email tot client_5+mmc-account-email.

Verbinding maken met Google

<?
Include auth.php 
$user = new AuthToken(emailadres-mmc-account, wachtwoord, 'adwords', 'Applicatie');
$token = $token->GetAuthToken();
?>

Met deze Authtoken kunnen we icm de developer- en applicatietoken verbinding maken met de SOAP interface.

Gebruik maken van services

Via de API zijn verschillende services beschikbaar:

TaakServices
Campagnes beherenCampaignService
Campagnecriteria beherenCampaignCriterionService
Campagne targeting beherenCampaignTargetService
Advertentiegroepen beherenAdGroupService
Advertenties beherenAdGroupAdService
Criteria beherenAdGroupCriterionService
API gebruik informatieInfoService
Keyword ideeen verzamelenTargetingIdeaService
Placement(?) ideeen verzamelenTargetingIdeaService

Twee soorten acties per service: get en mutate. Get haalt informatie op op basis van meegegeven Selector. Alle bewerkingen gaan via mutate, geef type mutatie door, ADD voor toevoegen, SET voor updaten, REMOVE om te deleten.

Werkwijze in code

  • Autoriseren, zie auth.php
  • SOAP opzetten (Soapheaders, service kiezen)
  • Soap-call doen

Code voorbeelden

  • http://code.google.com/intl/nl/apis/adwords/v2009/docs/reference/CampaignService.html#get
  • http://code.google.com/intl/nl/apis/adwords/v2009/docs/reference/CampaignService.CampaignSelector.html laten we leeg.
Voorbeelden maken gebuiken van sandbox. Als je getest hebt en de API ‘live’ wil gaan gebruiken, pas dan de regel:
$namespace = 'https://adwords-sandbox.google.com/api/adwords/cm/v200909';
Aan naar:
$namespace = 'https://adwords.google.com/api/adwords/cm/v200909';

Voorbeeld van get-actie:

<?php
include 'auth.php';

$token = new AuthToken('email@adres.adr', 'password', 'adwords', 'Test');
$_token = $token->GetAuthToken();

$namespace = 'https://adwords-sandbox.google.com/api/adwords/cm/v200909';
$ns = $namespace;

//Body of the Soap Header.
$headerbody = 
array(
  'userAgent' => 'Naam_van_applicatie',
  'authToken' => $_token,
  'developerToken'=> 'token',
  'applicationToken'  => ‘token,
  'clientEmail'   => 'client_1+email@adres.adr'
);

//SOAP header aanmaken   
$headers = new SOAPHeader("https://adwords.google.com/api/adwords/cm/v200909", 'RequestHeader', $headerbody);  
//gebruik de CampaignServer 
$service = new soapclient($namespace . '/CampaignService?wsdl', array('trace' => 1));  
$service->__setSoapHeaders($headers); 
//Gebruik een ‘get’ operatie met een lege selector. Dit zal alle campagnes terug geven van dit acnt
$response = $service->__soapCall('get', array('get' =>array('selector' => '')));
?>

Als alles goed gegaan is bevat $response nu een array met daarin alle campagnes die bij het opgegeven adword account horen.

Voorbeeld van mutate-actie:

Stel dat we een advertentie willen toevoegen aan een adgroup. Dan zullen we dus gebruik moeten maken van de AdgroupAdservice, en omdat we iets gaan toevoegen moet er een mutate-call gedaan worden van het type ADD. In de documentie kan opgezocht worden hoe de bijbehorende operand er uit moet zien.

Van:
http://code.google.com/intl/nl/apis/adwords/v2009/docs/reference/AdGroupAdService.AdGroupAdOperation.html
naar:
http://code.google.com/intl/nl/apis/adwords/v2009/docs/reference/AdGroupAdService.AdGroupAd.html
naar:
http://code.google.com/intl/nl/apis/adwords/v2009/docs/reference/AdGroupAdService.TextAd.html

<?php
include 'auth.php';

$token = new AuthToken('adwords@benschrijver.nl', 'adwordsadwords', 'adwords', 'Test');
$_token = $token->GetAuthToken();

$ns = 'https://adwords-sandbox.google.com/api/adwords/cm/v200909';

//Body of the Soap Header.
$headerbody = 
array(
  'userAgent' => 'Travelmap',
  'authToken' => $_token,
  'developerToken'=> '9PCmuSkMFaQxD86RBLxnhQ',
  'applicationToken'  => 'nJzvnH2jUX1ep_C6-rpBjQ',
  'clientEmail'   => 'client_1+adwords@benschrijver.nl'
);


//Create Soap Header.   
$headers = new SOAPHeader('https://adwords.google.com/api/adwords/cm/v200909', 'RequestHeader', $headerbody);   
$service = new soapclient($ns . '/AdGroupAdService?wsdl', array('trace' => 1));  
$service->__setSoapHeaders($headers); 

$arr = array(
'mutate' => array(
  'operations' => array(
'operator' => 'ADD',
'operand' => array(
  'adGroupId' => 5000002094,
  'ad' => sv('TextAd', array(
'url' => 'http://www.example2.com',
'displayUrl' => 'www.example2.com',
'headline' => 'Luxury Cruise to the Moon',
'description1' => 'Visit the moon in style.',
'description2' => 'Low-gravity fun for everyone!') 
  ))
)
  )
);

$response = $service->__soapCall('mutate', $arr);
?>
Let op: Maakt gebruik van de sv()-functie, deze maakt een soapvar (http://www.php.net/manual/en/class.soapvar.php), zodat er ook een type kan worden meegegeven aan operands.
function sv($type, $v)
{
  return new SoapVar($v, XSD_STRING, $type, 'https://adwords.google.com/api/adwords/cm/v200909');
}
Debugtips: - soapcall in try/catch blok zetten. Soapfault afvangen en weergeven. - _getLastRequest() om verstuurde xml te zien, wel zorgen dat trace aan staat. - response weergeven (print_r) Links Officiële documentatie van Google: http://code.google.com/intl/nl/apis/adwords/docs/developer/index.html PHP SOAP documentatie http://php.net/manual/en/book.soap.php Voorbeelden van XML http://code.google.com/p/adwords-api-xml-samples/source/browse/trunk/src/v200906/ Let op 200906, wel praktisch hetzelfde als 200909 Auth.php:
<?php
/**
 * Client used to retrieve an authentication token for the supplied credentials
 * with the client login API.
 */
class AuthToken {
  private $email;
  private $passwd;
  private $accountType;
  private $service;
  private $source;
  private $server;
  private $res;

  /**
   * Constructor for the authentication token.
   * @param string $email the email of the user
   * @param string $passwd the password of the user
   * @param string $service the service name
   * @param string $source the source name
   * @param string $accountType the account type. Defaults to GOOGLE
   * @param string $server the server to make the request to. Defaults to
   * https://www.google.com
   */
  function __construct($email, $passwd, $service,
  $source, $accountType = 'GOOGLE', $server = NULL) {
$this->email = $email;
$this->passwd = $passwd;
$this->accountType = $accountType;
$this->service = $service;
$this->source = $source;
$this->server = isset($server) ? $server : 'https://www.google.com';
  }

  /**
   * Gets the token from the client login API result.
   * @return string the auth token
   * @access private
   */
  private function GetToken() {
$lines = explode("\n", $this->res);
foreach ($lines as $line) {
  $parts = explode('=', $line);
  if ($parts[0] == 'Auth') {
return $parts[1];
  }
}

throw new InvalidArgumentException(
'The login request used a username or password that is not'
. ' recognized.');
  }

  /**
   * Peforms a POST to get the auth token and then parses the result.
   * @return string the auth token
   */
  public function GetAuthToken() {
$this->Login();
return $this->GetToken();
  }

  /**
   * Makes the client login requrest and stores the result.
   * @access private
   */
  private function Login() {
$postUrl = $this->server . '/accounts/ClientLogin';
$postVars = 'accountType=' . $this->accountType . '&Email='
. urlencode($this->email) . '&Passwd=' . urlencode($this->passwd)
. '&service=' . $this->service . '&source=' . $this->source;

$ch = curl_init($postUrl);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postVars);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$this->res = curl_exec($ch);
curl_close($ch);
  }
}
?>