Today I had a fun trial-and-error exploration of Ruby SOAP messaging. By “fun” I mean “hair-rippingly excruciating.”

Basic SOAP calls are pretty easy with the wsdlDriver inherent in Ruby. Here’s how you’d wrap MailBuild’s Subscriber.Add function in Ruby:

require 'soap/wsdlDriver'

class MailBuildWrapper

  attr_accessor :api_key, :list_id

  def initialize(api_key, list_id)
    @api_key = api_key
    @list_id = list_id
  end
  
  def add_subscriber(user)
    soap     = wsdl.create_rpc_driver
    response = soap.addSubscriber \
                 :ApiKey       => api_key, 
                 :ListID       => list_id, 
                 :Email        => user.email,
                 :Name         => user.full_name
    soap.reset_stream
    response.subscriber_AddWithCustomFieldsResult
  end

  private

    def wsdl
      SOAP::WSDLDriverFactory.new("http://iridesco.createsend.com/api/api.asmx?WSDL")
    end

end

Calling a simple add subscriber is, well, simple.

u  = User.find(:first)
mb = MailBuildWrapper.new
mb.add_subscriber(u)

Adding with custom fields is different. This is because an array of “SubscriberCustomField” objects is necessary. Finding the magic Ruby incantation to build this SOAP array was a trick. I never found anywhere that said how to do this - Google was not my friend. Here is an example MailBuildWrapper method adding a subscriber with an ‘is_admin’ custom field:

def add_with_is_admin_custom_field(user)
  soap     = wsdl.create_rpc_driver
  response = soap.addSubscriberWithCustomFields \
               :ApiKey       => api_key, 
               :ListID       => list_id, 
               :Email        => user.email,
               :Name         => user.full_name,
               :CustomFields => {:SubscriberCustomField =>
                 [{:Key => 'is_admin', :Value => user.is_admin?.to_s}]}
  soap.reset_stream
  response.subscriber_AddWithCustomFieldsResult
end

So the ‘CustomFields’ hash item needed to point to a hash with a ‘SubscriberCustomField’ item, which itself points to an array of hashes containing ‘Key’ and ‘Value’. So multiple custom fields would be specified as follows:

:CustomFields => {:SubscriberCustomField => 
                    [ {:Key => 'is_admin', :Value => user.is_admin?.to_s},
                      {:Key => 'is_loser', :Value => user.is_loser?.to_s}]}

Some useful links from my first experience consuming a SOAP web service with Ruby:

Feb 19, 2008 · Subscribe · Archive · Projects · Twitter · GitHub · Flickr