Google Adwords Java Integration

Step 1: Create Google AdwordSession configuration

package com.integration.adwords.config;

import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.lib.client.AdWordsSession;
import com.google.api.ads.adwords.lib.client.reporting.ReportingConfiguration;
import com.google.api.ads.common.lib.auth.OfflineCredentials;
import com.google.api.ads.common.lib.exception.OAuthException;
import com.google.api.ads.common.lib.exception.ValidationException;
import com.google.api.client.auth.oauth2.Credential;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Created by tmichels on 7/31/15.
 */

@Configuration
public class GoogleAdwordsConfig {

    @Value("${GOOGLE_ADWORD_CLIENTID}")
    private String googleAdWordClientId;

    @Value("${GOOGLE_ADWORD_SECRET}")
    private String googleAdwordSecet;

    @Value("${GOOGLE_ADWORDS_DEV_TOKEN}")
    private String googleAdwordDevToken;

    @Value("${GOOGLE_ADWORDS_REFRESH_TOKEN}")
    private String googleAdwordRefreshToken;

    @Value("${GOOGLE_ADWORDS_USER_AGENT}")
    private String googleAdwordUserAgent;

    @Value("${GOOGLE_ADWORDS_CLIENT_CUSTOMER_ID}")
    private String googleAdwordClientCustomerId;

    @Bean
    public Credential credential() throws ValidationException, OAuthException {
        Credential credential = new OfflineCredentials.Builder()
                                .forApi(OfflineCredentials.Api.ADWORDS)
                                .withClientSecrets(googleAdWordClientId, googleAdwordSecet)
                                .withRefreshToken(googleAdwordRefreshToken)
                                .build()
                                .generateCredential();
        return credential;
    }

    @Bean
    public AdWordsSession adWordsSession(Credential credential) throws ValidationException {
        AdWordsSession adWordsSession = new AdWordsSession.Builder()
                                        .withDeveloperToken(googleAdwordDevToken)
                                        .withOAuth2Credential(credential)
                                        .withClientCustomerId(googleAdwordClientCustomerId)
                                        .withUserAgent(googleAdwordUserAgent)


                .build();
        return adWordsSession;
    }
}

2. Create AdWord Service to export KeyWords, Campaigns, AdGroups and Ads.

package com.integration.adwords.service;

import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.utils.v201506.SelectorBuilder;
import com.google.api.ads.adwords.axis.v201506.cm.*;
import com.google.api.ads.adwords.lib.client.AdWordsSession;
import com.google.api.ads.adwords.lib.selectorfields.v201502.cm.CampaignField;
import com.google.api.ads.adwords.lib.selectorfields.v201506.cm.AdGroupAdField;
import com.google.api.ads.adwords.lib.selectorfields.v201506.cm.AdGroupCriterionField;
import com.google.api.ads.adwords.lib.selectorfields.v201506.cm.AdGroupField;
import com.integration.file.FileConverter;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by tmichels on 7/31/15.
 */

@Service
public class GoogleAdwordService {

    private static final Logger logger = org.slf4j.LoggerFactory.getLogger(GoogleAdwordService.class);

    private static final int PAGE_SIZE = 100;

    private static final String CAMPAIGNFILENAME="adwords/google/googleAdwordCampaign.csv";
    private static final String KEYWORDFILENAME="adwords/google/googleAdwordKeywords.csv";
    private static final String ADGROUPFILENAME="adwords/google/googleAdwordAdGroup.csv";
    private static final String ADSFILENAME="adwords/google/googleAdwordAds.csv";

    @Autowired
    AdWordsSession adWordsSession;

    @Autowired
    FileConverter fileConverter;

    public void getCampaigns() throws RemoteException {
        List<String> campaignColumns = new ArrayList<>();
        List<String> campaignData = new ArrayList<>();

        // Get the CampaignService.
        CampaignServiceInterface campaignService =
                new AdWordsServices().get(adWordsSession, CampaignServiceInterface.class);

        int offset = 0;

        // Create selector.
        SelectorBuilder builder = new SelectorBuilder();
        Selector selector = builder
                .fields(CampaignField.Id,
                        CampaignField.Name,
                        CampaignField.AdServingOptimizationStatus,
                        CampaignField.AdvertisingChannelSubType,
                        CampaignField.AdvertisingChannelType,
                        CampaignField.BiddingStrategyId,
                        CampaignField.BiddingStrategyName,
                        CampaignField.BiddingStrategyType,
                        CampaignField.BidType,
                        CampaignField.BudgetId,
                        CampaignField.BudgetName,
                        CampaignField.BudgetReferenceCount,
                        CampaignField.BudgetStatus,
                        CampaignField.DeliveryMethod,
                        CampaignField.Eligible,
                        CampaignField.EndDate,
                        CampaignField.FrequencyCapMaxImpressions,
                        CampaignField.Labels,
                        CampaignField.StartDate,
                        CampaignField.TrackingUrlTemplate,
                        CampaignField.UrlCustomParameters)
                .orderAscBy(CampaignField.Id)
                .offset(offset)
                .limit(PAGE_SIZE)
                .build();

        campaignColumns.add(CampaignField.Id.toString());
        campaignColumns.add(CampaignField.Name.toString());
        campaignColumns.add(CampaignField.AdServingOptimizationStatus.toString());
        campaignColumns.add(CampaignField.AdvertisingChannelSubType.toString());
        campaignColumns.add(CampaignField.AdvertisingChannelType.toString());
        campaignColumns.add(CampaignField.BiddingStrategyId.toString());
        campaignColumns.add(CampaignField.BiddingStrategyName.toString());
        campaignColumns.add(CampaignField.BiddingStrategyType.toString());
        campaignColumns.add(CampaignField.BidType.toString());
        campaignColumns.add(CampaignField.BudgetId.toString());
        campaignColumns.add(CampaignField.BudgetName.toString());
        campaignColumns.add(CampaignField.BudgetReferenceCount.toString());
        campaignColumns.add(CampaignField.BudgetStatus.toString());
        campaignColumns.add(CampaignField.DeliveryMethod.toString());
        campaignColumns.add(CampaignField.Eligible.toString());
        campaignColumns.add(CampaignField.EndDate.toString());
        campaignColumns.add(CampaignField.FrequencyCapMaxImpressions.toString());
        campaignColumns.add(CampaignField.Labels.toString());
        campaignColumns.add(CampaignField.StartDate.toString());
        campaignColumns.add(CampaignField.TrackingUrlTemplate.toString());
        campaignColumns.add(CampaignField.UrlCustomParameters.toString());

        CampaignPage page = null;
        do {
            // Get all campaigns.
            page = campaignService.get(selector);

            // Display campaigns.
            if (page.getEntries() != null) {
                for (Campaign campaign : page.getEntries()) {
                    campaignData.add(campaign.getId().toString());
                    campaignData.add(campaign.getName());
                    campaignData.add(campaign.getAdServingOptimizationStatus()!=null? campaign.getAdServingOptimizationStatus().toString() : "");
                    campaignData.add(campaign.getAdvertisingChannelSubType() != null ? campaign.getAdvertisingChannelSubType().toString() : "");
                    campaignData.add(campaign.getAdvertisingChannelType().toString());
                    campaignData.add(campaign.getBiddingStrategyConfiguration().getBiddingStrategyId() != null ? campaign.getBiddingStrategyConfiguration().getBiddingStrategyId().toString() : "");
                    campaignData.add(campaign.getBiddingStrategyConfiguration().getBiddingStrategyName());
                    campaignData.add(campaign.getBiddingStrategyConfiguration().getBiddingStrategyType() != null ? campaign.getBiddingStrategyConfiguration().getBiddingStrategyType().getValue() : "");
                    campaignData.add(campaign.getBudget().getBudgetId() != null ? campaign.getBudget().getBudgetId().toString() : "");
                    campaignData.add(campaign.getBudget().getName());
                    campaignData.add(campaign.getBudget().getReferenceCount() != null ? campaign.getBudget().getReferenceCount().toString() : "");
                    campaignData.add(campaign.getBudget().getStatus() != null ? campaign.getBudget().getStatus().getValue() : "");
                    campaignData.add(campaign.getBudget().getDeliveryMethod() != null ? campaign.getBudget().getDeliveryMethod().getValue() : "");
                    campaignData.add(campaign.getBudget().getIsExplicitlyShared() != null ? campaign.getBudget().getIsExplicitlyShared().toString() : "");
                    campaignData.add(campaign.getEndDate());
                    campaignData.add(campaign.getFrequencyCap()!=null && campaign.getFrequencyCap().getImpressions() != null ? campaign.getFrequencyCap().getImpressions().toString() : "");
                    campaignData.add(campaign.getLabels() != null ? campaign.getLabels().toString() : "");
                    campaignData.add(campaign.getStartDate());
                    campaignData.add(campaign.getTrackingUrlTemplate());
                    campaignData.add(campaign.getUrlCustomParameters()!=null &&  campaign.getUrlCustomParameters().getParameters() != null ? campaign.getUrlCustomParameters().getParameters().toString() : "");
                }
            } else {
                logger.info("No campaigns were found.");
            }

            offset += PAGE_SIZE;
            selector = builder.increaseOffsetBy(PAGE_SIZE).build();
        } while (offset < page.getTotalNumEntries());

        fileConverter.convertToCSV(campaignData, campaignColumns, CAMPAIGNFILENAME);
    }

    public void getKeyWords() throws RemoteException {
        List<String> campaignColumns = new ArrayList<>();
        List<String> campaignData = new ArrayList<>();

        // Get the AdGroupCriterionService.
        AdGroupCriterionServiceInterface adGroupCriterionService =
                new AdWordsServices().get(adWordsSession, AdGroupCriterionServiceInterface.class);

        int offset = 0;
        boolean morePages = true;

        // Create selector.
        SelectorBuilder builder = new SelectorBuilder();
        Selector selector = builder
                .fields(
                        AdGroupCriterionField.Id,
                        AdGroupCriterionField.AdGroupId,
                        AdGroupCriterionField.KeywordMatchType,
                        AdGroupCriterionField.KeywordText)
                .offset(offset)
                .limit(PAGE_SIZE)
                .equals(AdGroupCriterionField.CriteriaType, "KEYWORD")
                .build();

        campaignColumns.add(AdGroupCriterionField.Id.toString());
        campaignColumns.add(AdGroupCriterionField.AdGroupId.toString());
        campaignColumns.add(AdGroupCriterionField.KeywordMatchType.toString());
        campaignColumns.add(AdGroupCriterionField.KeywordText.toString());

        while (morePages) {
            AdGroupCriterionPage page = adGroupCriterionService.get(selector);

            if (page.getEntries() != null && page.getEntries().length > 0) {
                for (AdGroupCriterion adGroupCriterionResult : page.getEntries()) {
                    campaignData.add(adGroupCriterionResult.getAdGroupId().toString());
                    campaignData.add(adGroupCriterionResult.getCriterion().getId().toString());
                    campaignData.add(((Keyword) adGroupCriterionResult.getCriterion()).getText());
                    campaignData.add(((Keyword) adGroupCriterionResult.getCriterion()).getMatchType().toString());
                }
            } else {
                logger.info("No keywords were found.");
            }
            offset += PAGE_SIZE;
            selector = builder.increaseOffsetBy(PAGE_SIZE).build();
            morePages = offset < page.getTotalNumEntries();
        }

        fileConverter.convertToCSV(campaignData, campaignColumns, KEYWORDFILENAME);
    }

    public void getTextAds() throws RemoteException {
        List<String> campaignColumns = new ArrayList<>();
        List<String> campaignData = new ArrayList<>();

        AdGroupAdServiceInterface adGroupAdService =
                new AdWordsServices().get(adWordsSession, AdGroupAdServiceInterface.class);

        int offset = 0;
        boolean morePages = true;

        // Create selector.
        SelectorBuilder builder = new SelectorBuilder();
        Selector selector = builder
                .fields(AdGroupAdField.Id,
                        AdGroupAdField.AdGroupId,
                        AdGroupAdField.Status)
                .orderAscBy(AdGroupAdField.Id)
                .offset(offset)
                .limit(PAGE_SIZE)
                .in(AdGroupAdField.Status, "ENABLED", "PAUSED", "DISABLED")
                .build();

        campaignColumns.add(AdGroupAdField.Id.toString());
        campaignColumns.add(AdGroupAdField.AdGroupId.toString());
        campaignColumns.add(AdGroupAdField.Status.toString());

        while (morePages) {
            AdGroupAdPage page = adGroupAdService.get(selector);

            if (page.getEntries() != null && page.getEntries().length > 0) {
                for (AdGroupAd adGroupAd : page.getEntries()) {
                    campaignData.add(adGroupAd.getAd().getId().toString());
                    campaignData.add(adGroupAd.getAd().getAdType().toString());
                    campaignData.add(adGroupAd.getStatus().toString());
                }
            } else {
                logger.info("No text ads were found");
            }

            offset += PAGE_SIZE;
            selector = builder.increaseOffsetBy(PAGE_SIZE).build();
            morePages = offset < page.getTotalNumEntries();
        }

        fileConverter.convertToCSV(campaignData, campaignColumns, ADSFILENAME);

    }
    public void getAdGroups() throws RemoteException {
        List<String> campaignColumns = new ArrayList<>();
        List<String> campaignData = new ArrayList<>();

        AdGroupServiceInterface adGroupService = new AdWordsServices().get(adWordsSession, AdGroupServiceInterface.class);

        int offset = 0;
        boolean morePages = true;

        // Create selector.
        SelectorBuilder builder = new SelectorBuilder();
        Selector selector = builder
                .fields(AdGroupField.Id,
                        AdGroupField.Name,
                        AdGroupField.Status)
                .orderAscBy(AdGroupField.Name)
                .offset(offset)
                .limit(PAGE_SIZE)
                .build();

        campaignColumns.add(AdGroupField.Id.toString());
        campaignColumns.add(AdGroupField.Name.toString());
        campaignColumns.add(AdGroupField.Status.toString());

        while (morePages) {
            AdGroupPage page = adGroupService.get(selector);
            // Display ad groups.
            if (page.getEntries() != null) {
                for (AdGroup adGroup : page.getEntries()) {
                    campaignData.add(adGroup.getId().toString());
                    campaignData.add(adGroup.getName().toString());
                    campaignData.add(adGroup.getStatus()!=null ? adGroup.getStatus().getValue() : "");
                }
            } else {
                logger.info("No group ads were found.");
            }

            offset += PAGE_SIZE;
            selector = builder.increaseOffsetBy(PAGE_SIZE).build();
            morePages = offset < page.getTotalNumEntries();
        }
        fileConverter.convertToCSV(campaignData, campaignColumns, ADGROUPFILENAME);
    }
}

Google OAuth 2.0 Scribe Java Example

Google OAuthServiceConfig and OAuthServiceProvider Bean

<bean id="gdServiceConfig" class="com.example.oauth.OAuthServiceConfig">
		<constructor-arg value="xxx.apps.googleusercontent.com" />
		<constructor-arg value="xxx"/>
		<constructor-arg value="https://www.example.com/oauth/gd"/>
		<!-- <constructor-arg value="openid profile email https://www.googleapis.com/auth/drive.file"/> -->
		<constructor-arg value="com.example.oauth.GoogleDriveOauthApi"/>
	</bean>
	<bean id="gdServiceProvider" class="com.example.oauth.OAuthServiceProvider">
		<constructor-arg name="config" ref="gdServiceConfig" />
	</bean>
</bean>

Google OAuth Spring MVC Controller

package com.example.oauth.controller;

import static org.springframework.web.context.request.RequestAttributes.SCOPE_SESSION;

import java.util.Map;

import javax.servlet.http.HttpSession;

import org.scribe.model.Token;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.request.WebRequest;

import com.example.oauth.OAuthServiceProvider;

@Controller
@RequestMapping("/oauth/gd")
public class GoogleDriveController {

	@Autowired
	@Qualifier("gdServiceProvider")
	private OAuthServiceProvider gdServiceProvider;
	
	private static final Token EMPTY_TOKEN = null;
	
	@RequestMapping(value = "/login-gd", method = RequestMethod.GET)
	public String loginToGoogleDrive(Map<String, Object> map, WebRequest request) {
		OAuthService service = gdServiceProvider.getService();
		String auth = service.getAuthorizationUrl(EMPTY_TOKEN);
		System.out.println("RequestToken: " + auth);
		return "redirect:" + auth;
	}
	
	@RequestMapping(value={""}, method = RequestMethod.GET)
	public String callback(@RequestParam(value="oauth_token", required=false) String oauthToken,
			@RequestParam(value="code", required=false) String oauthVerifier, WebRequest request, Map<String, Object> map) {

		OAuthService service = gdServiceProvider.getService();

		// getting access token
		Verifier verifier = new Verifier(oauthVerifier);
		Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);

		// store access token as a session attribute
		request.setAttribute("oauthAccessToken", accessToken, SCOPE_SESSION);

		ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
		HttpSession session = attr.getRequest().getSession(false); //create a new session
		session.setAttribute("accessToken",accessToken);

		return "settings";
	}
}

Google OAuth extends DefaultApi20

package com.example.oauth;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.scribe.builder.api.DefaultApi20;
import org.scribe.extractors.AccessTokenExtractor;
import org.scribe.model.OAuthConfig;
import org.scribe.model.Verb;
import org.scribe.exceptions.OAuthException;
import org.scribe.model.OAuthConstants;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuth20ServiceImpl;
import org.scribe.oauth.OAuthService;
import org.scribe.utils.OAuthEncoder;
import org.scribe.utils.Preconditions;

public class GoogleDriveOauthApi extends DefaultApi20{

	  private static final String AUTHORIZE_URL = "https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=%s&redirect_uri=%s";
	    private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL + "&scope=%s";
	 
	    @Override
	    public String getAccessTokenEndpoint() {
	        return "https://accounts.google.com/o/oauth2/token";
	    }
	    
	    @Override
	    public AccessTokenExtractor getAccessTokenExtractor() {
	        return new AccessTokenExtractor() {
	            
	            @Override
	            public Token extract(String response) {
	                Preconditions.checkEmptyString(response, "Response body is incorrect. Can't extract a token from an empty string");
	 
	                Matcher matcher = Pattern.compile("\"access_token\" : \"([^&\"]+)\"").matcher(response);
	                if (matcher.find())
	                {
	                  String token = OAuthEncoder.decode(matcher.group(1));
	                  return new Token(token, "", response);
	                } 
	                else
	                {
	                  throw new OAuthException("Response body is incorrect. Can't extract a token from this: '" + response + "'", null);
	                }
	            }
	        };
	    }
	 
	    @Override
	    public String getAuthorizationUrl(OAuthConfig config) {
            return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(),
                    OAuthEncoder.encode(config.getCallback()),
                    OAuthEncoder.encode("openid profile email https://www.googleapis.com/auth/drive.file"));
	    }
	    
	    @Override
	    public Verb getAccessTokenVerb() {
	        return Verb.POST;
	    }
	    
	    @Override
	    public OAuthService createService(OAuthConfig config) {
	        return new GoogleOAuth2Service(this, config);
	    }
	    
	    private class GoogleOAuth2Service extends OAuth20ServiceImpl {
	 
	        private static final String GRANT_TYPE_AUTHORIZATION_CODE = "authorization_code";
	        private static final String GRANT_TYPE = "grant_type";
	        private DefaultApi20 api;
	        private OAuthConfig config;
	 
	        public GoogleOAuth2Service(DefaultApi20 api, OAuthConfig config) {
	            super(api, config);
	            this.api = api;
	            this.config = config;
	        }
	        
	        @Override
	        public Token getAccessToken(Token requestToken, Verifier verifier) {
	            OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint());
	            switch (api.getAccessTokenVerb()) {
	            case POST:
	                request.addBodyParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
	                request.addBodyParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
	                request.addBodyParameter(OAuthConstants.CODE, verifier.getValue());
	                request.addBodyParameter(OAuthConstants.REDIRECT_URI, config.getCallback());
	                request.addBodyParameter(GRANT_TYPE, GRANT_TYPE_AUTHORIZATION_CODE);
	                break;
	            case GET:
	            default:
	                request.addQuerystringParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
	                request.addQuerystringParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
	                request.addQuerystringParameter(OAuthConstants.CODE, verifier.getValue());
	                request.addQuerystringParameter(OAuthConstants.REDIRECT_URI, config.getCallback());
	                if(config.hasScope()) request.addQuerystringParameter(OAuthConstants.SCOPE, "openid profile email https://www.googleapis.com/auth/drive.file");
	            }
	            Response response = request.send();
	            return api.getAccessTokenExtractor().extract(response.getBody());
	        }
	    }
}

Apex Code: Visualforce Google Maps Customer Mapping

Create a Visualforce page to show all your customers addresses on Google Maps. Note there is a limit on the amount of Map pins that are set thus I created a timeout of a few seconds so Google does not show me pop-up an error message.

<apex:page controller="getCustomerAddress" sidebar="false" showChat="true">
<html>
<head>
<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> 
<script type="text/javascript"> 
 var arraddress= new Array();
 var arrids= new Array();
 var content=new Array();
 var arrnames= new Array();
 var i=0;
 
 var map;
 var geocoder;

function initialize() 
 {
 var mapDiv = document.getElementById('map-canvas');
 map = new google.maps.Map(mapDiv, 
 {
 zoom: 4,
 mapTypeId: google.maps.MapTypeId.ROADMAP 
 }
 );
 google.maps.event.addListenerOnce(map, 'idle', addMarkers);
 }
 
 function addMarkers() 
 {
 for (var i = 0; i < arraddress.length; i++) 
 {
 content[i] = arrnames[i]+' '+arraddress[i];
 geocodeAddress(arraddress[i],arrids[i],content[i]);
 }
 }
 
 function geocodeAddress(addds,id,content)
 {
 geocoder = new google.maps.Geocoder();
 
 geocoder.geocode( { 'address': addds}, function(results, status) 
 {
 if (status == google.maps.GeocoderStatus.OK) 
 {
 map.setCenter(results[0].geometry.location);
 
 var marker = new google.maps.Marker({map: map,position: results[0].geometry.location});
 var infowindow = new google.maps.InfoWindow({content: content});
google.maps.event.addListener(marker, 'mouseover', function() { infowindow.open(map,this);});
 
 google.maps.event.addListener(marker, 'mouseout', function() {infowindow.close();});
 google.maps.event.addListener(marker, 'click', function() { window.open('/'+id);});
 }
 else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) 
 { 
 setTimeout(function() {geocodeAddress(addds, id, content);}, 200);
 }
 else 
 {
 alert("Geocode was not successful for the following reason: " + status);
 }
 });
 }
 google.maps.event.addDomListener(window, 'load', initialize);
 
</script>
</head>
 <body style="font-family: Arial; border: 0 none;">
 <div id="map-canvas" style="width: 1500; height: 750px"></div>
 <apex:repeat value="{!Address}" var="a">
 <script>
 arraddress[i]= '{!a.BillingStreet}, {!a.BillingCity}, {!a.BillingPostalCode}, {!a.BillingCountry}';
 arrids[i]='{!a.id}';
 arrnames[i]='{!a.name}';
 i++;
 </script>
 </apex:repeat>
 </body>
 </html>
</apex:page>