Skip to main content

global class GoogleRatingBatch implements Database.Batchable<SObject>, Database.AllowsCallouts {

    

    private Map<Id, Double> accountIdToRatingMap = new Map<Id, Double>();

 

    global Database.QueryLocator start(Database.BatchableContext BC) {

        // Adjust this query to match your criteria for selecting accounts

        String query = 'SELECT Id, Name, inflooens__Google_Rating__c, inflooens__Review_Count__c FROM Account WHERE RecordType.Name = \'Business Account\'';

        return Database.getQueryLocator(query);

    }

 

    global void execute(Database.BatchableContext BC, List<Account> scope) {

        List<String> companyNames = new List<String>();

        List<Account> accountsToUpdate = new List<Account>();

 

        for (Account acc : scope) {

            companyNames.add(acc.Name);

        }

 

        Map<String, String> companyNameToPlaceIdMap = getPlaceIds(companyNames);

Double rating;

    integer reviewcount;

        for (Account acc : scope) {

            String companyName = acc.Name;

            String placeId = companyNameToPlaceIdMap.get(companyName);

 

            if (placeId != null) {

                accountIdToRatingMap.put(acc.Id, getGoogleRating(placeId));

            }

            rating = getGoogleRating(placeId);

            if (rating != null) {

                accountIdToRatingMap.put(acc.Id, rating);

            }

            

        }

 

        for (Account acc : scope) {

            if (accountIdToRatingMap.containsKey(acc.Id)) {

                acc.inflooens__Google_Rating__c  = String.valueOf(accountIdToRatingMap.get(acc.Id));

                acc.inflooens__Review_Count__c = rating.intValue(); // Convert to integer as needed

                accountsToUpdate.add(acc);

            }

        }

 

        // Update all modified accounts in a single DML operation

        if (!accountsToUpdate.isEmpty()) {

            update accountsToUpdate;

        }

    }

 

    global void finish(Database.BatchableContext BC) {

        // Execute any post-processing logic here

    }

 

    // Method to get Google Place IDs using Google Places API

  // Method to get Google Place IDs using Google Places API

private Map<String, String> getPlaceIds(List<String> companyNames) {

    Map<String, String> companyNameToPlaceIdMap = new Map<String, String>();

    String apiKey = getKey();//'AIzaSyCVUVkHPEjSJOpIu1lbirhvJRaqJ4hArr0';

 

    HttpRequest req = new HttpRequest();

    req.setMethod('GET');

    req.setEndpoint('https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=' + EncodingUtil.urlEncode(String.join(companyNames, ','), 'UTF-8') + '&inputtype=textquery&key=' + apiKey);

 

    Http http = new Http();

    HttpResponse res = http.send(req);

 

    if (res.getStatusCode() == 200) {

        String responseBody = res.getBody();

        Map<String, Object> jsonMap = (Map<String, Object>) JSON.deserializeUntyped(responseBody);

 

        if (jsonMap.containsKey('status') && jsonMap.get('status').equals('OK')) {

            List<Object> candidates = (List<Object>) jsonMap.get('candidates');

            for (Integer i = 0; i < Math.min(candidates.size(), companyNames.size()); i++) {

                Map<String, Object> candidate = (Map<String, Object>) candidates[i];

                String placeId = (String) candidate.get('place_id');

                companyNameToPlaceIdMap.put(companyNames[i], placeId);

            }

        } else {

            System.debug('Error in the response. Status: ' + jsonMap.get('status'));

        }

    } else {

        System.debug('Error: ' + res.getStatusCode() + ' ' + res.getStatus());

    }

 

    return companyNameToPlaceIdMap;

}

 

    // Method to get Google ratings using Google Places API

    private Double getGoogleRating(String placeId) {

        String apiKey = getKey();//'AIzaSyCVUVkHPEjSJOpIu1lbirhvJRaqJ4hArr0';

 

        HttpRequest req = new HttpRequest();

        req.setMethod('GET');

        req.setEndpoint('https://maps.googleapis.com/maps/api/place/details/json?placeid=' + placeId + '&fields=name,rating,reviewcount&key=' + apiKey);

 

        Http http = new Http();

        HttpResponse res = http.send(req);

 

        if (res.getStatusCode() == 200) {

            String responseBody = res.getBody();

            Map<String, Object> jsonMap = (Map<String, Object>) JSON.deserializeUntyped(responseBody);

 

            if (jsonMap.containsKey('status') && jsonMap.get('status').equals('OK')) {

                Map<String, Object> result = (Map<String, Object>) jsonMap.get('result');

                if (result != null && result.containsKey('rating')) {

                    return (Double) result.get('rating');

                }

                if(result!=null && result.containsKey('reviewcount')){

                    return (integer) result.get('reviewcount');

                }

            }

        }

 

        return null;

    }

   public static string getKey(){

        ApexTriggerSettings__c setting = ApexTriggerSettings__c.getValues('Inflooens Trigger Settings');

       

        String apiKey;// = 'AIzaSyCVUVkHPEjSJOpIu1lbirhvJRaqJ4hArr0';

        if(setting != NULL && setting.inflooens__Google_API_Key__c != NULL)

            apiKey=setting.inflooens__Google_API_Key__c;

        return apiKey;

    }

}

 

#BatchClass

2 answers
  1. Feb 22, 2024, 6:49 AM

    Hello @kaustubh chandratre, do you manage to get both calls done ? Does your second call's pass the good place id in parameter, and does the response body looks correct with rating inside ? Eric

0/9000