-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathGoogleMapsCallout.cls
More file actions
179 lines (154 loc) · 6.89 KB
/
GoogleMapsCallout.cls
File metadata and controls
179 lines (154 loc) · 6.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
Prior to running this class you will need to get an API Key
https://developers.google.com/maps/documentation/geocoding/get-api-key
For a full description of the JSON response visit:
https://developers.google.com/maps/documentation/geocoding/intro#GeocodingResponses
isStrictMode = True - will set all address fields to new values
if result is ROOFTOP or APPROXIMATE
isStrictMode = False - updates only the values that Google returns
this may produce less accurate responses as this includes RANGE_INTERPOLATED
and GEOMETRIC_CENTER
For more details about these codes visit:
https://developers.google.com/maps/documentation/geocoding/intro#Results
*/
public class GoogleMapsCallout
{
// set the variables for the API callout
Static String APIkey = '&key=';
Static String URLEndpoint = 'https://maps.googleapis.com/maps/api/geocode/json?address=';
Static Boolean isStrictMode = True;
// class for setting the address fields
class GeoProps {
String street_number = '';
String city = '';
String state_short = '';
String country_short = '';
String postal_code = '';
String street_name = '';
}
/*
Updates the values in Salesforce based on isStrictMode
if isStrictMode is True, then all values are replaced, this could include NULL
if isStrictMode is False, only fields with new values are replaced
@param accountId
The account Id of which to update in Salesforce
@param gpObj
The GeoProps instance that was used to store the results from Google API
*/
private Static void updateAcctAddress(Id accountId, GeoProps gpObj)
{
Account targetAccount = new Account(Id=accountId);
if (isStrictMode) {
targetAccount.billingStreet = gpObj.street_number + ' ' + gpObj.street_name;
targetAccount.billingCity = gpObj.city;
targetAccount.billingState = gpObj.state_short;
targetAccount.billingCountry = gpObj.country_short;
targetAccount.billingPostalCode = gpObj.postal_code;
} else {
if ((!String.isBlank(gpObj.street_number)) || (!String.isBlank(gpObj.street_name))) {
targetAccount.billingStreet = gpObj.street_number + ' ' + gpObj.street_name;
targetAccount.billingStreet.normalizeSpace();
}
if (!String.isBlank(gpObj.city)) {
targetAccount.billingCity = gpObj.city;
}
if (!String.isBlank(gpObj.state_short)) {
targetAccount.billingState = gpObj.state_short;
}
if (!String.isBlank(gpObj.country_short)) {
targetAccount.billingCountry = gpObj.country_short;
}
if (!String.isBlank(gpObj.postal_code)) {
targetAccount.billingPostalCode = gpObj.postal_code;
}
}
update targetAccount;
}
/*
Creates an HTTP request to the Google Maps API.
Receives the response from the API for the address that was passed.
The response is then parsed to obtain the correct address fields.
The data is then passed to the updateAcctAddress.
*/
//future callout class to google geocode api
@future (callout = true)
public static void getGoogleGeo(String addy, Id acctId)
{
// encode the address passed in the parameters
String addyEncoded = EncodingUtil.urlEncode(addy, 'UTF-8');
// create the get request
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setEndpoint(URLEndpoint + addyEncoded + APIkey);
system.debug(request);
request.setMethod('GET');
HttpResponse response;
try {
response = http.send(request);
}
catch (System.CalloutException e) {
System.debug('ERROR:' + e);
System.debug(response.getStatusCode());
System.debug(response.getStatus());
return;
}
if (response.getStatusCode() != 200) {
system.debug('Google Maps API code != 200 ' + response.getStatusCode());
return;
}
GeoProps gp = new GeoProps();
// Check if API status was successful
Map<String, Object> gresults = (Map<String, Object>)JSON.deserializeUntyped(response.getBody());
system.debug('results: ' + gresults.get('results'));
system.debug('status: ' + gresults.get('status'));
if (gresults.get('status') != 'OK') {
system.debug('GMap API status not OK');
return;
}
List<Object> gresultsList = (List<Object>)gresults.get('results');
system.debug('gresultsList: ' + gresultsList[0]);
Map<String, Object> addressComponents = (Map<String, Object>)gresultsList[0];
List<Object> addressComponentsList = (List<Object>)addressComponents.get('address_components');
if (isStrictMode == TRUE) {
Map<String, Object> geometryList = (Map<String, Object>)addressComponents.get('geometry');
String locationType = (String)geometryList.get('location_type');
system.debug('print location type:' + locationType);
// Location Type is the particular type of result produced
// See above comments for link to Google API
if (locationType != 'ROOFTOP' && locationType != 'APPROXIMATE') {
return;
}
}
// Loop through the Address Component to get each relevant address value
for (Object component : addressComponentsList) {
Map<String, Object> componentMap = (Map<String, Object>)component;
List<Object> geoTypes = (List<Object>)componentMap.get('types');
if (geoTypes.contains('street_number')) {
gp.street_number = (String)componentMap.get('short_name');
}
else if (geoTypes.contains('route')) {
gp.street_name = (String)componentMap.get('short_name');
}
else if (geoTypes.contains('country')) {
gp.country_short = (String)componentMap.get('short_name');
}
else if (geoTypes.contains('locality')) {
gp.city = (String)componentMap.get('short_name');
}
else if (geoTypes.contains('postal_town')) {
gp.city = (String)componentMap.get('short_name');
}
else if (geoTypes.contains('administrative_area_level_1')) {
gp.state_short = (String)componentMap.get('short_name');
}
else if (geoTypes.contains('postal_code')) {
gp.postal_code = (String)componentMap.get('short_name');
}
}
system.debug(gp);
// Pass id and geoprops to the updateAcctAddress function
if (gp != NULL) {
updateAcctAddress(acctId, gp);
}
}
}