2

We haven't figure out how to get the signed request (sr) in the visualforce page where we have a canvas app.

We are publishing a canvas event in our external app like:

Sfdc.canvas.client.publish(sr.client,
    {
     name : "namespace.eventName", 
     payload : {status : 'Completed'}
    }
);

And first we try to subscribe to the event in the VF page like:

<script type="text/javascript" src="/canvas/sdk/js/33.0/controller.js"></script>

<apex:canvasApp developerName="ourApp"/>

Sfdc.canvas(function() {
    Sfdc.canvas.controller.subscribe(
            {
              name : ‘namespace.eventName’,
            onData : function(e) {
                console.log("Subscribed to custom event ", e);
            }
        });
});

but we are getting the error Uncaught TypeError: Cannot read property 'publish' of undefined meaning that controller is undefined

So, we want to subscribe using the Sfdc.canvas.client.subscribe but that method takes two parameters, one of them is the signed request which we don't know how to get in the VF page

Eg:

Sfdc.canvas(function() {
    sr = JSON.parse('<%=signedRequestJson%>');
    Sfdc.canvas.client.subscribe(sr.client,
            {name : 'mynamespace.statusChanged', onData : function (event) {
                console.log("Subscribed to custom event ", event);
            }}
    );

});

So, the question is, how can we populate the variable sr in the line sr = JSON.parse('<%=signedRequestJson%>');?

Note: We have read this, this and been following the canvas developer guide

1

Add onCanvasAppLoad attribute in your canvas as descrebed below:

<apex:canvasApp developerName="ourApp"  onCanvasAppLoad="onCanvasLoad"/>

Add below JS function in your VF page where is the canvas located:

 <script type="text/javascript">                    
            var onCanvasLoad = function(){
               alert(document.getElementsByName('signed_request')[0].value.split('.')[1]);
            };
        </script>

The document.getElementsByName('signed_request')[0].value.split('.')[1] content is the signed request encoded in base64 format, so that you need to decode it as well.
Here is a useful info regading Base64 encoding/decoding.

Hope this will help you.

1

There should be absolutely no need for you to access the signed request on your Visualforce page. In fact it shouldn't even be possible as it is sent as part of a POST request to your external app.

We use the following placed after our apex:canvasApp in our Visualforce page and everything works fine.

<script type="text/javascript" src="/canvas/sdk/js/30.0/controller.js"></script>
<script type="text/javascript"> 
    Sfdc.onReady(function() {  
        Sfdc.canvas.controller.subscribe({name : 'namespace.event', onData : function (e) {
            // Do something
        }});
    });
</script>     

We publish events from our external app using the following:

<script type="text/javascript" src="sdk/js/canvas-all.js"></script>
<script type="text/javascript">
Sfdc.canvas.onReady(function () {
    Sfdc.canvas.client.refreshSignedRequest(function (data) {
    if (data.status === 200) {
        var encodedSignedRequest = data.payload.response;
        var sr = JSON.parse(Sfdc.canvas.decode(encodedSignedRequest.split('.')[1]));
        Sfdc.canvas.client.publish(sr.client, {
                name: 'namespace.event',
            payload: { "some":" data" }
            });
        } else {
            console.log(data);
    }
     });
});
</script>    

The only change I've made from our production code is to move the decoding of the signed request in the external app to the client-side (which you would never do in a real deployment for obvious security reasons).

  • I copied this code line-for-line into my VF page and canvas app - and nothing works. I am using a signed request Canvas App – John Westenhaver Jun 18 '15 at 4:42
  • I see that the first line of the second script does not reference a valid javascript - but when I change it to a valid path, the script still doesn't work. Could you share the rest of the app? – John Westenhaver Jun 18 '15 at 5:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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