Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

So I'm trying to access Woopra analytic's restful API via apex/visualforce. I am wondering a couple of things:

1) The API returns a JSON object via the usual POST/GET method... would it be best to call the API through apex, or would it be better (or even possible) to do a jquery/ajax style call from a VF page?

2) IF I were to need to do this in apex, how would I translate the following:

var params = {
  website: 'yourwebsite',
  segment: [
    {
      did: {
        operator: 'AND',
        filters: [
          {
            scope: 'actions',
            key: 'name',
            match: 'match',
            value: 'quote'
          }
        ]
      },
      are: {
        operator: 'AND',
        filters: []
      }
    }
  ]
  // optional parameters
  offset: 0,
  report_id: -1 //paging   
};

$.ajax({
  type: 'POST',
  url: 'http://www.woopra.com/rest/search'
  crossDomain: true,
  beforeSend: function(wrq) {
    wrq.setRequestHeader('X-Api-Version', '2.0');
    wrq.setRequestHeader('X-Access-Id', APP_IDXXXXXXXX);
    wrq.setRequestHeader('X-Access-Secret', SECRET_KEYXXXXXXX);
  },
  data: params
});

my best shot is:

    public global class WoopraData
    {
        @future (callout=true)
           public string json;
            public string response;
        public static void sendRequest() {

            HttpRequest req = new HttpRequest();
            HttpResponse res = new HttpResponse();
            Http http = new Http();

            req.setEndpoint('http(s)://www.woopra.com/rest/report`');
            req.setMethod('POST');
            req.setBody('website=XXXXXXXXX.com'+'&segment=did: {operator: \'AND\', filters: [ {scope:\'actions\', key : \'name\', mathch:\'match\', value: \'quote\'}]}, are: {
        operator: \'AND\',
        filters: []
      }
    }
  ]);
            req.setCompressed(true); // otherwise we hit a limit of 32000

            try {
                res = http.send(req);
                json = res.getbody();
                response = convertresponst(json);
            } catch(System.CalloutException e) {
                System.debug('Callout error: '+ e);
                System.debug(res.toString());
            }

        }

        public string convertresponse(string json)
        {
           try{
            JSONObject j = new JSONObject( json );
           }
           catch(Exception e){}

            results = j.getValue('totalvisits').values[0].dnum.format();
            return response;
        }
        public static testMethod void testMe() {
            WebServiceCallout.sendRequest();
        }
    }

... How would I go about 1) writing this correctly, and 2) displaying this on a VF page (very simply, I just want to get the data to appear)?

Any push in the right direction will help immensely (mainly, trying to translate the API call into APEX, or helping me figure out how ot make the call directly from the page.

Here is the API documentation:

http://www.woopra.com/docs/developer/analytics-api/

And My references so far are:

http://blogs.developerforce.com/developer-relations/2012/10/not-calling-the-rest-api-from-javascript-in-visualforce-pages.html

http://developer.force.com/cookbook/recipe/accessing-docusign-api-from-salesforcecom-to-send-contracts-for-esignatures

http://techblog.appirio.com/2010/01/calling-rest-web-service-json-with-apex.html

http://wiki.developerforce.com/page/Apex_Web_Services_and_Callouts

http://blog.jeffdouglas.com/2009/03/16/restful-web-service-callout-using-post/

share|improve this question
add comment

4 Answers 4

up vote 4 down vote accepted

Glad you showed us everything you tried. You are really close, man!

  1. go to Setup > Remote Site Settings and create an entry for http://www.woopra.com/

  2. create the following Visualforce Page and Apex Class, then view the page at /apex/Woopra

  3. see if you get a 403 like I do ;-) then substitute your real credentials into the request headers

  4. play until it gives you 200 OK, then remove the System.assert... (that was for debug)

  5. eyeball the response data, and how you might go about parsing / displaying it...

Don't forget to update us! Here's how you might do your API call in Apex - try:

WoopraController.cls

public class WoopraController {

  public String Headers {get; set;}
  public String Response {get; set;}

  public void doRequest() {
  String data = '{'
    + '\n' + '"website":"yourwebsite",'
    + '\n' + '"segment":['
    + '\n' + '  {'
    + '\n' + '    "did":{'
    + '\n' + '      "operator":"AND",'
    + '\n' + '      "filters":['
    + '\n' + '        {'
    + '\n' + '          "scope":"actions",'
    + '\n' + '          "key":"name",'
    + '\n' + '          "match":"match",'
    + '\n' + '          "value":"quote"'
    + '\n' + '        }'
    + '\n' + '      ]'
    + '\n' + '    },'
    + '\n' + '    "are":{'
    + '\n' + '      "operator":"AND",'
    + '\n' + '      "filters":[]'
    + '\n' + '    }'
    + '\n' + '  }'
    + '\n' + '],'
    + '\n' + '"offset":0,'
    + '\n' + '"report_id":-1' +
  '}';

  System.HttpRequest request = new System.HttpRequest();
  request.setBody(data);
  request.setMethod('POST');
  request.setEndpoint('http://www.woopra.com/rest/search');
  request.setHeader('X-Api-Version',   '2.0');
  request.setHeader('X-Access-Id',     'APP_IDXXXXXXXX');
  request.setHeader('X-Access-Secret', 'SECRET_KEYXXXXXXX');

  System.HttpResponse response = new System.Http().send(request);
  System.assert(false, response); //remove this once you fix the 403
  this.Response = response.getBody();
  }
}

Woopra.page

<apex:page controller="WoopraController" action="{!doRequest}" contentType="text/plain">
  {!Headers}
  {!Response}
</apex:page>
share|improve this answer
    
this is amazing, thank you so much... I'm playing around with it, and I'm getting a 500, so I'm contacting salesforce and seeing if they can help me out from here (pretty sure there's nothing else I can really do until the 500 gets resolved, right?) unless, that is, you have a magic fix for this as well =) –  gfppaste Feb 26 '13 at 17:20
    
Thanks @gfppaste, glad I could help - is the 500 error coming from Salesforce or from Woopra? Do these parameters exactly match the request body Woopra is expecting? As you progress, you'll get to the stage where you can use the suggestions from the other answers to construct the request more programmatically... but it's easier to walk before running! –  user320 Feb 26 '13 at 17:23
    
So I've worked around the 500, now I'm getting this: no website parameter in request : /rest/report : {}:java.lang.Exception: no website parameter in request : /rest/report : {} at api.APIHandler.xget(APIHandler.java:454) at... com.woopra.proxy.server.HttpSession.run(HttpSession.java:29) at... I can't tell if this is on the SF side or the Woopra side... do you know of any way to tell? –  gfppaste Feb 26 '13 at 19:09
    
That's all coming from Woopra - your Salesforce page/controller is just surfacing that onscreen for you. You replaced yourwebsite in the code, right? :-) –  user320 Feb 26 '13 at 20:05
    
Hey, I have got a few questions regarding Web Services (JSON as output). We are developing services to interact with AS400 and similarly the AS400 team is providing services to interact with Salesforce. This must be an authenticated process. I would like to know how to provide the AS400 team to invoke the SF service. We are provided with a service URL (as well as cURL command line) which when passed with few headers in the browsers, it returns output in JSON. Similarly, how can I provide them in a URL format. –  Sapthagiri Jan 7 at 12:54
show 1 more comment

Take a look at https://json2apex.herokuapp.com/

It was created by @Metadaddy & @Superfell and it works great for quickly generating APEX Classes to parse your json response into.

share|improve this answer
    
this is getting bookmarked, this is an awesome resource, thanks so much! –  gfppaste Feb 26 '13 at 17:10
add comment

I don't think you could keep the AJAX style callout, you'd run into cross-domain security issues. To keep it, you'd need an Apex based proxy anyway.

You don't need to, and actually can't, use an @future in a Visualforce controller. But you can do the callout off the constructor.

You can use the Apex JSON parser to handle the response: http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_jsonparser.htm

Note the comment below, if CORS is an option then a pure (or more pure) JavaScript approach would be possible.

share|improve this answer
5  
The woopra API does support CORS so the AJAX option should work as well: bit.ly/126QxL7 –  xn. Feb 26 '13 at 0:09
add comment

I am still getting 403 error by following above steps: I have updated apex code with website Name(my websitename),AccessId(my Username),AccessSecret(API Key).Please help me to resolve it : System.AssertException: Assertion Failed: System.HttpResponse[Status=Forbidden, StatusCode=403] Error is in expression '{!doRequest}' in component in page wooprapage

Class.WoopraController.doRequest: line 44, column 1

share|improve this answer
    
did you comment out the System.assert? –  gfppaste Mar 8 '13 at 14:14
    
Yes, after commmenting the assert statement I am getting : no website parameter in request : /rest/search : {} –  Balaji Mar 11 '13 at 12:00
    
before commenting the assert statement i am getting StatusCode 500 error.After commenting the assert statement the result is :no website parameter in request : /rest/search : {} –  Balaji Mar 11 '13 at 12:11
    
I'm getting the same error, I took a break on this for a little bit... have you come up with a solution? –  gfppaste Mar 15 '13 at 17:40
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.