Google Ads API JS Client Library
-------------------------

An **unofficial** JS client library for the SOAP-based DFP Ads API.

### Guides & samples

   * [Server-side](https://github.com/havelessbemore/googleads-node-lib/tree/master/examples/server_side)
   * [Client-side](https://github.com/havelessbemore/googleads-node-lib/tree/master/examples/client_side)

To get started quickly, use one of the step by step guides above for the environment of your choice. Otherwise, below is a general walkthrough of using this library.

### Setup

Follow [steps 1 - 3 of the Authentication guide](https://developers.google.com/doubleclick-publishers/docs/authentication#service) to create a [Google API Console project](https://support.google.com/googleapi/answer/7015000), generate your [OAuth2 credentials](https://developers.google.com/identity/protocols/OAuth2), and configure your [DFP network](https://www.google.com/dfp)

   - Service account: Securely store the downloaded private key in a location accessible to your node project. The project will need it to make authorized API calls.

   * Web application: Securely store the client ID and client secret in a location accessible to your node project. You will need them to make authorized API calls.

### Use server-side

1. Install [Node.js](https://nodejs.org/en/) and [NPM](https://www.npmjs.com/)

   Option A: Install using NVM ([see here for installing NVM](https://github.com/creationix/nvm#install-script))
   ```
   $ nvm install node
   ```

   Option B: Install from [nodejs.org](https://nodejs.org/en/download/)

2. Initialize a node project

   ```
   $ npm init -y
   ```

3. Install this client library as a dependency

   ```
   $ npm install -S gads
   ```

4. (Optional) [Setup Typescript for your node project](https://basarat.gitbooks.io/typescript/docs/quick/nodejs.html)
   ```
   $ npm install -D typescript @types/node
   $ node ./node_modules/typescript/lib/tsc --init --lib es6 --outDir build --strictNullChecks false
   ```

5. Include an authentication library of your choice that implements the OAuth2 service account or web app flow. A good option is the [Google APIs Node.js Client](https://github.com/google/google-auth-library-nodejs), made for OAuth2 authorization and authentication with Google APIs.
   ```
   $ npm install -S google-auth-library
   ```

6. Implement the [GoogleOAuth2Client](https://github.com/havelessbemore/googleads-node-lib/tree/master/src/oauth2) interface using your authentication library. The interface should be implemented to meet your environment, OAuth2 workflow, and application requirements
   - Service account: See [GoogleOAuth2ServiceClient](https://github.com/havelessbemore/googleads-node-lib/blob/master/examples/server_side/src/oauth2/googleOAuth2ServiceClient.ts)
   * Web application: See [GoogleOAuth2WebAppClient](https://github.com/havelessbemore/googleads-node-lib/blob/master/examples/server_side/src/oauth2/googleOAuth2WebAppClient.ts)

7. Initialize your GoogleOAuth2Client with your OAuth2 credentials
   - Service account

     **Note**: Make sure your credentials are accessible to your project ([see here for details](https://developers.google.com/identity/protocols/application-default-credentials#howtheywork))
     ```typescript
     const oauth2Client: GoogleOAuth2Client = new GoogleServiceAccountClient();
     ```
   * Web application
     ```typescript
     // ...
     const oauth2Client: GoogleOauth2Client = new GoogleWebAppRefreshTokenClient(clientId, clientSecret, refreshToken);
     ```

8. Initialize a [DFP Client](https://github.com/havelessbemore/googleads-node-lib/blob/master/src/dfp/dfpClient.ts)
   ```typescript
   // ...
   const dfpClient = new dfp.DfpClient(oauth2Client, applicationName, networkCode/*,...*/);
   ```

9. Construct a SOAP client to a service and perform an operation. See the [DFP API reference docs](https://developers.google.com/doubleclick-publishers/docs/rel_notes) for available services / operations

   - Using callbacks
   ```typescript
   // Create a network service
   dfpClient.getService<dfp.NetworkService>('NetworkService', (err, service) => {
      if (err) {
         // ...
      }

      // Request the current network and get the response
      service.getCurrentNetwork({}, (err, res) => {
         if (err) {
            // ...
         }

         // Print out some network information
         const network = res.rval;
         console.log(`Current network has network code ${network.networkCode}`);
         console.log(`Current network has display name "${network.displayName}"`);
      });
   ```
   - Using promises
   ```typescript
   // Create a network service
   dfpClient.getService<dfp.NetworkService>('NetworkService')

   // Request the current network and get the response
   .then(service => service.getCurrentNetwork({}))

   // Print out some network information
   .then(res => {
      const network = res.rval;
      console.log(`Current network has network code ${network.networkCode}`);
      console.log(`Current network has display name "${network.displayName}"`);
   });
   ```

   - Using async / await
   ```typescript
    // Create a network service
    const service = await dfpClient.getService<dfp.NetworkService>('NetworkService');

    // Request the current network and get the response
    const res = await service.getCurrentNetwork({});

    // Print out some network information
    const network = res.rval;
    console.log(`Current network has network code ${network.networkCode}`);
    console.log(`Current network has display name "${network.displayName}"`);
   ```

### Use client-side

1. Download the minified library ([from here](https://github.com/havelessbemore/googleads-node-lib/tree/master/dist)) and include it on your site
   ```html
   <script type="text/javascript" src="./PATH/TO/googleads.dfp.min.js"></script>
   <script type="text/javascript" src="./PATH/TO/googleads.oauth2.min.js"></script>
   ```
2. Include an authentication library of your choice that implements the OAuth2 web app flow. A good option is the [Google JS Client library](https://developers.google.com/api-client-library/javascript/), made for OAuth2 authorization and authentication with Google APIs. [See here for an example](https://github.com/havelessbemore/googleads-node-lib/tree/master/examples/client_side)
   ```html
   <script type="text/javascript" src="https://apis.google.com/js/api.js"></script>
   ```
3. Implement the [GoogleOAuth2Client](https://github.com/havelessbemore/googleads-node-lib/blob/master/src/oauth2/googleOAuth2Client.ts) interface using your authentication library. The interface should be implemented to meet your environment, OAuth2 workflow, and application requirements
   - Web application: See [GoogleOAuth2WebAppClient](https://github.com/havelessbemore/googleads-node-lib/blob/master/examples/client_side/src/static/oauth2/googleOAuth2WebAppClient.js)

4. Setup a proxy server & initialize a [DFP Proxy](https://github.com/havelessbemore/googleads-node-lib/blob/master/src/common/proxy.ts)

   **Note**: Not required for Chrome extensions. [See here](https://developer.chrome.com/extensions/xhr) for more details

   DFP API servers are not currently setup for [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS), so a proxy must be used to forward the HTTPS SOAP requests. You can choose to use a trusted proxy or implement one yourself. [See here for a simple example](https://github.com/havelessbemore/googleads-node-lib/blob/master/examples/client_side/src/httpServer.ts)

   ```js
   const proxy = new dfp.Proxy({
      hostname: proxyHostname, //e.g. localhost
      port: proxyPort, // e.g. 80
      path: proxyPath, // e.g. /foo/bar
      protocol: proxyPortocol // e.g. http or https
   });
   ```

5. Initialize your GoogleOAuth2Client with your OAuth2 credentials
   ```js
   // ...
   const oauth2Client = new GoogleWebAppOauth2Client(gapi);
   ```

6. Initialize a [DFP Client](https://github.com/havelessbemore/googleads-node-lib/blob/master/src/dfp/dfpClient.ts)
   ```js
   // ...
   const dfpClient = new dfp.DfpClient(oauth2Client, applicationName, networkCode, cache, proxy /*, ...*/);
   ```

7. Construct a SOAP client to a service and perform an operation. See the [DFP API reference docs](https://developers.google.com/doubleclick-publishers/docs/rel_notes) for available services / operations

   - Using callbacks
   ```js
   // Create a network service
   dfpClient.getService('NetworkService', (err, service) => {
      if (err) {
         // ...
      }

      // Request the current network and get the response
      service.getCurrentNetwork({}, (err, res) => {
         if (err) {
            // ...
         }

         // Print out some network information
         const network = res.rval;
         console.log(`Current network has network code ${network.networkCode}`);
         console.log(`Current network has display name "${network.displayName}"`);
      });
   ```
   - Using promises
   ```js
   // Create a network service
   dfpClient.getService('NetworkService')

   // Request the current network and get the response
   .then(service => service.getCurrentNetwork({}))

   // Print out some network information
   .then(res => {
      const network = res.rval;
      console.log(`Current network has network code ${network.networkCode}`);
      console.log(`Current network has display name "${network.displayName}"`);
   });
   ```

   - Using async / await
   ```js
    // Create a network service
    const service = await dfpClient.getService('NetworkService')

    // Request the current network and get the response
    const res = await service.getCurrentNetwork({});

    // Print out some network information
    const network = res.rval;
    console.log(`Current network has network code ${network.networkCode}`);
    console.log(`Current network has display name "${network.displayName}"`);
   ```
### Getting support

For client library specific bug reports and patches, please create an issue on the [issue tracker](https://github.com/havelessbemore/googleads-node-lib/issues).

  For general DFP API questions, bug reports, or feature requests, please post to the official API forums:
  * [AdWords API Forum](https://groups.google.com/group/adwords-api)
  * [DoubleClick for Publishers API Forum](https://groups.google.com/forum/#!forum/google-doubleclick-for-publishers-api)

### Useful References

  - The DFP API Reference Guide for Developers
    * [Get Started](https://developers.google.com/doubleclick-publishers/docs/start)
    * [Authentication](https://developers.google.com/doubleclick-publishers/docs/authentication)
    * [Release Notes](https://developers.google.com/doubleclick-publishers/docs/rel_notes)

  * [The Google Auth Library for Node.js](https://github.com/google/google-auth-library-nodejs)

  - [The Google API Client Library for JavaScript](https://developers.google.com/api-client-library/javascript/start/start-js)
