//
you're reading...
IPAR, Misc

Exchanging Data With Hobsons Connect, Part 2

In my last post on this subject, I provided an overall framework for exchanging data with Hobsons Connect via web service calls.  In this post, I’ll provide specific examples of how to call web services from PowerShell. Although the examples in this post were written with Hobsons Connect product in mind, similar web services are available for the Retain product and in fact many of the functions are identical.

Hobsons Connect uses SOAP-based web services for communication.  SOAP, short for “Simple Object Access Protocol”, encapsulates input and output information in XML constructs.  There are five main steps for dealing with SOAP-based calls in PowerShell

  1. Instantiate a Web Service object.  This is done through a command such as  the following:

$ws=New-WebServiceProxy -uri $WSURL

where $WSURL  is a string representing the address of the web service — https://Services02.askadmissions.net/ws/bridge.asmx?wsdl for example

2.  Form the input XML.  Parameters or inputs to the function call are passed as XML strings.  Below is a simple example of an XML string assigned to a string variable.

$InputXML = ‘<attributes><attribute><name>firstname</name></attribute></attributes>’

Hobsons provides a number of different web service functions and the parameters for each call varies. Fortunately, Hobsons has created a document that describes each call and provides some examples.  This web service documentation is available at the link below:

http://static.askadmissions.net/_EMTFILES/messagecenter/articles/webservices.pdf

3. Call the Web Service function.  In the function call, you pass credentials and input XML strings. An example of a GetContact call is shown below:

  [String]$ReturnValue = $ws.GetContact($ClientName, $PassKey, $InputXML, $AttributeXML)

In most Connect service calls, you’ll need to supply a “Client Name” and “Pass Key” as credentials. These are represented in the call above by the  $ClientName and $PassKey variables respectively, and are unique strings provided to you by Hobsons. In this case, we also have two input strings, $InputXML and $AttributeXML.

4. Capture the output XML returned by the service call. In the sample call above, output is returned in the $ReturnValue variable.

5. Finally, you parse the output XML and do something with it.  You will see how this is done in some of the examples that follow.

Let’s look at some real examples of code to see how these steps work together.  This first example illustrates how to call the GetAllAttributes function.  This function is useful to determine the internal name of attributes which you might want to use in other web service calls.  Within the Hobsons Connect application you are able to see the “Mapped Name” of each attribute.  The Mapped Name is the user friendly name you define for attributes and use in the application interface provided by Hobsons — “Application Status” for example.  However, you must use the corresponding “Internal Name” when working with attributes in web services.  Internal names are assigned by the system and are based on the type of attribute — text, numeric, or date.  For example, the internal name for “Application Status” might be “text359″.

#****** Get and display all contact attributes ***********
 $ws=New-WebServiceProxy -uri $WSURL      # *** Instantiate the web service. ****
 [String]$ReturnValue = $ws.GetAllAttributes($ClientName, $PassKey)  # ***Call the Web Service ***
write-Host $ReturnValue  # *** Display the raw XML ***
[xml]$ReturnValueXML = $ReturnValue  # ***Convert the string to an XML variable ***
# *** Crawl through the XML and display mapped and internal names ***
$nodelist = $ReturnValueXML.selectnodes("/result/returndata/attributes/attribute")
 Foreach ($node in $nodelist) {
 if ($node.type -eq "attribute") {
 write-host ($node.mappingname."#cdata-section" + ', ' + $node.name)
 }
 if ($node.type -eq "folder") {
 write-host ''
 write-host ('Folder = ' + $node.name)  #*** Display Folder Names if encountered ****
 write-host '------------------------------------------------------'
 }
 }

The XML returned by the function call will look something like the following:

<result>
 <code>1</code><ErrorMessage />
 <returndata>
 <attributes>
 <attribute>
 <type>attribute></type><level />
 <name>text289</name>
 <mappingname><![CDATA[SendViewBook]]></mappingname>
 <datatype>Varchar2</datatype>
 <size>30</size>
 <validationexp />
 </attribute>
 </attributes>
 </returndata>
 </result>

Each attribute description begins with a <attribute> tag. The <type> tag is used to identify whether the information refers to a folder or attribute. Notice the <name> and <mappingname> tags, as well as additional tags that identify the type and size of the attribute.

Below is a partial view of what a formatted view of the output might look like after the XML is parsed. In this case, some information such as the type and size of the attribute have been left out.

Folder = Area of Study and Interests
——————————————————
PreferredCampus, text229
ProgramInterest1, text253
ProgramInterest2, text255

Folder = International
——————————————————
InternationalStudent, text295
Arrival Dates, date1483
Flight Arrival Info, text1485
Mailing Tracking No, numeric1581

Now let’s look at sample code for searching for a contact record using the GetContact web service call. In the previous example, our only inputs were our Hobsons Client Name and Passkey. However for the GetContact call we have two more input parameters. The first of these is the search criteria, which consists of one or more attribute values used for comparison. Each criterium in the search consists of three parts: the internal name of the attribute, a value for comparison, and the type of comparison (equals, greater than, etc.). The example code below illustrates how to construct an XML search string to match on first and last name:

$InputXML = '<attributes>' `
 +'<attribute><name>firstname</name>' `
 +'<value>Scott</value>' `
 +'<operator>equals</operator>' `
 +'</attribute>' `
 +'<attribute><name>Lastname</name>' `
 +'<value>Guthrie</value>' `
 +'<operator>equals</operator>' `
 +'</attribute>' `
 +'</attributes>'

When more than one attribute is included in the search criteria, results for contacts which meet all conditions will be returned. That is, there is an implied “AND” between the attribute conditions. Hobsons also provides a function called GetContacts (easily confused with GetContact) which returns contacts meeting any of the conditions. That is, there is an implied “OR” between the attribute conditions.

In addition to search criteria, an XML string containing a list of attributes to returned with the contact information also needs to be provided in the call. The internal names rather than the mapped names from the Connect application interface must be specified. Below is an example which references both fixed (standard) attributes and custom attributes.

$AttributeXML = '<attributes>' `
 +'<attribute><name>city</name></attribute>' `
 +'<attribute><name>state</name></attribute>' `
 +'<attribute><name>text141</name></attribute>' `
 +'<attribute><name>ID</name></attribute>' `
 +'</attributes>'

Finally, you can put these input strings together with the ClientName and PassKey to make the function call and complete the program as shown below:

[String]$ReturnValue = $ws.GetContact($ClientName, $PassKey, $InputXML, $AttributeXML)

The output XML is contained in $ReturnVal. If you simply print this variable out, you’ll get something like:

<result>
 <code>1</code>
 <ErrorMessage></ErrorMessage>
 <returndata>
 <count>1</count>
 <contacts>
 <contact>
 <attribute>
 <name>city</name>
 <value><![CDATA[WestSalem]]></value>
 </attribute>
 <attribute>
 <name>state</name>
 <value><![CDATA[WI]]></value>
 </attribute>
 <attribute>
 <name>text141</name>
 <value><![CDATA[10755997]]></value>
 </attribute>
 <attribute>
 <name>ID</name>
 <value><![CDATA[601]]></value>
 </attribute>
 </contact>
 </contacts>
 </returndata>
 </result>

In order to make practical use of this information, you will likely have to parse the attributes out into individual variables. This can be done in several ways. The sample code below shows you how to assign the output to an XML variable and use object nomenclature along with the “where” verb to split each attribute into a separate variable.

$City =($ReturnValueXML.result.returndata.contacts.contact.attribute | where {$_.name -eq "city"}).value."#cdata-section"
 $State =($ReturnValueXML.result.returndata.contacts.contact.attribute | where {$_.name -eq "state"}).value."#cdata-section"
 $WarriorID =($ReturnValueXML.result.returndata.contacts.contact.attribute | where {$_.name -eq "text141"}).value."#cdata-section"
 $ConnectID =($ReturnValueXML.result.returndata.contacts.contact.attribute | where {$_.name -eq "ID"}).value."#cdata-section"
 

In addition to querying data from Connect, you can also use web service calls to create or update contacts. To create a new contact, you first form the XML containing the attributes and values you want the new contact to use. A simple example appears below:

 [string]$OutputXML = "<attributes>"`
 + "<attribute><name>firstname</name><value><![CDATA[Scott]]></value></attribute>" `
 + "<attribute><name>middlename</name><value><![CDATA[Alan]]></value></attribute>" `
 + "<attribute><name>lastname</name><value><![CDATA[Guthrie]]></value></attribute>" `
 + "<attribute><name>address1</name><value><![CDATA[123 Atwood Dr.]]></value></attribute>"`
 + "<attribute><name>city</name><value><![CDATA[Mankato]]></value></attribute>" `
 + "<attribute><name>state</name><value><![CDATA[MN]]></value></attribute>" `
+ "<attribute><name>email</name><value><![CDATA[sguthrie@winona.edu]]></value></attribute>" `
+ "<attribute><name>sourcecode</name><value><![CDATA[New Prospect]]></value></attribute>" `
 +"/<attributes>"

Note the use of CDATA strings; while not always required, it is good form to use these to avoid any attribute values from interfering with the XML markup language.

Once you have formed your attribute XML, you simply call the CreateContact web service to establish a new contact in Connect with these attributes:

[string]$wsResponse = $ws.CreateContact($ClientName, $ClientPassword, $OutputXML)

In this example, the variable $wsResponse will contain an XML string denoting if the operation was successful or not.  Below is what the response looks like when a new contact is successfully created.  The unique ContactID of the new contact (12345 in this case) is returned and a Code value of 1 indicates success.

<result>
<code>1</code>
<ErrorMessage></ErrorMessage>
<returndata>
<contactid>12345</contactid>
</returndata>
</result>

A code of 2 indicates that a contact already exists.  This determination is made based on the duplicate checking rules you have established in Connect.  For example: First Name + Last Name + eMail. When a duplicate contact is found, the existing ContactID will be returned in the XML and attribute values will not be updated.

Updating an exising contact is similar to adding a new contact.  You start out by forming the attribute XML, including only those attributes which need to be changed.  An example of changing an address is shown below:

 [string]$UpdateXML = "<attributes>"`
+ "<attribute><name>address1</name><value><![CDATA[707 Market St.]]><value></attribute>"`
+ "<attribute><name>city</name><value><![CDATA[Anytown]]></value></attribute>" `
+ "<attribute><name>state</name><value><![CDATA[WA]]></value></attribute>" `
+ "<attribute><name>sourcecode</name><value><![CDATA[Update Prospect]]></value></attribute>" `
+"/<attributes>"

To update, simply call the UpdateContact web service as in the example below:

 [string]$wsResponse = $ws.UpdateContact($ClientName, $ClientPassword, $ConnectID,  $UpdateXML)

Note the inclusion of the $ConnectID variable in this call.  This variable must contain a string containing the contact’s existing Connect ID.  If you do not have the Connect ID, you can use the previously mentioned GetContact service call to obtain it.

As with other service calls, Connect will return an XML string noting success or failure.  An example is shown below:

<result>
<code>1</code>
<ErrorMessage></ErrorMessage>
</result>

If the value of code is anything other than 1, the call failed.  The contents of ErrorMessage may give you a clue as to what the problem is.

There are many more web service calls available than I’ve shown, but hopefully this post gives you a framework to get started.

About saguthrie

I am a Data Integration Specialist and Database Developer assigned to Winona State University's Institutional Planning, Assessment, and Research (IPAR) team. I'm currently focused on CRM solutions, including Hobsons Connect, Retain, and Microsoft Dynamics CRM 2011. In past lives I've been an ERP consultant, Network Analyst/Consultant, and IT Department Manager. I still frequently contribute to ERP discussions on LinkedIn. My first exposure to computing was on a Teletype 30 which sat in a janitor's closet at our High School and was connected to a "time-sharing" HP 1000 running Basic. My first personal computer was an Atari 800.

Discussion

No comments yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

IPAR Posts

January 2013
S M T W T F S
« Oct    
 12345
6789101112
13141516171819
20212223242526
2728293031  

The WSU IPAR Team

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 6 other followers

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: