+ Start a Discussion
ritswaney007ritswaney007 

Invoking external webservice from Contacts Tab

3 days old (new) to salesforce!
i need to invoke a webservice from a tab like contacts when a button is clicked.
i understand i can add a custom button, but how do i write the code behind it, which will be triggered upon clicking.
the code behind the buttons needs to invoke this webservice, passing some details from the screen such as customer name and postcode, and the response that is received should be displayed on the screen.

please help people !
Best Answer chosen by Admin (Salesforce Developers) 
Ron HessRon Hess
i don't know how big your generated wsdl is.
you could break up the wsdl into separate wsdl's and parse each one?

do you need every method in the wsdl that you are using?

All Answers

Ron HessRon Hess
I would do this using visualforce, create a command button that calls an action in Apex Controller.
The controller will make a webservice.invoke() or http() callout to get the data, then refresh the page with the controller providing the updated data. 

There is a bit of Apex Code required to perform this type of callout, an example is documented in the Apex Developer Guide

is the service you are using a WebService or REST?
ritswaney007ritswaney007
Hi Ron,
Many thanks for your response.

Here's what I tried out today. I added a custom button to the Account tab, which on click, invoked an s-control. The s-control invoked an Apex class which had code to callout another Apex class, which I generated from a wsdl.

Since I am very new to SFDC, I would greatly appreciate it, if you could tell me how different/advantageous using a Visualforce page with controller would be to using the s-control approach.

Also, I am new to webservices, so not sure if the one we intend using is Rest or Soap. Its the Experian Credit Check interface in the UK, which we are trying to use as a web service.

Would it be possible to have your email address for further communication / advice.

Thanks for your time.

Ritesh
Ron HessRon Hess
Since I am very new to SFDC, I would greatly appreciate it, if you could tell me how different/advantageous using a Visualforce page with controller would be to using the s-control approach.

Visualforce would be easier to customize the UI of the rest of the page, using an scontrol under a button may work just fine for you.

When you render the result, that operation may be fairly simple using Visualforce and some outputtext components.

to output the same info in an scontrol you would need to construct the required html on your own, in javascript.

it sounds like your service is a webservice
ritswaney007ritswaney007
Hi again Ron,
Thanks for that clarification.
 
I actually require this button to be present in the Account tab, so will I have to override the controller for the Account Page? Are all existing pages that you see on clicking a Tab VisualForce pages?
 
Can I overrride the Account controller just for the button click to activate the new VF Page, without changing any existing behaviour? Or do you mean just embed a URL with arguments being passed in the URL from the Account page, because I do need information from the Account details currently displayed.
 
Thanks for your time.
 
Ritesh
Ron HessRon Hess
in this case perhaps a custom button that opens the url of the visualforce page, passing id and other required params using merge fields (added when you define the button url).
ritswaney007ritswaney007
Hi again Ron,
Thanks a ton for the guidance.

I have kinda managed to try that out. Now I'm trying to generated the Apex classes from the WSDL.

However, it can generate two classes out of the the three it tries to generate, the third one fails with the following error. Just wondering how to get around it.

The following generated class(es) have compilation errors:

Error: schemaUkExperianComExperianCemsMsg


Error: Script too large: //Generated by wsdl2apex

public class schemaUkExperianComExperianCemsMsg {
public class Special... at -1:-1

Cheers,
Ritesh
London BenLondon Ben
This is not really helpful - so I apologize for hijacking your thread - in the hope that someone from SalesForce may notice - that this problem also occurs when you try to consume SALESFORCE as a web service.

EG - I have multiple salesforce orgs. and wish to exchange data between the systems using SF webservices - however sadly when I try to process a salesforce generated wsdl - in another instance of salesforce - it gives the same error (too large)...

Is is just me - or does this seem a little ridiculous!!!!
ritswaney007ritswaney007
Get your own thread!

:)

Well, I think the Apex developer guide clearly mentions that organisatin wide wsdl's cannot be convert to apex classes by the wsdl-to-apex converter, and in particular mentions that its not possible to convert SalesForce wsdl's to Apex.

Cheers
Ritesh

P.S. > Ron, my unanswered question is just above Mr Ingram's question ! :)
Ron HessRon Hess
i don't know how big your generated wsdl is.
you could break up the wsdl into separate wsdl's and parse each one?

do you need every method in the wsdl that you are using?
This was selected as the best answer
ritswaney007ritswaney007
Hi Ron,
Hope you had a good weekend :)

Well, there is only one method (operation) in the WSDL, the rest of it is type and message definitions.

:(

Ritesh


Ron HessRon Hess
is this a public service? what is the uri?

or post the wsdl?

note: not all WSDL's are parse-able by the tools we have today.
ritswaney007ritswaney007
Hi Ron,
Apologies for the delay.

Salesforce manages to parse the WSDL alright I think, it manages to generate classes pertaining to two schemas, however on the third schema, which contains the "types", it fails saying script too long.

It is a webservice provided by Experian UK, which is a credit check bureau.

Its too long to paste on here, I'm wondering if you can provide an email address, where I could forward this to you. Mine is ritesh.aswaney@capgemini.com

I even tried trimming the extraneous fields in the WSDL and brought it down to 1/3 rd the size, but it still wont import, I'm wondering what to do next.

Cheers,
Ritesh
ritswaney007ritswaney007
Hi there

Does Apex support Secure Web Services. I need to consume an external WS, for one which need to be authenticated.
Authentication is via another WS, which accepts a X509 cert in the request and returns a Binary Security Token in the response.

This token needs to be embedded in all further requests, like this
<soap:Header>
<wsse:Security>
<wsu:Timestamp wsu:Id="Timestamp-2b27a32b-ca9c-4405-b377-4444f63c8f29">
<wsu:Created>2007-02-20T16:36:54Z</wsu:Created>
<wsu:Expires>2007-02-20T16:41:54Z</wsu:Expires>
</wsu:Timestamp>
<wsse:BinarySecurityToken
ValueType="ExperianWASP"
EncodingType="wsse:Base64Binary"
wsu:Id="SecurityToken-f64439f9-c12c-4d09-ac3d-fc478ad19775">
MjAtRTctQ0YtMTUtN0EtODEtNTk...
</wsse:BinarySecurityToken>

In .NET , this can be written as

AuthPlusWS.InteractiveWSWse service = new AuthPlusWS.InteractiveWSWse();
// Add the secure token to the secured service
service.RequestSoapContext.Security.MustUnderstand = false;
service.RequestSoapContext.Security.Tokens.Add(wt);

Is there a way to do this in apex ?

Cheers,
Ritesh
soasoa
Hi
 
I am new to Apex
 
I have similar requirement as Ritesh, i.e. I need to invoke a web service at a buttonm click from a standard tab ( e.g. Account, Cotact etc). Instead of default Save Buttom the button would invoke the external webservice.
 
The request of the web service would be formed from the value which users would enter in the while entering or editing the contact information (E.g. Account Name, phone, fax ect.)
 
We could generate the apex client for the external web service but not too sure that what is the right option for creating UI on the Apex Client.
 
It was mentioned in the thread that :
>> I would do this using visualforce, create a command button that calls an action in Apex Controller. The >>controller will make a webservice.invoke() or http() callout to get the data, then refresh the page with the >>controller providing the updated data. 
 
>>There is a bit of Apex Code required to perform this type of callout, an example is documented in the Apex >>Developer Guide
 
Can you elaborate the same .. it would be great if you can provide me exactly which document contains the example , is it Apex language refrence or any other document?
 
Thanking you in anticipation !
Sanghamitra
ritswaney007ritswaney007
Hi Sanghamitra

The apex language reference is available at
www.salesforce.com/us/developer/docs/apexcode/salesforce_apex_language_reference.pdf

Chapter 8 in that has a section titled
SOAP Services: Defining a Class from a WSDL Document

That should do it for you.

Cheers,
Ritesh
soasoa

Dear Ritesh

Many thanks for you prompt response.

However we could already create the apex client using the same reference as mentioned in your mail. But I am not too sure what is the best option for creating the UI.

It would be great if you can provide me any pointer on the same.

Thanks & regards

Sanghamitra

ui for the Apex Client

 

ritswaney007ritswaney007
Hi,
If you are invoking the webservice on a button click from a standard tab such as Accounts, that will serve as the UI for you?

If, however, you intend writing your own UI, you would have to use VisualForce to create VisualForce pages.

It is similar to a jsp tag-lib with a variety of functions already provided.

You can refer to the salesforce_pages_developers_guide.pdf for information on how to use VisualForce.

It is basically modelled on the MVC type, where the VisualForce Page is the View, and a Controller class can be written, which is associated with teh VF Page.
 
You can read sections pertaining to custom controllers in the guide mentioned above.

I'm quite new to salesforce myself, but hope this is of assistance to you.

Cheers,
Ritesh
soasoa

Hi Ritesh,

Many thanks for your reply !

>> If you are invoking the webservice on a button click from a standard tab such as Accounts, that will serve as the UI for you?
yes that would serve my purpose.

1. Generated a Apex Class from the WSDL of the Web Service.
(Ref : Chapter 8 of salesforce_apex_language_reference.pdf)

Here's the code of the apex class generated from my WSDL.

Code:
Code:
//Generated by wsdl2apex

public class wwwWebservicexNet {
    public class ConvertTemperatureSoap {
        public String endpoint_x = 'http://www.webservicex.net/ConvertTemperature.asmx';
        public Map<String,String> inputHttpHeaders_x;
        public Map<String,String> outputHttpHeaders_x;
        public String clientCert_x;
        public String clientCertPasswd_x;
        private String[] ns_map_type_info = new String[]{'http://www.webserviceX.NET/', 'wwwWebservicexNet'};
      public Double ConvertTemp(Double Temperature,String FromUnit,String ToUnit) {
            wwwWebservicexNet.ConvertTemp_element request_x = new wwwWebservicexNet.ConvertTemp_element();
            wwwWebservicexNet.ConvertTempResponse_element response_x;
            request_x.Temperature = Temperature;
            request_x.FromUnit = FromUnit;
            request_x.ToUnit = ToUnit;
            Map<String, wwwWebservicexNet.ConvertTempResponse_element> response_map_x = new Map<String, wwwWebservicexNet.ConvertTempResponse_element>();
            response_map_x.put('response_x', response_x);
            WebServiceCallout.invoke(
              this,
              request_x,
              response_map_x,
              new String[]{endpoint_x,
              'http://www.webserviceX.NET/ConvertTemp',
              'http://www.webserviceX.NET/',
              'ConvertTemp',
              'http://www.webserviceX.NET/',
              'ConvertTempResponse',
              'wwwWebservicexNet.ConvertTempResponse_element'}
            );
            response_x = response_map_x.get('response_x');
            return response_x.ConvertTempResult;
        }
    }
    public class ConvertTempResponse_element {
        public Double ConvertTempResult;
        private String[] ConvertTempResult_type_info = new String[]{'ConvertTempResult','http://www.w3.org/2001/XMLSchema','double','1','1','false'};
        private String[] apex_schema_type_info = new String[]{'http://www.webserviceX.NET/','true'};
        private String[] field_order_type_info = new String[]{'ConvertTempResult'};
    }
    public class ConvertTemp_element {
        public Double Temperature;
        public String FromUnit;
        public String ToUnit;
        private String[] Temperature_type_info = new String[]{'Temperature','http://www.w3.org/2001/XMLSchema','double','1','1','false'};
        private String[] FromUnit_type_info = new String[]{'FromUnit','http://www.webserviceX.NET/','TemperatureUnit','1','1','false'};
        private String[] ToUnit_type_info = new String[]{'ToUnit','http://www.webserviceX.NET/','TemperatureUnit','1','1','false'};
        private String[] apex_schema_type_info = new String[]{'http://www.webserviceX.NET/','true'};
        private String[] field_order_type_info = new String[]{'Temperature','FromUnit','ToUnit'};
    }
}


 

2. We then created a button which would invoke the method of the Apex Class
generated from the WSDL.
(Ref : Chapter 7 of Salesforce_platform_cookbook.pdf)
On-Click Java Script :

Code:
Code:
{!REQUIRESCRIPT("/soap/ajax/10.0/connection.js")} 
{!REQUIRESCRIPT("/soap/ajax/10.0/apex.js")} 

var fromUnit = prompt("Please enter the unit from which to convert"); 
var toUnit = prompt("Please enter the unit to which to be converted"); 
var temp= prompt("Please enter the temperature"); 

// alert (''Before calling "); 

// Now make a synchronous call to the Apex Web service 
// method 
var result = sforce.apex.execute( 
"wwwWebservicexNet. ConvertTemperatureSoap", // class 
"ConvertTemp", // method 
{iFrom : fromUnit, // method arguments 
iTo: toUnit, 
iTemp:temp});


 

. Add the button to the Account List view Layout

On Click of the button the input prompt are appearing to accept the input value
However finally it is showing the following errors:

fault code : 'Soapenv.client',
Faultstring : 'No Service available for the class wwwWebServiceNet.ConvertTemperatureSOAP'

Is it the right way to call apex class from the button. Am I missing something?
 
Thanks & Regards
Sanghamitra
SuperfellSuperfell
the class/method you are trying to call from the button needs to be exposed as a web service, the generated web service client class is not marked as such (see the apex docs on the webservice keyword)
soasoa

Hi,

As per your suggestion We added another class which is calling the Apex Class generated from the WSDL:

the code is:

global class HelloWorld {
WebService static Double ConvertTemp()
{
    String ToUnit = 'degreeCelsius';
    String FromUnit = 'degreeFahrenheit';
    Double Temperature = 123;

   wwwWebservicexNet.ConvertTemperatureSoap stub = new wwwWebservicexNet.ConvertTemperatureSoap();
  Double result = stub.ConvertTemp(Temperature,ToUnit, FromUnit );
   return(result);
}

}

When I am invoking it from the Accounts tab I am getting a HelloWorld button .this button is calling the ConvertTemp method.

i am getting the Following error:

A problem with OnClick JavaScript for this button or link was encountered :

{faultcode:'soapenv:Client',faultstring:'System.CalloutException:IO Exception: Unauthorized endpoint, please check Setup->Security->Remote site settings.endpoint = http://www.webservicex.net/ConvertTemperature.asmx

Class.wwwWebservicexNet.ConvertTemperatureSoap.ConvertTemp:line 19, column 13

Class.HelloWorld.Converttemp: line 16 column 17',}

Kindly Help me for the same .

Here is the URL of the WSDL for your Refrence:

 http://www.webservicex.net/ConvertTemperature.asmx?WSDL

Thankx



Message Edited by soa on 08-21-2008 10:04 PM
SantDevTeamSantDevTeam
OK, I'm glad to see I'm not the only one having these problems:( I have followed (religiously!) the cookbook manual section called "Sending Messages from Apex" to try and test the calling of external web services. However, no matter what I try, I always get that same error when I try and select the new tab I put the s-control on.

The actual reason I tried to copy the manual is I tried to access our own web service first and could not get that to work either!. I've also tried the Feed s-control that comes with Dev and that does not work (I did add a remote site for the URL...).

Any help or pointers here would be most appreciated as I need to get this working so I can test our new product integration woth SF:)

Thanks,
Andy.

cheenathcheenath
You are getting this error, because the endpoint you are trying to access is not added to the whitelist in the setup-security-remote site settings page.

{faultcode:'soapenv:Client',faultstring:'System.CalloutException:IO Exception: Unauthorized endpoint, please check Setup->Security->Remote site settings.endpoint = Link:






BellaBella

I'm getting the same error when I'm trying to attach a pdf file rendered through a vf page to the respective opportunity it's rendered from. I can SEE the file when I put in the URL but then it gives me that error when I actually run

 

 

Http h = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint('https://c.cs2.visual.force.com/apex/PDF?Id=o.Id');
req.setMethod('GET');
HttpResponse res = h.send(req);
Attachment a = new Attachment(Name = 'Bob', ParentId = o.Id, Body = Blob.valueOf(res.getBody()));

 How can this be? I'm working entierly within salesforce so how can it give me an external entry error? Anyone?

 

BigRobBigRob
I get the same error and I have added the reference using Security->Remote Site Settings