I am trying to call the USPS Address Validation API from within Google Apps Script. It requires XML, which I am inexperienced with compared to JSON. Here is another stackoverflow question that is similar (How do I get domestic shipping rates via the USPS API using Google Apps Script?), and I have followed it to a "t", but it is different enough and when adapted for the USPS Address Validation API, it is not working for me. I have signed up for a userid and received a confirmation from USPS.
Here is the USPS Address Validation API documentation: https://www.usps.com/business/web-tools-apis/address-information-api.htm#_Toc34052588.
Here is my Apps Script Code (with the USPS userid changed for confidentiality):
var site = 'https://secure.shippingapis.com/ShippingAPI.dll';
var userid = "999ABCDE9999";
var payload = {
"API": "Verify",
"XML" : "<AddressValidateRequest USERID=\"" + userid + "\"> \
<Revision>0</Revision> \
<Address ID=\"0\"> \
<Address2>" + address1 + "</Address2> \
<City>" + city1 + "</City> \
<State>" + state1 + "</State> \
<Zip5>" + zip1 + "</Zip5> \
</Address> \
</AddressValidationRequest>"
};
var options = {
method: "POST",
payload: payload
}
Logger.log('payload = ' + JSON.stringify(payload));
var response = UrlFetchApp.fetch(site, options);
var xmlreturn = response.getContentText();
Logger.log('return xml = ' + xmlreturn);
Here are my logs (with the street address changed for confidentiality as well:
payload = {"API":"Verify","XML":"<AddressValidateRequest USERID=\"999ABCDE9999\"> <Revision>0</Revision> <Address ID=\"0\"> <Address2>123 AnyStreet Dr</Address2> <City>Forney</City> <State>TX</State> <Zip5>75126</Zip5> </Address> </AddressValidationRequest>"}
return xml = <?xml version="1.0" encoding="UTF-8"?>
<Error><Number>80040B19</Number><Description>XML Syntax Error: Please check the XML request to see if it can be parsed.(B)</Description><Source>USPSCOM::DoAuth</Source></Error>
This is the return/result I get regardless of what I try to do. I think, perhaps, a problem could be that payload.XML includes USERID=\"999ABCDE9999\" instead of what the documentation says it should - USERID="999ABCDE9999" (without the backslash), but I don't know how to get rid of those (and have tried).
Thank you for your help!
I figured out what the problem was. My only real problem was that I had my closing XML tag incorrect. It should be < /AddressValidateRequest > instead of < /AddressValidationRequest >. You ALSO need to include a self-closing < Address1/ > tag before < Address2 > and < Zip4/ > after < /Zip5 >. It will throw an error if you don't.
However, I'm glad I had the problem and posted it here, so that hopefully this will help others in the future to have the code pretty much the way you'll need it for a USPS Validation request from Google Apps Script. I had not found this anywhere else. Here is the final code, then I'll talk about how I worked with the result below as well.
var userid = 'Enter the ID USPS Gave you when you signed up here';
var url = 'https://secure.shippingapis.com/ShippingAPI.dll';
var payload = {
"API": "Verify",
"XML" : "<AddressValidateRequest USERID=\"" + userid + "\"> \
<Revision>1</Revision> \
<Address ID=\"0\"> \
<Address1/> \
<Address2>" + address1 + "</Address2> \
<City>" + city1 + "</City> \
<State>" + state1 + "</State> \
<Zip5>" + zip1 + "</Zip5> \
<Zip4/> \
</Address> \
</AddressValidateRequest>"
};
var options = {
"method": "POST",
"payload": payload,
muteHttpExceptions: true
}
// Use a try & catch routine to catch any major errors.
try {
var response = UrlFetchApp.fetch(url, options);
}
catch (e) {
Logger.log(e);
continue; // If there is an error (i.e. the API service is not available), then skip the rest of the logic for this row.
}
var xmlReturn = response.getContentText();
Once you have the "xmlreturn" (as I called it above) from the fetch, you'll need to parse the XML response to get each piece of the address returned from USPS. Here is how I did it using regex for Address Line 2. You do the same pretty much for the other pieces, just changing your regex slightly.
// *********************************
// Get Address Line 2
// *********************************
var uspsAddress2Reg = /(?<=<Address2>)[^]+(?=<\/Address2>)/g;
var uspsAddress2Arr =xmlReturn.match(uspsAddress2Reg);
// If we found the Address Line 2 in the following format: <Address2>1234 ANYSTREET DRIVE</Address2>
if (uspsAddress2Arr != null) {
var uspsAddress2 = uspsAddress2Arr[0];
} else {
var uspsAddress2 = ''; // If not found, set it to blank.
} // End If (uspsAddress2Arr != null)