Google Apps Script

Tutorial: Accessing a Soap Service

Cyrus Najmabadi, Google Apps Script Team
Dec 2009

Goal

This tutorial guides you through the steps of invoking a Soap service operation.

Time to Complete

Approximately 20 minutes

Index

This tutorial is divided into the following sections:


Section 1: Creating a Wsdl Object

To help demonstrate this, we will use a simple and free SOAP web service provided by WebserviceX called GeoIPService. This web service allows you to easily look up the country of origin for a given IP Address.

To use the SOAP library, the first thing you need is the WSDL file associated with the web service. WSDL (which stands for 'Web Service Definition Language') files contain the necessary metadata to let the library know where the service can be reached and which operations can be used.

For this service, the WSDL can be found at "http://www.webservicex.net/geoipservice.asmx?wsdl". Feel free to take a look. It's just a small XML file that describes what services and operations are available, and what types of arguments they expect to be given.

Once you have the location of the WSDL file, you can start using it in Google Apps Script like so:

  var wsdl = SoapService.wsdl("http://www.webservicex.net/geoipservice.asmx?wsdl");

Section 2: Querying a Wsdl Object

SoapService.wsdl will return an object of type Wsdl that has several helpful methods on it to help you introspect the WSDL description at the specified location. For now, we'll use the method getServiceNames to determine what services are available. Normally, there will just be a single service available, but sometimes there might be more. You can invoke this method and log the results like so:

  Logger.log(wsdl.getServiceNames());

Running this and checking the log, you will see that one service was returned: 'GeoIPService'. (If you look at the original WSDL file, you'll see that this was the one service defined in it like so:

  <wsdl:service name="GeoIPService">

Section 3: Getting a WsdlService Object

Now, we can start checking out that service to see what operations it makes available. There are two methods to get to the actual service. The first is to simply call getService on the Wsdl object with the name of the service returned above. i.e.:

  var geoService = wsdl.getService("GeoIPService");

The second is to get it like so:

  var geoService = wsdl.getGeoIPService();

How is it that this object has a method on it that's so specific to this particular web service? Thanks to the power of javascript's dynamic type system, the soap library is able to generate these convenience methods for you so your code can be far more direct about what it's trying to do without having to pass strings around all the time. So why would you ever use the first form? Sometimes SOAP services will have names for things that can't be represented in Javascript. For these situations, the first form provides a system that will always work no matter what the service name is.

Section 4: Querying a WsdlService Object

Now that you have the Service object, it's time to figure out what you can do with it. For that, you use the helpful getOperationNames method. As before, here's how you can invoke that method and log the result to take a look at:

  Logger.log(geoService.getOperationNames());

This will return the following result: [GetGeoIP, GetGeoIPContext] . As expected, these are the same names of the operations listed on the original WebservicesX page. For this example, you're going to want to invoke the GetGeoIP method whose documentation says that it "enables you to easily look up countries by IP addresses."

Section 5: Creating Web Service Paramaters

Now that you've found the operations we want, it's time to invoke your first web service. For this step it can be helpful to see how the web service is invoked currently. To determine this, you can either use one of the many Soap tools out there. Or, conveniently, WebserviceX has has pages that demonstrate their web services in action. You can try this out not by going from the original WebservicesX page to the specific operation page for GetGeoIP. On this page you can experiment by plugging in your own IP address, or just a sample IP address like "72.14.228.129".

On the WebserviceX demonstration page you can see documentation showing that the web service is invoked with a message like so:

  POST /geoipservice.asmx HTTP/1.1
  Host: www.webservicex.net
  Content-Type: text/xml; charset=utf-8
  Content-Length: length
  SOAPAction: "http://www.webservicex.net/GetGeoIP"

  <?xml version="1.0" encoding="utf-8"?>
  <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                 xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
      <GetGeoIP xmlns="http://www.webservicex.net/">
        <IPAddress>72.14.228.129</IPAddress>
      </GetGeoIP>
    </soap:Body>
  </soap:Envelope>

This would normally be a lot of infrastructure for you to handle. However, the Soap library will take care of most of this for you! All you need to provide is the following section from inside the <soap:Body> tag, and the library will take care of the rest:

    <GetGeoIP xmlns="http://www.webservicex.net/">
      <IPAddress>72.14.228.129</IPAddress>
    </GetGeoIP>

To generate this snippet of Xml several helper methods are provided. For the above, you would use the following code:

  var param = Xml.element("GetGeoIP", [
                Xml.attribute("xmlns", "http://www.webservicex.net/"),
                Xml.element("IPAddress", [
                  "72.14.228.129"
                ])
              ]);

For full details on creating XML, please see the Xml Documentation.

Section 6: Testing a Soap Operation

Once you've created the parameter to pass to the web service, you can verify that the right message is being created by using the debugging method 'getSoapEnvelope' on the service object. This method does every step of the soap operation except for actually sending the message to the service on the Internet. This lets you see what is being generated in case you need to tweak or debug things. You can try it and check the results like so:

  var envelope = geoService.getSoapEnvelope("GetGeoIP", param)
  Logger.log(envelope);

In the logs you should now see:

  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                     xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
                     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Body>
      <GetGeoIP xmlns="http://www.webservicex.net/">
        <IPAddress>72.14.228.129</IPAddress>
      </GetGeoIP>
    </SOAP-ENV:Body>
  </SOAP-ENV:Envelope>

This is exactly the same as the XML shown above (except for some minor changes in how namespaces are named). With this, you can see that the message looks right and it's finally time to invoke the web service.

Section 7: Invoking a Soap Operation

To invoke the web service, two methods are provided. You can either call:

  var result = geoService.invokeOperation("GetGeoIP", [param]);

or

  var result = geoService.GetGeoIP(param);

As before (with getService ), we have automatically generated the method name from information in the WSDL file to make it easy for you to invoke. The latter form makes the code simple simpler and allows you to invoke the service with a minimum of fuss. However, if the operation name cannot be expressed in javascript, the former form is provided so that you can always invoke it.

Section 8: Working with a Soap Operation Result

Now that you've invoked the SOAP operation, it's time to work with the result provided. Because SOAP is a system for passing XML messages back and forth, the result returned is itself XML. To view the XML, you can call the help debugging method 'toXmlString' on it like so:

  Logger.log(result.toXmlString());

In the logs you'll now see:

  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  <GetGeoIPResponse xmlns="http://www.webservicex.net/">
    <GetGeoIPResult>
      <ReturnCode>1</ReturnCode>
      <IP>72.14.228.129</IP>
      <ReturnCodeDetails>Record Found</ReturnCodeDetails>
      <CountryName>UNITED STATES</CountryName>
      <CountryCode>US</CountryCode>
    </GetGeoIPResult>
  </GetGeoIPResponse>

To get to the information we want (i.e. the country code for the IP address) you can now simply "dot" into the returned XML object in a very natural way like so:

  Logger.log(result.Envelope.Body.GetGeoIPResponse.GetGeoIPResult.CountryCode.Text);

These helpful properties were generated for you by the Xml library. You can reach nested elements with their tag name, and you can get the text contents of an Xml element with the "Text" property.

For full information on how to simply access information in an XML document, please see the Xml Documentation. Checking the logs you will now see "US" printed.

Summary and Complete Code

And now you've done it! You've been able to go from an arbitrary IP address to the country that it belongs to in just a few simple steps. Here's the code in its entirety:

  function determineCountryFromIP(ipAddress) {
    var wsdl = SoapService.wsdl("http://www.webservicex.net/geoipservice.asmx?wsdl");
    var geoService = wsdl.getGeoIPService();

    var param = Xml.element("GetGeoIP", [
                  Xml.attribute("xmlns", "http://www.webservicex.net/"),
                  Xml.element("IPAddress", [
                    ipAddress
                  ])
                ]);

    var result = geoService.GetGeoIP(param);
    return result.Envelope.Body.GetGeoIPResponse.GetGeoIPResult.CountryCode.Text;
  }

It's just that simple to now call into a soap service anywhere and process the result that you get back!

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.