7

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/

4 Answers 4

7

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>
6
  • 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, 2013 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! Feb 26, 2013 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, 2013 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? :-) Feb 26, 2013 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, 2014 at 12:54
5

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.

1
  • this is getting bookmarked, this is an awesome resource, thanks so much!
    – gfppaste
    Feb 26, 2013 at 17:10
4

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.

1
  • 5
    The woopra API does support CORS so the AJAX option should work as well: bit.ly/126QxL7
    – xn.
    Feb 26, 2013 at 0:09
0

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

4
  • did you comment out the System.assert?
    – gfppaste
    Mar 8, 2013 at 14:14
  • Yes, after commmenting the assert statement I am getting : no website parameter in request : /rest/search : {}
    – Balaji
    Mar 11, 2013 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, 2013 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, 2013 at 17:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .