Connecting to the AdWords API Using Just SOAP

in AdWords API

It is best to use the official client libraries provided by Google to access the AdWords API: They have additional modifications and utilities to make life easier, and are kept up to date. However, occasionally you might want to bypass the client library and construct the SOAP calls yourself. This tutorial covers how to use the PHP 5 SOAP extension to build AdWords API tools without using a client library.

Using the AdWords API with No Client Library

I personally find the PHP SOAP extension a challenge; it’s probably my lack of knowledge of SOAP that’s the problem, but I thought the whole point of it in the first place was that it could be used without detailed knowledge. The idea was that WSDL could be used by tools to generate structures appropriate for a specific language. In strongly typed languages such as Java and C# this works well, as you just automatically generate a library using a tool and make calls to it as if it was an API written in the same language; however, in the case of PHP there’s no such tool, and the structure of SOAP just seems to make things more difficult. Using the extension I sometimes feel that it would be simpler to generate the SOAP as a text string and push it up with cURL.

Anyway, if you find that you’re having problems then the best thing to do is turn the tracing option on, and look at the SOAP that’s being produced. You can use the logging option in the AdWords API client library to generate the correct SOAP, then compare it to your own.

The AdWords API Service Location and Namespace

That said, let’s push on with the using the extension. First off, you need to specify the namespace and endpoint location URL for the service: The namespace is the URL https://adwords.google.com/api/adwords/cm/, followed by the version of the API you want to use; the service URL is this namespace with the name of the service on the end. However, if you want to use the sandbox instead, you also need to change the service URL to point to the sandbox server. Here’s some constants for the sandbox version of the v201209 Campaign Service:

define("ADWORDS_API_VERSION", "v201209"); 
define("ADWORDS_API_SERVER", "https://adwords-sandbox.google.com"); 
define("ADWORDS_API_NAMESPACE", "https://adwords.google.com/api/adwords/cm/" . ADWORDS_API_VERSION); 
define("ADWORDS_API_CAMPAIGN_SERVICE", ADWORDS_API_SERVER . "/api/adwords/cm/" . ADWORDS_API_VERSION . "/CampaignService");
AdWords API SOAP Parameters

When you want to move over to the production API, just change the ADWORDS_API_SERVER constant:

define("ADWORDS_API_SERVER", "https://adwords.google.com");
AdWords API Live Server

Generating an AdWords API ClientLogin Token

To authenticate your request to the API, you need to provide a token from Google’s ClientLogin service. This can be done by posting a request to the URL https://www.google.com/accounts/ClientLogin, along with the service, type of account you want to access, and the account's username and password. This can be achieved using cURL:

$url = "https://www.google.com/accounts/ClientLogin"; 
$params = array( 
   "accountType" => "GOOGLE", 
   "Email" => $username, 
   "Passwd" => $password, 
   "service" => "adwords", 
   "source" => "test" 
); 
$curl = curl_init(); 
curl_setopt($curl, CURLOPT_URL, $url); 
curl_setopt($curl, CURLOPT_HEADER, false); 
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); 
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($curl, CURLOPT_POST, true); 
curl_setopt($curl, CURLOPT_POSTFIELDS, $params); 
curl_setopt($curl, CURLOPT_ENCODING, ""); 
$curlData = curl_exec($curl); 
curl_close($curl);
Generating an AdWords API ClientLogin Token using CURL

The response contains a parameter called Auth that you need to extract:

$pos = strpos($curlData, "Auth="); 
if ($pos > -1) { 
   $auth = trim(substr($curlData, $pos + 5)); 
}
Extracting the Token from the Response

AdWords API Authentication Headers

Once you have your ClientLogin token, you need to encode it into a SOAP header to be sent along with the request; the header also needs to contain your developer token and the customer id of the account you want to access. These need to be wrapped into a structure called RequestHeader:

define("ADWORDS_API_TOKEN", "YOUR_DEV_TOKEN"); 
$username = "YOUR_USERNAME";
$password = "YOUR_PASSWORD";
$customerId = "123-456-7890";
 
$headers = array( 
   "developerToken" => ADWORDS_API_TOKEN, 
   "userAgent" => "testing", 
   "clientCustomerId" => $customerId,
   "authToken" => $auth 
); 
$encodedHeaders = new SoapHeader(ADWORDS_API_NAMESPACE, "RequestHeader", $headers, false);
Setting the Authentication Headers for the SOAP Call

The AdWords API Service Selector

The body of the request contains the operations you want to carry out via the API. For this example, I’m just going to issue a GET request to retrieve all the campaigns in an account; I will use a simple selector so that the id and name fields are retrieved. No special encoding is needed here so the request is just an array:

$request = array( 
   "get" => array( 
      "serviceSelector" => array( 
         "fields" => array("Id", "Name") 
      ) 
   ) 
);
A Selector for Retrieving Campaign Fields

Calling the AdWords API Campaign Service

To send the request, you need to create a SoapClient for the service, then call it using the headers and request you created earlier. The client needs the location of the WSDL, which is just the service location with ?wsdl on the end. I’m also specifying the tracing option here, so the SOAP calls are logged, and can be inspected:

$client = new SoapClient(ADWORDS_API_CAMPAIGN_SERVICE . "?wsdl", array("trace" => true)); 
$result = $client->__soapCall("get", $request, null, $encodedHeaders);
SOAP Call for Retrieving AdWords Campaigns

Processing the Response fro the AdWords API

To process the response, you can either consult the API documentation, or simply print_r it to see what it contains. In this example, the response has a property called rval that has another property called entries, which is an array containing the campaigns. The following code just loops through the campaigns, and outputs the id and name fields that I requested:

$campaigns = $result->rval->entries; 
   foreach ($campaigns as $campaign) { 
   print "Found campaign '{$campaign->name}' with an ID of {$campaign->id}\n"; 
}
Extracting each AdWords Campaign

Full Example: Using the AdWords API without a Client Library

Here's the complete sample code for you to try out:

// Reference to the service and version of the API you want to use
define("ADWORDS_API_VERSION", "v201209");
 
// Production API 
//define("ADWORDS_API_SERVER", "https://adwords.google.com"); 
// Sandbox API
define("ADWORDS_API_SERVER", "https://adwords-sandbox.google.com");
 
define("ADWORDS_API_NAMESPACE", "https://adwords.google.com/api/adwords/cm/" . ADWORDS_API_VERSION);
define("ADWORDS_API_CAMPAIGN_SERVICE", ADWORDS_API_SERVER . "/api/adwords/cm/" . ADWORDS_API_VERSION . "/CampaignService");
 
// Your API Developer Token
define("ADWORDS_API_TOKEN", "YOUR_DEV_TOKEN");
 
// The account that you want to download performace data from
$username = "YOUR_USERNAME";
$password = "YOUR_PASSWORD";
$customerId = "123-456-7890";
 
try {
    // Get an auth token for the user
    $url = "https://www.google.com/accounts/ClientLogin";
    $params = array(
        "accountType" => "GOOGLE",
        "Email" => $username,
        "Passwd" => $password,
        "service" => "adwords",
        "source" => "test"
    );
 
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HEADER, false);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
    curl_setopt($curl, CURLOPT_ENCODING, "");
    $curlData = curl_exec($curl);
    curl_close($curl);
 
    $pos = strpos($curlData, "Auth=");
    if ($pos > -1) {
        $auth = trim(substr($curlData, $pos + 5));
    } else {
        throw new Exception("You haven't supplied a valid username or password for an existing Google account.");
    }
 
    // Create the headers needed to access the API
    $headers = array(
        "developerToken" => ADWORDS_API_TOKEN,
        "userAgent" => "testing",
        "clientCustomerId" => $customerId,
        "authToken" => $auth
    );
 
    // Encode the headers
    $encodedHeaders = new SoapHeader(ADWORDS_API_NAMESPACE, "RequestHeader", $headers, false);
 
    // Create the selector
    $request = array(
        "get" => array(
            "serviceSelector" => array(
                "fields" => array("Id", "Name")
            )
        )
    );
 
    // Create the SOAP client
    $client = new SoapClient(ADWORDS_API_CAMPAIGN_SERVICE . "?wsdl", array("trace" => true));
 
    // Get the campaigns
    $result = $client->__soapCall("get", $request, null, $encodedHeaders);
 
    // Output the results
    $campaigns = $result->rval->entries;
    foreach ($campaigns as $campaign) {
        print "Found campaign '{$campaign->name}' with an ID of {$campaign->id}\n";
    }
} catch (Exception $e) {
    print_r($e);
    if (isset($client)) {
        print $client->__getLastRequest() . "\n";
        print $client->__getLastResponse() . "\n";
    }
}
?>
Extracting AdWords Campaigns using SOAP

To use this code, you need to change the ADWORDS_API_VERSION constant to the latest version of the API, modify the ADWORDS_API_TOKEN constant so that it contains your developer token, then add the username, password, and customer id of the account you want to access into the $username, $password, and $customerId variables.

Comments

I'm keen to get feedback on my posts, so if you have any questions or comments, then please send me a message and I'll be happy to help.

uness

how can i know my developerToken ?

Reply

laid

Hi Ewan i'm getting this error: [previous:Exception:private] => [faultstring] => [AuthenticationError.LOGIN_COOKIE_REQUIRED @ ; trigger:'']

Any suggestions??

thnx :)

Reply

Ewan

Hi Laid,

As mentioned on the AdWords API forum, your issue is probably due to not entering a valid username and password. I've also updated the post to reference the latest API version and explain how to use the code with the sandbox version of the API.

Regards,

Ewan

Reply

newbie

Hi!

if using the sandbox do you still need to put information in the email, password in the auth.ini?

Reply

karthik

Hi

How to get getkeywords using Soap request?

Reply

Ewan

Hi Karthik,

The best way to work out how to build the SOAP requests is to generate it using the logging in the client library, then copy the log output into your program and use it to either generate code for the PHP SOAP extension, or even just modify the raw XML and post it to the API using cURL.

However, I really would recommend using the client library unless you've got a really good reason not to. You need to upgrade AdWords API tools every six to twelve months when Google deprecates older versions, and the upgrade is much easier when you just need to swap out the library and make some small amendments to your code.

Regards,

Ewan

Reply

newbie

if using the sandbox do you still need to put information in the email, password in the auth.ini?

Reply

Ewan

Yes, but it can be the email and password for any Google Account; it doesn't need to be attached to an AdWords account.

Reply