Saturday 9 December 2017

How to integrate Salesforce webservices with Ruby on Rails

In this article we will see how to integrate Salesforce REST API to push data from Ruby on Rails application. Please note it requires Ruby greater than 2.0 because of TLS security issues. 

Here are the detailed steps for integrating Salesforce API with Rails application:-


(a) GET WSDL Files and Security Token


Enterprise/ParterWSDL Files: If you have salesforce account you can get your WSDL files from there. You can get this file from your salesforce account “App Setup > Develop > Download your organization-specific WSDL” link.


<?xml version=”1.0″ encoding=”UTF-8″?>
<!–
Web Services API : WebToLeadServices
–>
<definitions targetNamespace=”http://soap.sforce.com/schemas/class/WebToLeadServices” xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns=”http://schemas.xmlsoap.org/wsdl/” xmlns:soap=”http://schemas.xmlsoap.org/wsdl/soap/” xmlns:tns=”http://soap.sforce.com/schemas/class/WebToLeadServices”>
<types>
<xsd:schema elementFormDefault=”qualified” targetNamespace=”http://soap.sforce.com/schemas/class/WebToLeadServices”>
.
.
.
<xsd:complexType name=”WebLead”>
<xsd:sequence>
<xsd:element name=”name” minOccurs=”0″ type=”xsd:string” nillable=”true”/>
<xsd:element name=”email” minOccurs=”0″ type=”xsd:string” nillable=”true”/>
<xsd:element name=”phone” minOccurs=”0″ type=”xsd:string” nillable=”true”/>
<xsd:element name=”comments” minOccurs=”0″ type=”xsd:string” nillable=”true”/>
</xsd:sequence>
</xsd:complexType><xsd:element name=”createLeadFromWeb”>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=”wl” type=”tns:WebLead” nillable=”true”/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
.
.
.
<service name=”WebToLeadServicesService”>
<documentation></documentation>
<port binding=”tns:WebToLeadServicesBinding” name=”WebToLeadServices”>
<soap:address location=”https://ap7.salesforce.com/services/Soap/class/WebToLeadServices”/>
</port>
</service>
</definitions>

Webtolead.wsdl : If you want to send data from your website to salesforce then it will require wsdl files for e.g webtosalesforcelead.xml with content something like this.


Security token : Navigate to My Settings > Personal > Reset My Security Token and click on “Reset Security Token”. This will send you security token on your registered mail id.


(b) Install the SOAP4R gem using Terminal.


gem install soap4r


(c) Run wsdl2ruby


Go to folder where have install soam gem. run the following commands in terminal.

cd /path/to/gem/soap/
wsdl2ruby.rb –wsdl ~/path/to/enterprise.wsdl.xml –type client

Change your paths accordingly. This will produce 4 files in your current working directory: default.rb, defaultDriver.rb, defaultMappingRegistry.rb, and SforceServiceClient.rb.

One more file is required as SOAP4R uses “header handlers” to modify outgoing and read incoming headers (and note that these are SOAP headers, not HTTP headers), so you’ll have to write one of your own (syntax highlighted version):

client_auth_header_handler.rb

require ‘soap/header/simplehandler’
class ClientAuthHeaderHandler < SOAP::Header::SimpleHandler
SessionHeader = XSD::QName.new(“rn:enterprise.soap.sforce.com”, “SessionHeader”)

attr_accessor :sessionid
def initialize
super(SessionHeader)
@sessionid = nil
end


def on_simple_outbound

if @sessionid
{“sessionId” => @sessionid}
end
end


def on_simple_inbound(my_header, mustunderstand)

@sessionid = my_header[“sessionid”]
end
end



(d) Create Rails application


install these two gems

gem ‘soap4r’
gem ‘soap4r-spox’


(e) Put all generated files and client_auth_header_handler.rb in you salesforce folder in lib folder of your project.

lib/salesforce
lib/salesforce/default.rb
lib/salesforce/defaultDriver.rb
lib/salesforce/defaultMappingRegistry.rb
lib/salesforce/SforceServiceClient.rb
lib/salesforce/client_auth_header_handler.rb

and change require path accordingly on each files e.g.

require ‘salesforce/default.rb’
require ‘salesforce/defaultMappingRegistry.rb’
require ‘soap/rpc/driver’


(f) Create helper salesfore_helper.rb


module SiteHelper
require ‘rubygems’
gem ‘soap4r’
require ‘soap/soap’
require ‘salesforce/defaultDriver’
require ‘salesforce/client_auth_header_handler’
require ‘soap/wsdlDriver’

def sendtosf

sf = User.first
d = Soap.new
d.wiredump_dev = STDOUT
h = ClientAuthHeaderHandler.new
username = “yourusername”
password = “yourpassword”
token = “yoursectoken”
l=d.login(:username => username, :password => password+token)
h.sessionid = l.result.sessionId
d.headerhandler << h
client = SOAP::WSDLDriverFactory.new( ‘lib/salesforce/webtosalesforcelead.xml’ ).create_rpc_driver
client.wiredump_dev = STDOUT
client.headerhandler << h
leadData = {}
leadData[“wl”] = sf #=> “wl” createLeadFromWeb element
Rails.logger.info “========#{leadData.inspect}============”
response = client.createLeadFromWeb(leadData) #=> createLeadFromWeb method which is present in webtosalesforcelead.xml

#Rails.logger.info “========#{leadData.inspect}============”

Rails.logger.info “========#{response.inspect}============”
#response = client.WebLead(sf)
end
end

That's all for steps to integrate Salesforce REST API with Ruby on Rails. If you have any query, please write in comment section.

Tuesday 6 June 2017

Can Ansible make a REST call

In this article, we will learn how Ansible can make a REST call

Introduction:

RESTful API’s is a platform independent architecture based on representational state transfer (REST) technology and are now a days used to  integrate  different applications. So, if we want to interact with an existing infrastructure we can expose the infrastructure as REST webservice and other applications can use its API to make calls.

Ansible, using URI module, provides way to make the REST calls. The URI module allows us to send XML or JSON payload and get the necessary details. In this article we will see how we can use the URI module and make the REST calls. 



REST call - 

In the below example, we are using the Nexus artifactory to connect to REST Webservice running on 8081 Port. The URL are specified in the vars/main.yml file.

The idea here is to make a Get REST Call using the Ansible URI module to fetch the necessary details. Get call doesn't change anything on REST Server.



- name: Make a Call


  uri:

   url: "{{nexus_url}}/repositories"

   method: GET

   user: user1

   password: user123

   force_basic_auth: yes

   return_content: yes


In the above code, we are making the Get REST call to the “nexus_url/respositories” URL by passing them the user name and password along with the method as “Get” and the return_content.  We can use the Ansible debug to check the obtained response.



POST call – 

Making a Post call needs a little extra details. Now for making a post call we need the JSON data. We have option to create a file with JSON data and pass that to the file or we can include the JSON data at the same POST call. Lets create a JSON file first as below:


{


    "data": {

        "repoType": "proxy",

        "id": "somerepo1",

        "name": "Some Repo Name1",

        "browseable": true,

        "indexable": true,

        "notFoundCacheTTL": 1440,

        "artifactMaxAge": -1,

        "metadataMaxAge": 1440,

        "itemMaxAge": 1440,

        "repoPolicy": "RELEASE",

        "provider": "maven2",

        "providerRole": "org.sonatype.nexus.proxy.repository.Repository",

        "downloadRemoteIndexes": true,

        "autoBlockActive": true,

        "fileTypeValidation": true,

        "exposed": true,

        "checksumPolicy": "WARN",

        "remoteStorage": {

            "remoteStorageUrl": "http://testserver.com:8081/local",

            "authentication": null,

            "connectionSettings": null

        }

    }

}

Next, we will save this file as proxy.json and move the file to the files location. Now we can use the proxy.json using the lookup in ansible as follows:



- name: Make a Proxy Repository


  uri:

    url: "{{ nexus_url }}/repositories"

    method: POST

    body: "{{ lookup('file','proxy.json') }}"

    user: user1

    password: user123

    force_basic_auth: yes

    body_format: json

    HEADER_Content-Type: application/json

    HEADER_Accept: application/json,version=2

    return_content: yes

    status_code: 201



Explanation:

In the above code,we passed the JSON file an argument to the  Ansible lookup. Besides this we passed the user name , password and most importantly the body_format , Header fields etc. We also need to pass the return code of the REST call so that Ansible will compare the return status code with the status code that we defined. In the above example we passed the status code as 201. In this example Ansible will check the rest call status code and passed status code to check if that is success or not. Even though the rest call is success if the status codes are not same Ansible will throw an error.

If we want to pass the JSON format in the body itself without using the file, we can use it this way:



- name: Make a Hosted Repository


  uri:

    url: "{{nexus_url}}/{{ nexus_endpoint }}/{{ nexus_repositories_service }}"

    method: POST

    body: >

     {

      data: {

        "repoType": "{{ hosted_repo_data.repoType }}",

        "id": "{{ repoId }}",

        "name": "{{ repoName }}",

        "provider": "{{ repoProvider}}",

        "browseable": {{ hosted_repo_data.browseable }},

        "repoPolicy": {{ hosted_repo_data.repoPolicy }},

        "providerRole": {{ hosted_repo_data.providerRole }}

           }

     }

    user: "{{ nexus_admin }}"

    password: "{{ nexus_admin_password }}"

    force_basic_auth: yes

    body_format: json

    HEADER_Content-Type: application/json

    HEADER_Accept: application/json,version=2

    return_content: yes

    status_code: 201

The body can be added directory to the Body method in the Ansible JSON call.


Thats all for different ways to make REST call via Ansible. If you have a query please mention in comments section and don't forget to subscribe to latest articles -> Subscribe to Tech693