Salesforce Canvas Developer Guide Developer Guide
Reklama
Reklama
Canvas Developer Guide
Version 41.0, Winter ’18
@salesforcedocs
Last updated: November 2, 2017
©
Copyright 2000–2017 salesforce.com, inc. All rights reserved. Salesforce is a registered trademark of salesforce.com, inc., as are other names and marks. Other marks appearing herein may be trademarks of their respective owners.
CONTENTS
GETTING STARTED
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Chapter 1: Introducing Force.com Canvas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Enabling Canvas Personal Apps within an Organization
. . . . . . . . . . . . . . . . . . . . . . . . 8
Making an App a Canvas Personal App
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Uninstalling a Canvas Personal App
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Chapter 2: Quick Start
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Chapter 3: Quick Start—Advanced
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Configure Who Can Access the Canvas App
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Configure Who Can Access the Installed Canvas App
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
USING FORCE.COM CANVAS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Chapter 4: Force.com Canvas SDK
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Referencing the Force.com Canvas SDK
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Contents
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
SAML Single Sign-On for Canvas Apps
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Getting Context in Your Canvas App
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Getting a List of Chatter Users
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Automatically Resizing a Canvas App
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Explicitly Resizing a Canvas App
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Getting the Size of a Canvas App
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Handling Orientation Changes in Your Canvas App
. . . . . . . . . . . . . . . . . . . . . . . . . . 44
Implementing Canvas App Events
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Canvas App Events Considerations
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Subscribing to a Canvas App Event
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Unsubscribing from a Canvas App Event
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Using Streaming API in a Canvas App
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Subscribing to a Streaming API Event
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Unsubscribing from a Streaming API Event
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Using the <select> Tag in a Canvas App
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Chapter 5: Canvas Apps and Visualforce Pages
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Visualforce Page Code Examples
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Returning Fields in the Record Object
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Using Events between a Visualforce Page and a Canvas App
. . . . . . . . . . . . . . . . . . . . . . . 57
Publishing a Canvas Event from a Visualforce Page
. . . . . . . . . . . . . . . . . . . . . . . . . . 58
Resizing a Canvas App in a Visualforce Page
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Unsubscribing from Events in a Visualforce Page
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Chapter 6: Canvas Apps in a Page Layout or a Mobile Card
. . . . . . . . . . . . . . . . . . . 61
Where Canvas Apps Appear in a Page Layout
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Add a Canvas App to a Page Layout
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Chapter 7: Canvas Apps in the Publisher
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Set Canvas App Location and Create the Action
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Force.com Canvas SDK Publisher Events
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Publisher Context Considerations
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Contents
Publisher Canvas App Access Considerations
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Chapter 8: Canvas Apps in the Chatter Feed
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Chatter Feed Context Considerations
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Chatter Feed Canvas App Access Considerations
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Chapter 9: Canvas in the Salesforce App
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Set Canvas App Location and Add it to the Navigation Menu
. . . . . . . . . . . . . . . . . . . . . . . . 73
Salesforce App Context Considerations
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Salesforce App Access Considerations
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Salesforce App Navigation Methods for Use with Canvas Apps
. . . . . . . . . . . . . . . . . . . . . . 75
Chapter 10: Customizing Your App Lifecycle
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Creating a CanvasLifecycleHandler
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Associating Your CanvasLifecycleHandler with Your App
. . . . . . . . . . . . . . . . . . . . . . . . . . 80
Filtering CanvasRequest Context Data
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Controlling Canvas App Behavior
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Presenting User Error Messages
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Testing Your CanvasLifecycleHandler Implementation
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Distributing Your CanvasLifecycleHandler Class
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
REFERENCE
Chapter 11: Objects
Chapter 12: Force.com Canvas Limits
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
INDEX
GETTING STARTED
CHAPTER 1
Introducing Force.com Canvas
In this chapter ...
•
•
•
•
•
•
•
•
Force.com Canvas enables you to easily integrate a third-party application in Salesforce. Force.com
Canvas is a set of tools and JavaScript APIs that you can use to expose an application as a canvas app.
This means you can take your new or existing applications and make them available to your users as part of their Salesforce experience.
Instead of redesigning and reintegrating your external applications, you can now use these tools to integrate your technology within Force.com Canvas. Force.com Canvas includes tools that handle:
•
Authentication —If your application requires authorization, you can implement it by using a signed
request or OAuth 2.0.
•
Context —API support that enables you to retrieve context information about the environment in
which the canvas app is running.
•
Cross-domain XHR —JavaScript support for cross-domain XML HTTP requests back to the Salesforce
domain.
•
Resizing —Methods that support the ability to resize your canvas app.
•
Events —Events provide a JavaScript-based way to send and receive events between canvas apps.
Use events to enable communication between multiple canvas apps on a single page.
•
Canvas Apps in Visualforce —A Visualforce component that lets you expose your canvas app on a
Visualforce page.
•
Canvas Apps in the Publisher —Lets you add a canvas app as a custom action and expand the
publisher to include a canvas app.
•
Canvas Apps in the Chatter Feed
—Lets you expose your canvas apps as feed items.
•
Canvas in the Salesforce App —Makes your canvas apps available in the Salesforce app.
The third-party app that you want to expose as a canvas app can be written in any language. The only requirement is that the app has a secure URL (HTTPS).
SEE ALSO:
1
Introducing Force.com Canvas Force.com Canvas Scenarios
Force.com Canvas Scenarios
From a high-level view, there are two common scenarios where Force.com Canvas is implemented.
•
Application integration—You’re a partner, systems integrator, or customer that builds cloud apps, and you’d like to integrate these applications with Salesforce.
•
Application rationalization/enterprise desktop—You’re a large organization that has many existing apps that your users access in addition to Salesforce. You’d like to integrate these apps into Salesforce so that users can accomplish all of their tasks in one place.
SEE ALSO:
Where Canvas Apps Appear
Canvas apps can appear in a few places.
•
In the Canvas App Previewer in the organization in which it was created
•
In the Chatter feed, if you code the canvas app to appear there and the current user has access to the canvas app
•
On the Chatter tab, in the Chatter apps list, for any user who has been allowed access to it
•
As an option in the navigation menu in the Salesforce app, for any user who has been allowed access to it
•
In an Open CTI call control tool after you add it to the call center’s definition file
•
In the Chatter publisher and Salesforce app action bar, if you configure it to appear as a quick action
•
In a Salesforce Console after you add it as a custom console component
•
In a Visualforce page after you add it to a page and make that page available to users
•
In a Profile page in the Chatter apps list, for any user who has been allowed access to it
•
In a page layout for a standard or custom object after you add the canvas app to the page layout. Depending on where you place the canvas app on the page layout, the canvas app can appear in the record detail page or in a mobile card.
Where an installed canvas app appears depends on the values you select in the
Locations
field when creating the connected app in Salesforce.
•
Chatter Feed—The canvas app appears in the feed. If this option is selected, you must create a CanvasPost feed item and ensure that the current user has access to the canvas app.
•
Chatter Tab—The canvas app appears in the app navigation list on the Chatter tab. If this option is selected, the canvas app appears there automatically.
•
Console—The canvas app appears in the footer or sidebars of a Salesforce console. If this option is selected, you must choose where the canvas app appears in a console by adding it as a custom console component.
•
Layouts and Mobile Cards—The canvas app can appear on a page layout or a mobile card. If this option is selected, you choose where the canvas app appears by adding it to the page layout.
•
Mobile Nav—The canvas app is accessible from the navigation menu.
•
Open CTI—The canvas app appears in the call control tool. If this option is selected, you must specify the canvas app in your call center’s definition file for it to appear.
•
Publisher—The canvas app appears in the Chatter publisher and action bar. If this option is selected, you must also create a canvas custom action and add it to the global publisher layout or to an object’s page layout.
2
Introducing Force.com Canvas Supported Browsers
•
Visualforce Page—The canvas app can appear on a Visualforce page . If you add an
<apex:canvasApp>
component to expose a canvas app on a Visualforce page, be sure to select this location for the canvas app; otherwise, you’ll receive an error.
SEE ALSO:
Supported Browsers
Force.com Canvas supports the most recent versions of the following browsers:
•
Mozilla
®
Firefox
®
(preferred)
•
Google Chrome
™
•
Microsoft
®
Internet Explorer
®
(be sure Compatibility Mode is disabled)
•
Microsoft
®
Edge
•
Apple
®
Safari
®
(be sure to set the Block Cookies setting to Never)
See the supported browsers topics in the Salesforce online help for specific versions and some important considerations. Because
Force.com Canvas is not built on Lightning, it still supports Microsoft
®
Internet Explorer
®
11.
If your app uses session cookies, you might need to set your P3P header to allow for third-party cookies or change the browser settings to allow all session cookies.
SEE ALSO:
Supported Browsers
Supported Salesforce Editions
Force.com Canvas supports these Salesforce Editions:
Edition
Group
Professional
Enterprise
Unlimited
Performance
Developer
Yes
Yes
Yes
Yes
Create a canvas app
Yes*
Yes*
No
No
No
Yes
Publish a canvas app
No
No
Yes
Yes
Yes
Yes
Install a canvas app
Yes*
Yes*
3
Introducing Force.com Canvas User Permissions Required
*Group and Professional Editions can only use or create canvas apps that have a permitted users value of “Admin approved users are pre-authorized” if profiles and page layouts are enabled in the org.
SEE ALSO:
User Permissions Required
The following user permissions are required to create canvas apps and view them in the Canvas App Previewer:
•
“Customize Application”
•
“Modify All Data”
SEE ALSO:
Configure Who Can Access the Canvas App
Configure Who Can Access the Installed Canvas App
User Interface Considerations
Canvas Size
The frame size for canvas apps varies depending on the location where the app appears. When using the SDK, these values are returned in the
object.
Note: If you plan to use your canvas app in the Salesforce app, take into account mobile device screen sizes. For more information,
see Canvas in the Salesforce App.
Location
Chatter tab
Chatter feed
Open CTI
Publisher
Salesforce Console
Description
The default dimensions are 800 pixels (wide) by 900 pixels (high). The maximum dimensions are 1,000 pixels (wide) by 2,000 pixels (high).
The default dimensions are 420 pixels (wide) by 100 pixels (high). The maximum dimensions are 420 pixels (wide) by 400 pixels (high).
The default and maximum dimensions are determined by the way you set up the custom console component.
The way you set up the canvas publisher action determines the default height. The default width is 522 pixels. The maximum dimensions are
522 pixels (wide) by 500 pixels (high).
The default and maximum dimensions are determined by the way you set up the custom console component.
4
Introducing Force.com Canvas Canvas App Process
Location
Visualforce page
Description
The default dimensions are 800 pixels (wide) by 900 pixels (high). A developer can change these dimensions by modifying the attributes on
the apex:canvasApp Component .
Logo Image
The logo image associated with a canvas app is displayed when someone installs your canvas app or during OAuth authentication when the user is prompted to allow the app to run. We recommend that you use an image of size 256 pixels (high) by 256 pixels (wide).
Icon Image
The icon image associated with a canvas app is displayed in these locations.
•
To the left of the link to your canvas app on the Chatter tab, in the Chatter apps list
•
To the left of the link to your canvas app in the Canvas App Previewer
•
In the Salesforce navigation menu
We recommend that you use an image of size 60 pixels (wide) by 60 pixels (high) so that the icon appears correctly in both mobile and the Salesforce site. If you have no plans to display your icon in the Salesforce app, you can use a smaller icon size of 16 pixels (wide) by
16 pixels (high).
Thumbnail Image
The thumbnail image associated with a canvas app feed item is displayed when someone accesses your canvas app in the feed. If specified, this image appears next to the feed item title and description.
We recommend that you use an image of size 120 pixels (wide) by 120 pixels (high) or smaller.
SEE ALSO:
Canvas App Process
In the process of creating, publishing, installing, and running a canvas app, there are actions required by the developer, the administrator, and the user, as shown in the following diagram.
5
Introducing Force.com Canvas Canvas App Process
6
Introducing Force.com Canvas Canvas Personal Apps
SEE ALSO:
Enabling Canvas Personal Apps within an Organization
Canvas Personal Apps
Canvas personal apps let you create connected apps that are designed specifically for end users across organizations. With a canvas personal app, you make your own app available for installation without relying on organization administrators for distribution.
Previously, only administrators could install canvas apps. Administrators can still install canvas apps, but now developers can create canvas personal apps that end users can install themselves.
End users install and use canvas personal apps right from the Chatter tab (provided that they have appropriate permissions in Salesforce).
When end users install the app, they are prompted to allow the app to use their Salesforce data.
Creating a canvas personal app is similar to creating any canvas app, except that:
•
Users are prompted to approve or deny a canvas personal app the first time they access the app, regardless of whether you’ve used
OAuth or signed request as the access method. This is because initial access triggers the OAuth approval flow. After initial access, users are identified transparently and are not prompted for approval or credentials (as long as they are logged in to Salesforce).
•
With a canvas personal app, only the app’s metadata is installed, without the other package components (such as Apex classes and
Visualforce components). This facilitates widespread installation of the app, and lets you limit the app’s functionality to only what the end user needs.
For information about managed and unmanaged packages, see “Overview of Packages” in the ISVforce Guide .
Canvas Personal App Process
Creating a canvas personal app is similar to creating any canvas app. However, you distribute a canvas personal app directly to end users, who install it via a link that you provide, integrating the app with their Salesforce data. After the app is installed, end users run it right from the Chatter tab.
Here’s how to make canvas personal apps available to end users.
Canvas Personal Apps within an Organization on page 8.
on page 8.
3. The end user clicks the app link that you’ve provided. For example, the link could be a button on your website, or delivered in an email. Clicking the link invokes the OAuth approval process for the app. Here’s an example of what a link to the app looks like: https://login.salesforce.com/services/oauth2/authorize?response_type=code&client_id=<your_client_id>&redirect_uri=<your_redirect_uri>
4. When prompted, the end user approves the app and allows access to Salesforce data.
5. The OAuth approval flow triggers the canvas installer in asynchronous mode. The canvas installer gets context information for the app from the API, and installs the app’s metadata. The app is installed in the background, and the end user receives an email when installation is complete.
7
Introducing Force.com Canvas Enabling Canvas Personal Apps within an Organization
Note: Only the canvas personal app’s metadata is installed. Any additional components that are typically packaged with a canvas app are not installed with the app. This means that users get only the functionality they need, and installation is quick and lightweight. However, if the administrator chooses to install the canvas personal app for the entire organization, the additional package components are installed, as with any canvas app.
6. The user starts using the canvas personal app by clicking the app’s icon from the Chatter tab.
SEE ALSO:
Making an App a Canvas Personal App
Enabling Canvas Personal Apps within an Organization
The administrator of an organization controls whether users can install canvas personal apps within that organization. Before attempting to create a canvas personal app, verify that the organization administrator has enabled canvas personal apps.
Here’s how the organization administrator enables canvas personal apps.
1. From Setup, enter
Connected Apps
in the
Quick Find
box, then select the option for managing connected apps.
2. Next to App Access Settings, click Edit.
3. Select the Allow users to install canvas personal apps checkbox.
4. Click Save.
After the administrator has done these steps, you can designate your canvas app as a canvas personal app. For details, see
App a Canvas Personal App on page 8.
SEE ALSO:
Making an App a Canvas Personal App
You (the app’s developer) can enable an app as a canvas personal app when you first create it, or make your existing canvas app a canvas personal app. This process involves ensuring that an organization preference is active, and activating a setting on the app’s Detail page.
In order for you to make an app a canvas personal app:
8
Introducing Force.com Canvas Uninstalling a Canvas Personal App
•
The administrator for the app’s destination organization must enable canvas personal apps in that organization. To do so, from Setup, enter
Connected Apps
in the
Quick Find
box, then select the option for managing connected apps.
•
You need to enable the app as a canvas personal app, as follows.
1. In the Locations field, select Chatter Tab. If this is a canvas personal app, Chatter Tab is the only location where a canvas personal app can appear.
2. Under Canvas App Settings, select the Enable as a Canvas Personal App checkbox. This setting is available only when Chatter
Tab is selected as the app’s location.
After you’ve created the canvas personal app and provided a link to it, end users can access the app and install it themselves.
SEE ALSO:
Uninstalling a Canvas Personal App
When a user installs and allows a canvas personal app, a refresh token is created, which in turn generates an OAuth token. To stop end users from accessing the app, this refresh token must be revoked. This action effectively uninstalls the canvas personal app.
Here’s how a canvas personal app can be uninstalled.
•
The organization administrator removes the refresh token for one or all users in the organization via the Connected Apps OAuth
Usage page in Setup.
•
End users revoke the canvas personal app from their Connected Apps list.
•
The administrator explicitly uninstalls the canvas personal app from the organization via the Manage Apps page in Setup. This action removes the app from the organization.
If an organization administrator disables canvas personal apps within the organization after a canvas personal app is installed, the canvas personal app continues to work. This is because the app’s version number and URL persist, regardless of how the organization preference for canvas personal apps is set.
9
Introducing Force.com Canvas Uninstalling a Canvas Personal App
However, the administrator can explicitly uninstall the app, completely removing it from use within the organization.
SEE ALSO:
10
CHAPTER 2
Quick Start
In this chapter ...
•
•
•
This simple quick start shows you how to get started with Force.com Canvas by using the Heroku Quick
Start. The Heroku Quick Start creates a “hello world” app on Heroku in either Java or Ruby, depending on the template you select. At the same time, it creates a corresponding canvas app in Salesforce.
The Heroku app is a “hello world” Web page that calls the Force.com Canvas SDK to display information about the current user and lets you post to the current user’s Chatter feed.
SEE ALSO:
11
Quick Start Prerequisites
Prerequisites
You need the appropriate access and tools to complete the quick start steps.
•
Access to a Developer Edition organization.
If you are not already a member of the Force.com developer community, go to developer.salesforce.com/signup and follow the instructions for signing up for a Developer Edition organization. Even if you already have Enterprise Edition, Unlimited
Edition, or Performance Edition, use Developer Edition for developing, staging, and testing your solutions against sample data to protect your organization’s live data. This is especially true for applications that insert, update, or delete data (as opposed to simply reading data).
If you have an existing Developer Edition organization, and, from Setup, you don’t see the menu item Canvas App Previewer, contact Salesforce.
•
“Customize Application” and “Modify All Data” user permissions. If you’re an administrator, you most likely already have these permissions. Otherwise, you need to add them so that you can see the Canvas App Previewer and create canvas apps.
•
A Heroku account. Go here to create a Heroku account: https://api.heroku.com/signup
.
•
Java version 1.6 or 1.7 to run the local instance of the “hello world” app that you create. (The Heroku instance of the app automatically downloads the correct version of Java.)
SEE ALSO:
Create the App
In this step, you’ll create both the Heroku “hello world” app and the associated canvas app in your Salesforce organization.
1. In Salesforce, from Setup, enter
Canvas App Previewer
in the
Quick Find
box, then select Canvas App Previewer.
2. Click Heroku Quick Start.
3. In the
Template
field, select Java – Quick Start Template.
4. In the
Canvas App Name
field, enter a unique name of up to 30 characters.
5. In the
Heroku App Name
field, enter a unique name of up to 30 characters that begins with a letter and contains only lowercase letters, numbers, and dashes. The
newappName
must be unique across all Heroku apps. This name becomes part of the URL for your app, for example,
newappName.herokuapp.com
.
6. In the
Auth Type
field, select OAuth or API Key. Heroku OAuth initiates the Heroku OAuth flow or uses the Heroku token if you’re logged in to Heroku. Find the API key associated with your account on the Heroku
My Account
page.
7. Click Create. The app displays in the left navigation pane.
If you see an error like “Error [Read timed out] executing POST to Heroku clone REST service,” this means the operation has timed out trying to contact Heroku. You can check the status of Heroku at http://status.heroku.com
.
Note:
If you have two-factor authentication enabled and select OAuth, first enter your Heroku username and password and then your two-factor authentication information. Close the OAuth prompt and click Create again, and the app now displays in the navigation pane.
12
Quick Start Set the App Location
8. Click the link to your new app on the left.
The app appears and you’ll see the message
Hello
User.FullName
, as well as other information about the current user.
You just created a canvas app—congratulations! You’ll only be able to see your canvas app in the Canvas App Previewer until you set
the locations where it can appear by following the steps in Set the App Location
. This defines where a user sees your app after it’s installed in their organization.
Behind the scenes, the Heroku Quick Start sets the canvas app’s
Permitted Users
, which includes admin-approved users and your profile. For example, if your user profile is System Administrator, that profile is added to the canvas app you just created, and any users with that profile can access the canvas app.
We recommend that you inspect the code to see how the canvas app works. The source code for the app is available in public GitHub repositories for the Java app and Ruby app . Use the example code in these apps to learn how to decode and validate the canvas signed request in your app.
SEE ALSO:
Set the App Location
In this step, you’ll specify where your canvas app can display to a user in Salesforce.
1. In the Salesforce application, from Setup, enter
Apps
in the
Quick Find
box, then select Apps.
2. In the Connected Apps related list, click the app you just created and then click Edit.
3. In the Canvas Apps Settings section, in the
Locations
field, select where the canvas app can appear to the user. For this walkthrough, select Chatter Tab.
•
Chatter Feed—The canvas app appears in the feed. If this option is selected, you must create a CanvasPost feed item and ensure that the current user has access to the canvas app.
•
Chatter Tab—The canvas app appears in the app navigation list on the Chatter tab. If this option is selected, the canvas app appears there automatically.
•
Console—The canvas app appears in the footer or sidebars of a Salesforce console. If this option is selected, you must choose where the canvas app appears in a console by adding it as a custom console component.
•
Layouts and Mobile Cards—The canvas app can appear on a page layout or a mobile card. If this option is selected, you choose where the canvas app appears by adding it to the page layout.
•
Mobile Nav—The canvas app is accessible from the navigation menu.
•
Open CTI—The canvas app appears in the call control tool. If this option is selected, you must specify the canvas app in your call center’s definition file for it to appear.
•
Publisher—The canvas app appears in the Chatter publisher and action bar. If this option is selected, you must also create a canvas custom action and add it to the global publisher layout or to an object’s page layout.
•
Visualforce Page—The canvas app can appear on a Visualforce page . If you add an
<apex:canvasApp>
component to expose a canvas app on a Visualforce page, be sure to select this location for the canvas app; otherwise, you’ll receive an error.
4. Click Save.
13
Quick Start
Because you selected Chatter Tab, your canvas app now appears in the left navigation pane on the Chatter tab.
SEE ALSO:
Set the App Location
14
CHAPTER 3
Quick Start—Advanced
In this chapter ...
•
•
•
•
•
•
•
•
•
•
•
This advanced quick start shows you how to get started with more of the Force.com Canvas features. It takes you step-by-step through the process of creating, packaging, uploading, installing, and running a canvas app. The sample canvas app is a “hello world” Web page that calls the Force.com Canvas SDK to display the current user’s name.
In this example, you’ll:
•
Clone the “hello world” app from GitHub
•
Run the app on a local Web server
•
Expose the Web app as a canvas app in your Salesforce development organization and test it in the
Canvas App Previewer
•
Deploy the Web app to Heroku
•
Package and upload the canvas app
•
Install the canvas app in another Salesforce organization and run it as a user would
The steps in this quick start assume you’re using Windows. You can use another OS, but there might be some minor differences in the steps.
SEE ALSO:
15
Quick Start—Advanced Prerequisites
Prerequisites
You need the appropriate access and tools to complete the quick start steps.
•
Access to a Developer Edition organization for developing your canvas app. To install your canvas app, you’ll need a Developer
Edition organization other than the one you use to create the canvas app.
If you are not already a member of the Force.com developer community, go to developer.salesforce.com/signup and follow the instructions for signing up for a Developer Edition organization. Even if you already have Enterprise Edition, Unlimited
Edition, or Performance Edition, use Developer Edition for developing, staging, and testing your solutions against sample data to protect your organization’s live data. This is especially true for applications that insert, update, or delete data (as opposed to simply reading data).
If you have an existing Developer Edition organization, and, from Setup, you don’t see the menu item Canvas App Previewer, contact Salesforce.
•
“Customize Application” and “Modify All Data” user permissions. If you’re an administrator, you most likely already have these permissions. Otherwise, you need to add them so that you can see the Canvas App Previewer and create canvas apps.
•
Git installed. Go here to install and configure Git: https://help.github.com/articles/set-up-git
.
After you install Git, you might need to configure SSH by using the keygen tool. See https://help.github.com/articles/generating-ssh-keys
for more information. If you’re using Windows, this tool is located in the Git
\bin
directory, which isn’t added to the path after you install Git. Add the
\bin
directory to your path by using Control Panel. Depending on your installation directory, the path might be something like
C:\Program Files
(x86)\Git\bin
.
•
A GitHub account to clone the code example. Go here to set up a GitHub account: https://github.com/plans
.
•
Maven 3.0 or greater installed to package the sample app. Go here to download and install Maven: http://maven.apache.org/download.html
.
•
A Heroku account if you want to run the app from Heroku. Go here to create a Heroku account: https://api.heroku.com/signup
.
•
Heroku Toolbelt if you want to manage the Heroku app from the command line. Go here to download and install Heroku Toolbelt: https://toolbelt.heroku.com
.
SEE ALSO:
Clone the Project from GitHub
The “hello world” sample project is part of the Force.com Canvas SDK which is located on GitHub. In this step, we’ll clone the project to make a copy of it on your local machine.
1. Log into https://github.com
.
2. Locate the project that contains the Force.com Canvas SDK and code examples by going to: https://github.com/forcedotcom/SalesforceCanvasFrameworkSDK
.
3. Clone the project by clicking Zip and downloading the .zip file.
16
Quick Start—Advanced Run the Web App Locally
4. Extract all the files from the zip file locally into a directory called c:\SalesforceCanvasFrameworkSDK
. Alternatively, you can download the project by using the Git command line and issuing this command: git clone [email protected]:forcedotcom/SalesforceCanvasFrameworkSDK.git
.
5. Open a command window and navigate to c:\SalesforceCanvasFrameworkSDK
.
6. Enter the command git submodule init
.
7. Enter the command git submodule update
. This adds other projects into the current project. The file c:\SalesforceCanvasFrameworkSDK\.gitmodules
shows you which projects are included as submodules.
After you clone the project, the c:\SalesforceCanvasFrameworkSDK
directory should contain a subdirectory named src
, as well as files like pom.xml
and
README.md
.
SEE ALSO:
Run the Web App Locally
In this step, you’ll package the Web app using Maven and then run it locally using Jetty. When you package the Web app, the process downloads all the components needed to run the Web app, including Jetty.
1. Open a command window and navigate to c:\SalesforceCanvasFrameworkSDK
.
2. Enter the command mvn package
. You’ll see output in the command window as Maven packages the app and its dependent components. If the process completes successfully, you’ll see something like this:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 28.016s
[INFO] Finished at: Tue Jul 03 08:00:42 PDT 2012
[INFO] Final Memory: 8M/59M
[INFO] ------------------------------------------------------------------------
3. To use Jetty to run the app, you’ll need to enable local SSL support. This step only needs to be done once per app, so if you’ve already done this, skip this step. Ensure that the command window is open and you’re in the directory c:\SalesforceCanvasFrameworkSDK
.
4. Run the following command: keytool -keystore keystore -alias jetty -genkey -keyalg RSA
.
After you run this command, you’ll be prompted for the following information. Enter
123456
for the keystore password and yes to confirm at the end. When prompted, “Enter key password for <jetty>,” press Enter to use the keystore password. For the other information, you can enter values or leave them blank.
Enter keystore password: <Choose Your Password>
Re-enter new password: <Choose Your Password>
What is your first and last name?
[Unknown]: <Enter First and Last Name>
What is the name of your organizational unit?
[Unknown]: <Enter an Org Unit>
What is the name of your organization?
17
Quick Start—Advanced Create the Canvas App
[Unknown]: <Enter an Org>
What is the name of your City or Locality?
[Unknown]: <Enter a City>
What is the name of your State or Province?
[Unknown]: <Enter a State>
What is the two-letter country code for this unit?
[Unknown]: <Enter a Country>
Is CN=XXXX, OU=XXXX, O=XXXX, L=XXXX, ST=XX, C=XX correct?
[no]: yes
Enter key password for <jetty>
(RETURN if same as keystore password):
This creates a file named keystore
in the directory c:\SalesforceCanvasFrameworkSDK
. The keystore is used by
Jetty for SSL support.
5. Run the Web server by entering this command: target\bin\webapp.bat
(Windows) or sh target/bin/webapp
(Unix/OS X).
If you’re using Unix/OS X, you may need to add execute permissions to webapp
before you can run it. Use this command to do so: chmod +x target/bin/webapp
.
6. Verify that the app is running by opening a browser and navigating to the following URL: https://localhost:8443/examples/hello-world/index.jsp
.
Depending on your browser and security settings, you might need to add a security exception because you’re running a site with an unsigned SSL certificate.
You should see a message that says, “This App must be invoked via a signed request!” This is an indication that the Web app is running locally. This message appears because the app is designed to receive a signed request from Salesforce, therefore, the app won’t run outside of the Salesforce canvas environment.
SEE ALSO:
Create the Canvas App
In this step, you’ll create the canvas app in your Salesforce organization. You’ll need user permissions “Customize Application” and
“Modify All Data” to create a canvas app.
1. In Salesforce, from Setup, enter
Apps
in the
Quick Find
box, then select Apps.
2. In the Connected Apps related list, click New.
3. In the
Connected App Name
field, enter Hello World.
4. Accept the default
API Name
of Hello_World. This is the internal name of the canvas app and can’t be changed after you save it.
5. In the
Contact Email
field, enter your email address.
6. In the
Logo Image URL
field, enter https://localhost:8443/images/salesforce.png
. This is the default
Salesforce “No Software” image. This image appears on the installation screen and on the detail screen for the app.
18
Quick Start—Advanced Create the Canvas App
7. In the
Icon URL
field, enter https://localhost:8443/examples/hello-world/logo.png
. This is the default
Salesforce “No Software” image.
This is the image that appears next to the app name in the user interface. If you leave this field blank, a default cloud image appears next to the app name.
8. In the API (Enable OAuth Settings) section, select the
Enable OAuth Settings
field.
9. In the
Callback URL
field, enter https://localhost:8443/sdk/callback.html
.
10. In the
Selected OAuth Scopes
field, select Access your basic information.
11. In the Canvas App Settings section, select
Force.com Canvas
.
12. In the
Canvas App URL
field, enter https://localhost:8443/examples/hello-world/index.jsp
.
13. In the
Access Method
field, select Signed Request (Post).
14. In the
Locations
field, select Chatter Tab.
15. Click Save. After the canvas app is saved, the detail page appears.
16. On the detail page for the canvas app, next to the
Consumer Secret
field, click the link
Click to reveal
. The consumer secret is used in the app to authenticate.
17. Select the consumer secret value and enter CTRL+C to copy it.
18. Go to the command window and stop the Jetty Web server by entering CTRL+C. At the prompt, enter Y.
19. Create an environment variable named
CANVAS_CONSUMER_SECRET
and set that value to the consumer secret you just copied.
To do this in Windows, in the command window, enter set CANVAS_CONSUMER_SECRET=
value_you_just_copied
.
If you’re using Unix/OS X, set the environment variable with the command export
CANVAS_CONSUMER_SECRET=
value_you_just_copied
.
The “hello world” page
( c:\SalesforceCanvasFrameworkSDK\src\main\webapp\examples\hello-world\index.jsp
) uses the consumer secret, as shown in the following code:
<%@ page import = "canvas.SignedRequest" %>
<%@ page import = "java.util.Map" %>
<%
// Pull the signed request out of the request body and verify and decode it.
Map<String, String[]> parameters = request.getParameterMap();
String[] signedRequest = parameters.get( "signed_request" ); if (signedRequest == null) {%>
This app must be invoked via a signed request!<% return ;
}
String yourConsumerSecret=System.getenv( "CANVAS_CONSUMER_SECRET" );
String signedRequestJson = SignedRequest.verifyAndDecodeAsJson(signedRequest[0], yourConsumerSecret);
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
<html xmlns= "http://www.w3.org/1999/xhtml" lang= "en" >
<head>
<title>Hello World Canvas Example</title>
19
Quick Start—Advanced Configure Who Can Access the Canvas App
<link rel= "stylesheet" type= "text/css" href= "/sdk/css/connect.css" />
<script type= "text/javascript" src= "/sdk/js/canvas-all.js" ></script>
<!-- Third part libraries, substitute with your own -->
<script type= "text/javascript" src= "/scripts/json2.js" ></script>
<script> if (self === top) {
// Not in an iFrame.
alert( "This canvas app must be included within an iFrame" );
}
Sfdc.canvas(function() { var sr = JSON.parse( '<%=signedRequestJson%>' );
Sfdc.canvas.byId( 'username' ).innerHTML = sr.context.user.fullName;
});
</script>
</head>
<body>
<br/>
<h1>Hello <span id= 'username' ></span></h1>
</body>
</html>
20. Restart the Web server by entering this command: target\bin\webapp.bat
(Windows) or sh target/bin/webapp
(Unix/OS X).
SEE ALSO:
Configure Who Can Access the Canvas App
Configure Who Can Access the Canvas App
You’ve created the canvas app in Salesforce, now let’s configure access for specific users..
1. In Salesforce, from Setup, enter
Connected Apps
in the
Quick Find
box, then select the option for managing connected apps.
2. Click the Hello World app, and then Edit.
3. In the
Permitted Users
field, select "Admin approved users are pre-authorized." Click OK on the pop-up message that appears.
We selected "Admin approved users are pre-authorized," so users won’t see the canvas app until we give them permissions. If we selected "All users may self-authorize," users would see the canvas app but would need to approve or deny access to it.
20
Quick Start—Advanced Deploy the Web App to Heroku
4. Click Save.
This is where you define who can see your canvas app. This can be done using profiles and permission sets. In this example, we assume that your profile is System Administrator.
5. In the Profiles related list, click Manage Profiles.
6. Select the
System Administrator
profile and click Save.
7. In Salesforce, from Setup, enter
Canvas App Previewer
in the
Quick Find
box, then select Canvas App Previewer.
You can use the Canvas App Previewer to test out your canvas app before publishing it.
8. Click the Hello World link on the left.
The app appears and you’ll see the message
Hello
User.FullName
. The canvas app works in this context because when you click the app name in the previewer, the signed request is sent to the endpoint https://localhost:8443/examples/hello-world/index.jsp
.
After configuring access, you can see the canvas app in the Canvas App Previewer and on the Chatter tab in your development organization.
SEE ALSO:
Deploy the Web App to Heroku
In this walkthrough, you previously ran the “hello world” Web app locally before adding it as a canvas app and testing it. Now that your canvas app works locally, you’re ready to deploy your “hello world” Web app to Heroku and run it from there. Here’s how you do it.
.
2. Open a command window, navigate to c:\SalesforceCanvasFrameworkSDK
, and enter the following command: git init
. This re-initializes the directory as a Git repository.
3. In the command window, enter the following command: heroku create
. This creates a new “shell” app on Heroku.
Confirmation that the app was created looks like this:
Creating deep-samurai-7923... done, stack is cedar http://deep-samurai-7923.herokuapp.com/ | [email protected]:deep-samurai-7923.git
Git remote heroku added
4. To rename this Heroku app, enter the following command in the command window: heroku rename newAppName -—app
oldAppName
.
In this example,
oldAppName
is deep-samurai-7923. The
newAppName
you create must begin with a letter and can only contain lowercase letters, numbers, and dashes. You’ll see a confirmation of the renaming that looks similar to this: http://
newappName
.herokuapp.com/ | [email protected]:
newappName
.git
The
newappName
must be unique across all Heroku apps. This name becomes part of the URL for your app, for example,
newappName.herokuapp.com
.
21
Quick Start—Advanced Update the Canvas App
5. Run the following command in the command window: git add -A
. This adds the entire SalesforceCanvasFrameworkSDK project to the Git repository. If you’re working in the Windows environment, you might see some messages about LF (line feeds) being replaced by CRLF (carriage return line feeds).
6. Enter the following command in the command window to commit the changes along with a comment: git commit —m
“ MyChangeComments”
.
7. Enter the following command in the command window to deploy the changes to Heroku: git push heroku master
.
If the process completes successfully, you’ll see something like this:
[INFO] -------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] -------------------------------------------------
[INFO] Total time: 13.188s
[INFO] Finished at: Sat Feb 09 21:14:23 UTC 2013
[INFO] Final Memory: 11M/490M
[INFO] -------------------------------------------------
If you receive a “permission denied” error message, you may need to set up your SSH key and add it to Heroku. See https://devcenter.heroku.com/articles/keys
.
8. Open a command window, and set the Heroku environment variable that contains the consumer secret by entering this command and replacing
consumer_secret_value
with the value you just copied: heroku config:add
CANVAS_CONSUMER_SECRET=
consumer_secret_value
.
To get the consumer secret for the canvas app, from Setup, enter
Apps
in the
Quick Find
box, then select Apps and click the
Hello World app. You’ll see the Consumer Secret field in the OAuth Settings section.
9. Verify that the app is running in Heroku by opening a browser and navigating to the following URL: https://newappName.herokuapp.com/examples/hello-world/index.jsp
.
You should see a message that says, “This App must be invoked via a signed request!” This is an indication that the app is running in Heroku. This message appears because the app is designed to receive a signed request from Salesforce, therefore, the app won’t run outside of the Salesforce canvas environment.
SEE ALSO:
Configure Who Can Access the Canvas App
Update the Canvas App
In this step, you’ll update the canvas app to run the “hello world” app that’s now running on Heroku.
1. In Salesforce, from Setup, enter
Apps
in the
Quick Find
box, then select Apps.
2. In the Connected Apps related list, click Hello World.
3. Click Edit.
4. In the
Logo Image URL
field, enter https://appName.herokuapp.com/images/salesforce.png
. This is the default Salesforce “No Software” image. This image appears on the installation screen and on the detail screen for the app. The
appName
is the name of Heroku app that you just created.
22
Quick Start—Advanced Package the Canvas App
5. In the
Icon URL
field, enter https://appName.herokuapp.com/examples/hello-world/logo.png
. This is the default Salesforce “No Software” image.
This is the image that appears next to the app name on the Chatter tab or in the Canvas App Previewer. If you leave this field blank, a default cloud image appears next to the app name. The
appName
is the name of Heroku app that you just created.
6. In the
Callback URL
field, enter https://appName.herokuapp.com/sdk/callback.html
. The
appName
is the name of Heroku app that you just created.
7. In the
Canvas App URL
field, enter https://appName.herokuapp.com/examples/hello-world/index.jsp
.
The
appName
is the name of Heroku app that you just created.
8. Click
Save
. After the canvas app is saved, the detail page appears.
9. In Salesforce, from Setup, enter
Canvas App Previewer
in the
Quick Find
box, then select Canvas App Previewer.
You can use the Canvas App Previewer to test out your canvas app before repackaging it.
10. Click the Hello World link on the left.
The app should appear and you’ll see the message
Hello
User.FullName
. The canvas app works in this context because when you click the app name in the previewer, the signed request is sent to the endpoint https://appName.herokuapp.com/examples/hello-world/index.jsp
.
In this example, we’re using the same canvas app that we just created, but updating it to point to the “hello world” Web app running on Heroku. Therefore, the consumer secret that we previously added to our “hello world” app doesn’t need to be updated.
If you want to create a new canvas app in Salesforce that displays the “hello world” app running on Heroku, then go to
to create the new app, update the consumer secret in the app, and then deploy the changes to Heroku.
SEE ALSO:
Package the Canvas App
Now that you’ve created the canvas app, tested it in the Canvas App Previewer, and deployed it to Heroku, you’re ready to package and distribute it. Packaging is the first step in making your canvas app available for installation in another organization. For more information about packaging, see the ISVforce Guide .
1. In Salesforce, from Setup, enter
Packages
in the
Quick Find
box, then select Packages and click New.
Tip:
To package your canvas app for installation in other organizations, you must create a namespace prefix. A namespace prefix can only be defined in a Developer Edition organization. For more information, see the topic “Registering a Namespace
Prefix” in the online help.
2. Set the
Package Name
field to Hello World Package and accept the defaults for the other fields.
3. Select the
Managed
field to make the package the managed package for the organization.
4. A prompt appears stating you’re only allowed one managed package. Click OK.
5. Click Save.
6. The package is empty, so click Add.
7. In the
Component Type
field, select Connected App.
23
Quick Start—Advanced Upload the Canvas App Package
8. Select the checkbox next to the Hello World app and click Add To Package. The Package Detail screen appears. From Setup, enter
Packages
in the
Quick Find
box, then select Packages to see the new managed package.
Now you’re ready to upload the package you created and get the installation link. Use the installation link to install your canvas app in another organization.
SEE ALSO:
Understanding Managed and Unmanaged Packages
Distributing Your CanvasLifecycleHandler Class
Upload the Canvas App Package
Now that you’ve packaged the canvas app, you’re ready to upload the package. This creates an installation link that you can provide to anyone who needs to install your canvas app in their organization.
1. In Salesforce, from Setup, enter
Packages
in the
Quick Find
box, then select Packages.
2. In the Packages list, click the Hello World Package link.
3. On the Package Detail page, click Upload to publish the managed package.
4. In the
Version Name
field, enter Winter 2014 Beta. Keep the default Version Number of 1.0 and Release Type of Managed—Beta.
5. Click Upload.
Note: A canvas app can only be installed in an organization other than the one you’re developing in.
After the upload completes, the Version Detail page appears. The Installation URL field contains the URL that you can use to install the canvas app in another organization. You’ll also receive a notification email that contains the installation URL.
SEE ALSO:
Publishing Your App
Install the Canvas App
Uploading the packaged canvas app creates the installation link. You can then use this link to install the canvas app in another organization.
Beta packages can only be installed in sandbox or Developer Edition organizations, otherwise, you’ll receive an error.
1. Open a browser and enter the canvas app installation URL in the browser address bar. If you’re in the process of developing your canvas app, be sure to log out of your development organization before you install the app.
The installation URL looks something like: https://login.instance.salesforce.com/services/packaging/installPackage.apexp?p0=04eU0000000AWNA
.
24
Quick Start—Advanced Configure Who Can Access the Installed Canvas App
2. When prompted, enter your login credentials for the organization in which you’re installing the package.
3. The Package Installation Details page appears. In the Package Components list, you should see the Hello World canvas app. Click
Continue.
4. Click Next and then click Install.
After the package installation completes successfully, you’ll receive an email notification.
SEE ALSO:
Configure Who Can Access the Installed Canvas App
Configure Who Can Access the Installed Canvas App
You’ve installed the canvas app in your Salesforce organization, but no one can see it until you configure user access.
1. In Salesforce, from Setup, enter
Connected Apps
in the
Quick Find
box, then select the option for managing connected apps.
2. Click the Hello World app, and then click Edit.
3. In the
Permitted Users
field, select Admin approved users are pre-authorized. Click OK on the pop-up message that appears.
4. Click Save.
Now you’ll define who can see your canvas app. This can be done using profiles and permission sets. In this example, we’ll allow anyone with the System Administrator to access the app.
5. On the Connected App Detail page, in the Profiles related list, click Manage Profiles.
6. Select the
System Administrator
profile and click Save.
7. Click the Chatter tab.
8. Click the Hello World link on the left.
The app appears and you’ll see the message
Hello
User.FullName
.
SEE ALSO:
25
USING FORCE.COM CANVAS
CHAPTER 4
Force.com Canvas SDK
In this chapter ...
•
•
•
•
•
•
•
Using Streaming API in a Canvas App
•
•
Force.com Canvas is a set of tools that enable you to integrate your apps within Salesforce. This framework includes an SDK that you can use to authenticate your app and retrieve data from Salesforce. The
Force.com Canvas SDK and code examples are available on GitHub at https://github.com/forcedotcom/salesforcecanvasframeworksdk
.
The Force.com Canvas SDK is versioned and matches the API version in each release. The current version is 41.0. You can find out the version of the SDK that you have by calling the version
method. Previous versions of this developer’s guide can be found at https://developer.salesforce.com/page/Earlier_Reference_Documentation
.
SEE ALSO:
Referencing the Force.com Canvas SDK
Getting Context in Your Canvas App
Implementing Canvas App Events
26
Force.com Canvas SDK Referencing the Force.com Canvas SDK
Referencing the Force.com Canvas SDK
The Force.com Canvas SDK is available on GitHub , and you have two options for referencing it from your canvas app.
•
Host the SDK on your own Web server and access it there
•
Access the SDK hosted on the Salesforce server
For example, here’s what the include statement looks like if you host the SDK on your own Web server:
<script type= "text/javascript" src= "/sdk/js/canvas-all.js" > </script >
Here’s what the include statement looks like if you reference the hosted SDK:
<script type= "text/javascript" src= "https://<instance>.salesforce.com/canvas/sdk/js/ 41.0/canvas-all.js
"></script>
The ability to reference the SDK on the Salesforce server is useful when you want to include one of the SDK files in a Web app or from a
Visualforce page.
SEE ALSO:
Authentication
When you create a canvas app, you can use one of the following authentication methods:
•
—The default method of authentication for canvas apps. The signed request authorization flow varies depending on whether you configure the canvas app so that the administrator gives users access to the canvas app or if users can self-authorize.
The signed request containing the consumer key, access token, and other contextual information is provided to the canvas app if the administrator has allowed access to the canvas app for the user or if the user has approved the canvas app via the approve/deny
OAuth flow.
•
OAuth and the Force.com platform, see https://developer.salesforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com
.
SEE ALSO:
Understanding Authentication
Canvas App User Flow—Signed Request
Signed Request Authentication
This is the default authorization method for canvas apps. The signed request authorization flow varies depending on whether the canvas app’s Permitted Users field is set to "Admin approved users are pre-authorized" or "All users may self-authorize."
27
Force.com Canvas SDK Signed Request Authentication
Permitted Users Value
Admin approved users are pre-authorized
All users may self-authorize
Canvas App
Accessibility
When the User
Needs to Approve the Canvas App
The app is accessible to users as soon as the administrator installs it in the organization and configures which users can see it. Users don’t need to approve or deny access.
Never
POST or GET Behavior
Salesforce performs a POST to the canvas app with all the authorization information contained in the body of the signed request, including the refresh token.
The app is accessible to all users, but the user is prompted to approve or deny access to the app.
•
The first time that the user opens the app
•
If the access token is revoked by the administrator
•
If the administrator sets a time limit on the token and that time limit is exceeded
If the user has previously approved the app and the access hasn’t been revoked or expired,
Salesforce performs a POST to the canvas app with a signed request payload.
If the user hasn’t approved the app, or if the access has been revoked or expired, Salesforce performs a GET to the canvas app URL. The canvas app must handle the GET by accepting the call and looking for the URL parameter
_sfdc_canvas_authvalue
. If the canvas app receives this parameter value, the canvas app should initiate the approve or deny OAuth flow.
_sfdc_canvas_authvalue = user_approval_required
After the OAuth flow is initiated and the user approves the app, the canvas app should call the repost()
method with a parameter of
true
to retrieve the signed request.
The signed request information can be verified with the client secret and used to customize the app, and make subsequent calls to
Salesforce.
The signed request is a string of the following elements concatenated:
•
The canvas app consumer secret encrypted with HMAC SHA–256 algorithm
•
A period (“.”)
•
The context and authorization token JSON encoded in Base64
The signed request looks similar to this, although it will be much longer:
9Rpl6rE7R2bSNjoSfYdERk8nffmgtKQNhr5U/5eSJPI=.eyJjb250ZXh0Ijp7InVzZXIiOnsibGFuZ3V
....
Signed request considerations:
•
Salesforce performs an HTTP POST or GET when invoking the canvas app URL, depending on the Permitted Users value and whether the refresh token is returned.
•
Server-side code is needed to verify and decode the request.
28
Force.com Canvas SDK
•
You can request a signed request on demand, after the app is invoked, by using the SDK.
SEE ALSO:
Verifying and Decoding a Signed Request
Canvas App User Flow—Signed Request
Canvas App User Flow—Signed Request
This diagram shows the user flow for a canvas app that uses signed request authentication.
Signed Request Authentication
29
Force.com Canvas SDK Signed Request Authentication
SEE ALSO:
Verifying and Decoding a Signed Request
Verifying and Decoding a Signed Request
When using a signed request, Salesforce delivers the user context and authentication information to your canvas app URL. To ensure that the signed request is valid, you must verify that the signed request was signed using your specific canvas app consumer secret. If the correct consumer secret was used, then you can trust the context; otherwise, you can assume that the request was not initiated by
Salesforce. To verify and decode the signed request, your application should:
1. Receive the POST message that contains the initial signed request from Salesforce.
2. Split the signed request on the first period. The result is two strings: the hashed Based64 context signed with the consumer secret and the Base64 encoded context itself.
3. Use the HMAC SHA-256 algorithm to hash the Base64 encoded context and sign it using your consumer secret.
30
Force.com Canvas SDK Signed Request Authentication
4. Base64 encode the string created in the previous step.
5. Compare the Base64 encoded string with the hashed Base64 context signed with the consumer secret you received in step 2.
If the two values are the same, then you know that the signed request was signed using your consumer secret and can be trusted. From there, you can Base64 decode the encoded context and parse out any values you need. For more information on those values, see
. If the two strings are different, then the request was not hashed and signed using your consumer secret, and you should return the appropriate message to the user.
Functions for Verifying and Decoding
To verify the signed request, you can call the one the following functions found in the Force.com Canvas SDK (in
SalesforceCanvasFrameworkSDK\src\main\java\canvas\SignedRequest.java
):
•
verifyAndDecode
—Returns a verified and decoded version of the signed request as a Java object.
•
verifyAndDecodeAsJson
—Returns a verified and decoded version of the signed request as a JSON-formatted string.
The following code example shows you how to verify and decode a signed request using the functions in the SDK. This code splits the signed request string at the period to parse out the signed secret and the Base64 JSON string. It then encrypts the canvas app consumer secret signed with the HMAC SHA-256 algorithm and compares the encrypted value with the encrypted value sent to you by Salesforce.
If the two values are the same, you know that the context is valid and came from Salesforce. If the two values are different, then the request didn’t come from Salesforce.
/**
*
* The utility method can be used to validate/verify the signed request.
* In this case, the signed request is verified that it's from Salesforce and that
* it has not been tampered with.
*
* This utility class has two methods. One verifies and decodes the request
* as a Java object, the other as a JSON String.
*
*/ public class SignedRequest { public static CanvasRequest verifyAndDecode(String input, String secret) throws SecurityException {
String[] split = getParts(input);
String encodedSig = split[0];
String encodedEnvelope = split[1];
// Deserialize the JSON body.
String json_envelope = new String( new Base64(true).decode(encodedEnvelope));
ObjectMapper mapper = new ObjectMapper();
ObjectReader reader = mapper.reader(CanvasRequest.
class );
CanvasRequest canvasRequest;
String algorithm; try { canvasRequest = reader.readValue(json_envelope); algorithm = canvasRequest.getAlgorithm() == null ?
"HMACSHA256" : canvasRequest.getAlgorithm();
} catch (IOException e) { throw new SecurityException(String.format( "Error [%s] deserializing JSON to
Object [%s] ", e.getMessage(), CanvasRequest.class.getName()), e);
} verify(secret, algorithm, encodedEnvelope, encodedSig);
31
Force.com Canvas SDK Signed Request Authentication
// If we got this far, then the request was not tampered with.
// Return the request as a Java object.
return canvasRequest;
} public static String verifyAndDecodeAsJson(String input, String secret) throws SecurityException {
String[] split = getParts(input);
String encodedSig = split[0];
String encodedEnvelope = split[1];
String json_envelope = new String( new Base64(true).decode(encodedEnvelope));
ObjectMapper mapper = new ObjectMapper();
String algorithm;
StringWriter writer;
TypeReference<HashMap<String,Object>> typeRef
= new TypeReference<HashMap<String, Object>>() { }; try {
HashMap<String,Object> o = mapper.readValue(json_envelope, typeRef); writer = new StringWriter(); mapper.writeValue(writer, o); algorithm = (String)o.get( "algorithm" );
} catch (IOException e) { throw new SecurityException(String.format( "Error [%s] deserializing
JSON to Object [%s] ", e.getMessage(), typeRef.getClass().getName()), e);
} verify(secret, algorithm, encodedEnvelope, encodedSig);
// If we got this far, then the request was not tampered with.
// Return the request as a JSON string.
return writer.toString();
} private static String[] getParts(String input) { if (input == null || input.indexOf( "." ) <= 0) { throw new SecurityException(String.format( "Input [%s] doesn't look like a signed request ", input));
}
String[] split = input.split( "[.]" , 2); return split;
} private static void verify(String secret, String algorithm,
String encodedEnvelope, String encodedSig ) throws SecurityException
{ if (secret == null || secret.trim().length() == 0) { throw new IllegalArgumentException( "secret is null, did you set your environment variable CANVAS_CONSUMER_SECRET?
");
}
SecretKey hmacKey = null; try { byte [] key = secret.getBytes(); hmacKey = new SecretKeySpec(key, algorithm);
Mac mac = Mac.getInstance(algorithm); mac.init(hmacKey);
32
Force.com Canvas SDK Signed Request Authentication
}
}
// Check to see if the body was tampered with.
byte [] digest = mac.doFinal(encodedEnvelope.getBytes()); byte [] decode_sig = new Base64(true).decode(encodedSig); if (! Arrays.equals(digest, decode_sig)) {
String label = "Warning: Request was tampered with" ; throw new SecurityException(label);
}
} catch (NoSuchAlgorithmException e) { throw new SecurityException(String.format( "Problem with algorithm [%s]
Error [%s] ", algorithm, e.getMessage()), e);
} catch (InvalidKeyException e) { throw new SecurityException(String.format( "Problem with key [%s]
Error [%s] ", hmacKey, e.getMessage()), e);
}
// If we got here and didn't throw a SecurityException then all is good.
Calling the
verifyAndDecode
Function
The following code shows an example of getting the signed request, and then verifying and decoding the request by using the verifyAndDecode
function.
// From a JSP or servlet.
<%@ page import = "canvas.SignedRequest" %>
<%@ page import = "java.util.Map" %>
<%
// Pull the signed request out of the request body and verify/decode it.
Map<String, String[]> parameters = request.getParameterMap();
String[] signedRequest = parameters.get( "signed_request" ); if (signedRequest == null) {%>
This app must be invoked via a signed request!<% return ;
}
String yourConsumerSecret=System.getenv( "CANVAS_CONSUMER_SECRET" );
String signedRequest = SignedRequest.verifyAndDecode(signedRequest[0], yourConsumerSecret);
%>
...
// From JavaScript, you can handle the signed request as needed.
var signedRequest = '<%=signedRequestJson%>' ;
Calling the
verifyAndDecodeAsJson
Function
The following code shows an example of getting the signed request, verifying and decoding the request by using the verifyAndDecodeAsJson
function, and parsing the returned JSON result.
// From a JSP or servlet.
<%@ page import = "canvas.SignedRequest" %>
<%@ page import = "java.util.Map" %>
<%
// Pull the signed request out of the request body and verify/decode it.
Map<String, String[]> parameters = request.getParameterMap();
33
Force.com Canvas SDK Signed Request Authentication
String[] signedRequest = parameters.get( "signed_request" ); if (signedRequest == null) {%>
This App must be invoked via a signed request!<% return ;
}
String yourConsumerSecret=System.getenv( "CANVAS_CONSUMER_SECRET" );
String signedRequestJson = SignedRequest.verifyAndDecodeAsJson(signedRequest[0], yourConsumerSecret);
%>
...
// From JavaScript, you can parse with your favorite JSON library.
var signedRequest = JSON.parse( '<%=signedRequestJson%>' );
SEE ALSO:
Requesting a Signed Request
If your canvas app is set to use signed request for authentication, you can request a signed request on demand by using the SDK. Your app can ask Salesforce to resend the signed request that was used when your app was loaded or to send a new signed request. Requesting a signed request is useful when you are refreshing an expired session or getting authentication information after your app has been redirected.
You can request a signed request on demand by using the refreshSignedRequest()
or repost()
JavaScript methods in the SDK. refreshSignedRequest()
returns a new signed request via a callback, while repost()
asks the parent window to initiate a new POST to your canvas app and reloads the app page with a refreshed signed request.
Use these methods whenever you need to refresh the signed request for your app. Here are some example scenarios where you might need to refresh the signed request information.
•
The OAuth token within a signed request typically expires after two hours. If the OAuth token has expired, and you need to make additional API requests, you can call refreshSignedRequest()
to get a new OAuth token without interrupting the user.
•
Canvas apps might need to use redirects, particularly when trying to provide single sign-on functionality across multiple systems. If your canvas app uses redirects, the redirect URL will not receive the original request body that contains the initial signed request information. You can use the new methods to request the signed request again.
•
In Summer ’14 and later, canvas apps can be user-approved apps. If your user-approved app has not been approved by the user, your app will not get an initial signed request POST. Instead, your app will need to be approved through OAuth, and then you can call repost()
to get the signed request.
Your canvas app must be configured to use signed request for authentication to use these methods. You’ll also need to reference canvas-all.js
in your JavaScript code, as described in Referencing the Force.com Canvas SDK
.
After a request succeeds, your canvas app must verify the returned
information. For more information on verifying signed request information that is received from Salesforce, see
Verifying and Decoding a Signed Request
.
34
Force.com Canvas SDK OAuth Authentication
Using
refreshSignedRequest()
to Obtain a Signed Request
Use refreshSignedRequest()
to request a new signed request via a callback that you provide. In this example, refreshSignedRequest()
is called with a callback that checks the response code and then parses the signed request into the hashed Based64 context that is signed with the consumer secret and the Base64 encoded context itself.
// Gets a signed request on demand.
Sfdc.canvas.client.refreshSignedRequest( function (data) { if (data.status === 200) { var signedRequest = data.payload.response; var part = signedRequest.split( '.' )[1]; var obj = JSON.parse(Sfdc.canvas.decode(part));
}
}
Using
repost()
to Obtain a Signed Request
Use repost()
to instruct the parent window to send a new POST to your canvas app URL. The POSTcontains the signed request that was used when your app was loaded or a new signed request. Unlike refreshSignedRequest()
, using repost()
reloads the canvas app page. The following example calls repost()
, asking for the original signed request.
// Gets a signed request on demand, without refreshing the signed request.
Sfdc.canvas.client.repost();
The following example calls repost()
, asking for a new signed request.
// Gets a signed request on demand, first by refreshing the signed request.
Sfdc.canvas.client.repost({refresh : true});
SEE ALSO:
Verifying and Decoding a Signed Request
OAuth Authentication
Force.com Canvas supports OAuth 2.0 for authorization. When using OAuth, you have two options:
•
Web Server OAuth Authentication Flow—When users run your canvas app, they can authorize the app to access their data. This requires each user to allow the canvas app to access their information. For more information, see Understanding the Web Server
OAuth Authentication Flow in the
Force.com REST API Developer Guide
.
•
User-Agent OAuth Authentication Flow—When users run your canvas app, they can authorize the app to access their data by using just the browser for authentication. Like Web Server OAuth authentication, this option requires each user to allow the canvas app to access their information.
It’s recommended that you use this authorization method during development and not in production because with this type of authorization no server-side code is needed and there’s no need to expose development machines to the Internet. For more information, see Understanding the User-Agent OAuth Authentication Flow in the
Force.com REST API Developer Guide
.
Regardless of which OAuth flow you implement, the canvas app must provide code for initiating the standards-based OAuth flow. OAuth considerations include:
•
Salesforce performs an HTTP GET when invoking the canvas app URL.
35
Force.com Canvas SDK OAuth Authentication
•
With user agent OAuth, all authorization can be performed in the browser (no server-side code is needed).
For more information about OAuth and the Force.com platform, see https://developer.salesforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com
.
If you have an existing connected app that uses OAuth authentication and you want to expose that app as a canvas app, you have two options. First, you can edit the existing app (create a new version) and add the canvas app information to it. This means your app can continue to use the same client ID and consumer secret. The second option is to create a new canvas app. If you do this, you’ll get a new client ID and consumer secret, and you’ll need to update your app with that information.
SEE ALSO:
Canvas App User Flow—OAuth
If your canvas app uses OAuth authentication, the user experience varies depending on where the canvas app is located in the user interface and how the user access is set. This diagram shows the user flow for a canvas app that uses OAuth authentication.
36
Force.com Canvas SDK OAuth Authentication
SEE ALSO:
37
Force.com Canvas SDK OAuth Authentication
Initiating OAuth Flow
The following code examples show you how to start the authorization process in your canvas app using OAuth.
<html>
<head>
<script type= "text/javascript" src= "/sdk/js/canvas-all.js" ></script>
</head>
<body>
<script> function loginHandler(e) { var uri; if (! Sfdc.canvas.oauth.loggedin()) { uri = Sfdc.canvas.oauth.loginUrl();
Sfdc.canvas.oauth.login(
{uri : uri, params: { response_type : "token" , client_id : "3MVG9lKcPoNINVBLigmW.8dAn4L5HwY VBzxbW5FFdzvU0re2 f7o9aHJNUpY9ACdh.3SUgw5rF2nSsC9_cRqzD
", redirect_uri : encodeURIComponent(
"https://demoapp1234.herokuapp.com/sdk/callback.html" )
}});
} else {
Sfdc.canvas.oauth.logout(); login.innerHTML = "Login" ;
Sfdc.canvas.byId( "oauth" ).innerHTML = "" ;
} return false;
}
// Bootstrap the page once the DOM is ready.
Sfdc.canvas(function() {
// On Ready...
var login = Sfdc.canvas.byId( "login" ), loggedIn = Sfdc.canvas.oauth.loggedin(), token = Sfdc.canvas.oauth.token() login.innerHTML = (loggedIn) ?
"Logout" : "Login" ; if (loggedIn) {
// Only displaying part of the OAuth token for better formatting.
Sfdc.canvas.byId( "oauth" ).innerHTML = Sfdc.canvas.oauth.token()
});
</script>
.substring(1,40) + "…" ;
} login.onclick=loginHandler;
<h1 id= "header" >Force.com Canvas OAuth App</h1>
<div> access_token = <span id= "oauth" ></span>
</div>
<div>
<a id= "login" href= "#" >Login</a><br/>
38
Force.com Canvas SDK SAML Single Sign-On for Canvas Apps
</div>
</body>
</html>
SEE ALSO:
SAML Single Sign-On for Canvas Apps
Whether you use signed request or OAuth authorization, you can use SAML-based single sign-on (SSO) to provide your users with a seamless authentication flow. You can leverage Salesforce as an identity provider or as a service provider. SAML SSO enables you to give your users automatic authentication into your canvas app via SAML and authentication into Salesforce via the signed request.
SAML (Security Assertion Markup Language) is an XML-based standard for user authentication on the Web which allows the exchange of authorization data between two domains. With this feature you can create a canvas app that begins a standard SAML authentication flow when opened by a user. After this process completes, the user is authenticated into your Web application.
For canvas apps that use signed request authentication, two methods that are included in the Force.com Canvas SDK enable your canvas app to call into Salesforce to receive a new signed request directly or enable Salesforce to repost the signed request to your Web application endpoint. This results in a complete end-to-end authentication flow.
refreshSignedRequest
Method
Returns a new signed request via a callback. After the SAML SSO process is completed, your app can call this method and receive a new signed request. This method is intended for developers who need to retrieve the signed request by using a more client-side
JavaScript approach. (The Force.com Canvas SDK sends the signed request to your app.)
repost
Method
Requests the parent window to initiate a POST to your canvas app and reloads the app page with a refreshed signed request. After the SAML SSO process is completed, your app can call this method and a new signed request is sent to your app via a POST. This method is for developers who want to retrieve the signed request using a more server-side approach. (Salesforce POSTs the signed request to your server.)
Note: The SAML Initiation Method
Identity Provider Initiated
is not supported for canvas apps on Force.com
communities.
Getting Context in Your Canvas App
When you authenticate your canvas app using signed request, you get the CanvasRequest
object (which contains the Context object) as part of the POST to the canvas app URL. If you’re authenicating using OAuth, or you want to make a call to get context information, you can do so by making a JavaScript call.
The following code sample is an example of a JavaScript call to get context. This code creates a link with the text “Get Context” which then calls the
Sfdc.canvas.client.ctx
function.
<script> function callback(msg) { if (msg.status !== 200) { alert( "Error: " + msg.status); return ;
} alert( "Payload: " , msg.payload);
}
39
Force.com Canvas SDK Cross-Domain XHR var ctxlink = Sfdc.canvas.byId( "ctxlink" ); var client = Sfdc.canvas.oauth.client(); ctxlink.onclick=function() {
Sfdc.canvas.client.ctx(callback, client)};
}
</script>
<a id= "ctxlink" href= "#" >Get Context</a>
SEE ALSO:
Filtering CanvasRequest Context Data
Cross-Domain XHR
Canvas apps are loaded on a Salesforce page in an iFrame. Therefore, the canvas app (in its own domain) can’t make XHR (XML HTTP request) calls back to the *.salesforce.com domain. You can develop and deploy your own proxies as part of the SDK, however, Force.com
Canvas provides a client-side proxy written in JavaScript. This proxy enables client-side XHR calls back to Salesforce.
If you use this proxy from the client to make an XHR request, the API forwards the request to the outer iFrame and the request is submitted on your behalf. When the request is complete, the SDK calls the client’s callback function with the results. Here are some examples of how you can make XHR calls:
•
Getting a List of Chatter Users
•
Note:
The SDK supports cross-domain XHR calls, however, it shouldn’t be used to make same-domain calls.
SEE ALSO:
Getting a List of Chatter Users
The following code example shows a call to return a list of Chatter users.
// Paste the signed request string into a JavaScript object for easy access.
var sr = JSON.parse( '<%=signedRequestJson%>' );
// Reference the Chatter user's URL from Context.Links object.
var chatterUsersUrl = sr.context.links.chatterUsersUrl;
// Make an XHR call back to salesforce through the supplied browser proxy.
Sfdc.canvas.client.ajax(chatterUsersUrl,
{client : sr.client, success : function(data){
// Make sure the status code is OK.
if (data.status === 200) {
40
Force.com Canvas SDK Posting to a Chatter Feed
}});
}
// Alert with how many Chatter users were returned.
alert( "Got back " + data.payload.users.length +
" users" ); // Returned 2 users
SEE ALSO:
Posting to a Chatter Feed
The following code example shows a call to post an item to the context user’s Chatter feed.
var sr = JSON.parse( '<%=signedRequestJson%>' );
// Reference the Chatter user's URL from Context.Links object.
var url = sr.context.links.chatterFeedsUrl+ "/news/" +sr.context.user.userId+ "/feed-items" ; var body = {body : {messageSegments : [{type: "Text" , text: "Some Chatter Post" }]}};
Sfdc.canvas.client.ajax(url,
{client : sr.client, method: 'POST' , contentType: "application/json" , data: JSON.stringify(body), success : function(data) { if (201 === data.status) { alert( "Success" );
}
}
});
SEE ALSO:
Resizing a Canvas App
Force.com Canvas provides methods for resizing a canvas app. Full reference documentation for these methods can be found in the
SDK and here .
•
autogrow
—Starts or stops a timer that checks the content size of the canvas iFrame and adjusts the frame. See
•
resize
—Informs the parent window to resize the canvas iFrame. See Explicitly Resizing a Canvas App .
•
size
—Returns the current size of the canvas iFrame. See
Getting the Size of a Canvas App
.
41
Force.com Canvas SDK Automatically Resizing a Canvas App
•
subscribe
—Subscribes to parent events. Currently, canvas.scroll
(of the parent) is the only supported parent event in the canvas
namespace. See
Subscribing to Parent Events .
Attention: For resize functions to work with your canvas app, you must declare a DOCTYPE at the top of any HTML pages that are associated with the app. For example:
<!DOCTYPE html>
.
SEE ALSO:
Automatically Resizing a Canvas App
The following code examples show how to call the autogrow
method to resize a canvas app. Use this method when your content will change size, but you’re not sure when.
Note: In Mozilla
®
Firefox
®
and Microsoft
®
Internet Explorer
®
, the autogrow
method might not resize the frame if the content size is reduced. In this case, you can use the resize
method to specify the exact size that you want to change the frame to.
// Turn on auto grow with default settings.
Sfdc.canvas(function() { sr = JSON.parse( '<%=signedRequestJson%>' );
Sfdc.canvas.client.autogrow(sr.client);
});
// Turn on auto grow with polling interval of 100ms (milliseconds).
Sfdc.canvas(function() { sr = JSON.parse( '<%=signedRequestJson%>' );
Sfdc.canvas.client.autogrow(sr.client, true, 100);
});
// Turn off auto grow.
Sfdc.canvas(function() { sr = JSON.parse( '<%=signedRequestJson%>' );
Sfdc.canvas.client.autogrow(sr.client, false);
});
SEE ALSO:
Explicitly Resizing a Canvas App
Explicitly Resizing a Canvas App
The following code example shows how to call the resize
method to resize a canvas app. If you don’t specify the height and width parameters, the parent window attempts to determine the height of the canvas app based on its content and then set the iFrame width and height accordingly.
// Automatically determine the size.
Sfdc.canvas(function() { sr = JSON.parse( '<%=signedRequestJson%>' );
Sfdc.canvas.client.resize(sr.client);
42
Force.com Canvas SDK Getting the Size of a Canvas App
});
// Set the height and width explicitly.
Sfdc.canvas(function() { sr = JSON.parse( '<%=signedRequestJson%>' );
Sfdc.canvas.client.resize(sr.client, {height : "1000px" , width : "900px" });
});
// Set only the height.
Sfdc.canvas(function() { sr = JSON.parse( '<%=signedRequestJson%>' );
Sfdc.canvas.client.resize(sr.client, {height : "1000px" });
});
SEE ALSO:
Automatically Resizing a Canvas App
Getting the Size of a Canvas App
Getting the Size of a Canvas App
The following code example shows how to call the size
method to get the size of the canvas app. The console.log
function outputs the frame sizes so you can see the sizes change as you resize the canvas app.
// Get the canvas app sizes in the sizes object.
var sizes = Sfdc.canvas.client.size(); console.log( "contentHeight; " + sizes.heights.contentHeight); console.log( "pageHeight; " + sizes.heights.pageHeight); console.log( "scrollTop; " + sizes.heights.scrollTop); console.log( "contentWidth; " + sizes.widths.contentWidth); console.log( "pageWidth; " + sizes.widths.pageWidth); console.log( "scrollLeft; " + sizes.widths.scrollLeft);
// Resize the canvas app.
Sfdc.canvas(function() { sr = JSON.parse( '<%=signedRequestJson%>' );
Sfdc.canvas.client.autogrow(sr.client);
});
SEE ALSO:
43
Force.com Canvas SDK Subscribing to Parent Events
Subscribing to Parent Events
The following code example shows how to call the subscribe
method so that a canvas app can subscribe to parent events. This example handles the onscroll
event that fires when the user scrolls in the parent window.
//Subscribe to the parent window onscroll event.
Sfdc.canvas(function() { sr = JSON.parse( '<%=signedRequestJson%>' );
// Capture the onScrolling event of the parent window
Sfdc.canvas.client.subscribe(sr.client,
{name : 'canvas.scroll' , onData : function (event) { console.log( "Parent's contentHeight; " + event.heights.contentHeight); console.log( "Parent's pageHeight; " + event.heights.pageHeight); console.log( "Parent's scrollTop; " + event.heights.scrollTop); console.log( "Parent's contentWidth; " + event.widths.contentWidth); console.log( "Parent's pageWidth; " + event.widths.pageWidth); console.log( "Parent's scrollLeft; " + event.widths.scrollLeft);
}}
);
});
SEE ALSO:
Handling Orientation Changes in Your Canvas App
The orientation
event enables you to handle changes in orientation when your canvas app appears on a mobile device. After your canvas app subscribes to the event, the event fires whenever the parent window fires a window.orientation
event. The event returns a payload that contains these values.
Value
clientHeight clientWidth orientation
Description
The height of the app in pixels, specific to the device on which the canvas app renders
The width of the canvas app in pixels, specific to the device on which the canvas app renders
Contains one of these values.
•
0: landscape to portrait
•
90: portrait to landscape
•
-90: portrait to landscape turned counterclockwise
The following code example shows how to subscribe to the orientation
event.
// Capture the orientation event of the parent window.
Sfdc.canvas.client.subscribe(sr.client,
{name : 'canvas.orientation' , onData : function (event) { console.log( "Parent's orientation: " + event.orientation +
44
Force.com Canvas SDK Implementing Canvas App Events
"Canvas app height: " + event.clientHeight +
"Canvas app width: " + event. clientWidth);
}} );
});
Note: The orientation
event isn’t supported on Windows phones.
SEE ALSO:
Implementing Canvas App Events
Events provide a JavaScript-based way to send and receive events between canvas apps. Use events to enable communication between multiple canvas apps on a single page.
One scenario might be a page on which you expose two custom apps as canvas apps: a travel and expense app, and an approvals app.
You can create an event so that when the status of an expense report changes, that event gets raised and contains data (in JSON format) about that expense report. The approvals canvas app subscribes to that event and specifies a function that’s called when the event is raised. When the status is changed, the approvals app receives the event and the specified function runs.
Force.com Canvas provides methods for implementing custom events in a canvas app. Full reference documentation for these methods can be found in the SDK and here .
•
publish
—Creates a custom event to which other canvas apps or Visualforce pages can subscribe. See
•
subscribe
—Subscribes to a parent event or custom event. This method can be used to subscribe to multiple events. See
Subscribing to a Canvas App Event
.
•
unsubscribe
—Unsubscribe from a parent event or custom event. This method can be used to unsubscribe from multiple events.
See
Unsubscribing from a Canvas App Event .
Note: The subscribe
and unsubscribe
methods can also be used to subscribe to a single Streaming API event.
SEE ALSO:
Canvas App Events Considerations
Using Streaming API in a Canvas App
Canvas App Events Considerations
Keep these considerations in mind when implementing canvas app events:
•
We recommend that you use a namespace when naming events, but it’s not required.
•
The event namespace is different than the organization namespace in Salesforce. However, if you use namespaces, we recommend that you make the event namespace the same as the organization namespace.
•
The namespace must be a string with no periods in it. For example, my.name.space.statusChanged
is invalid. An example of a valid event name with a namespace is mynamespace.statusChanged
.
45
Force.com Canvas SDK Creating a Canvas App Event
•
These names are reserved and can’t be used as a namespace:
–
canvas
–
chatter
–
force
–
publisher
–
salesforce
–
sfdc
•
Events work only between canvas apps on the same page. If you have a canvas app on the Chatter tab, that app can’t subscribe to events published by a canvas app on a Visualforce page.
•
You can subscribe to more than one custom event in a subscribe
call.
•
You can subscribe to only one Streaming API event in a subscribe
call.
•
You can’t subscribe to a custom event and a Streaming API event with the same subscribe
call.
•
If you define multiple events with the same name in an array, only the last event defined is available. In this example, the last event where the Status is Negotiating is the one that’s used.
Sfdc.canvas.client.subscribe(sr.client, [
{ name :"mynamespace.statusChanged", payload : {status : 'Closed'}
},
{ name:"mynamespace.statusChanged", payload : {status : 'Negotiating'}
]);
This is also true for Streaming API events.
SEE ALSO:
Implementing Canvas App Events
Creating a Canvas App Event
The following code example shows how to call the publish
method to create a canvas app event. If you’re using a namespace, the event name must be prefaced by the namespace. For example, namespace.eventName
.
Sfdc.canvas(function() { sr = JSON.parse( '<%=signedRequestJson%>' );
Sfdc.canvas.client.publish(sr.client,
{name : "mynamespace.statusChanged" , payload : {status : 'Completed' }});
});
SEE ALSO:
Implementing Canvas App Events
46
Force.com Canvas SDK Subscribing to a Canvas App Event
Subscribing to a Canvas App Event
Subscribing to a Custom Event
The following code example shows how to call the subscribe
method to subscribe to a canvas app event.
// Subscribe to a custom event.
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);
}}
);
});
Subscribing to Multiple Custom Events
The following code example shows how to call the subscribe
method to subscribe to multiple canvas app events. The events you subscribe to can be in different namespaces or might not have a namespace. When a canvas app subscribes to an event, it creates an association between an event (in the other canvas app) and a function (in the subscribing canvas app).
// Subscribe to multiple events.
Sfdc.canvas(function() { sr = JSON.parse( '<%=signedRequestJson%>' );
Sfdc.canvas.client.subscribe(sr.client, [
{name : 'mynamespace.statusChanged' , onData : handler1},
{name : 'anothernamespace.tripCancelled' , onData : handler2},
]);
});
Using the travel and expense and approval canvas app examples, your approvals canvas app has two functions: handler1
and handler2
. That canvas app then subscribes to two events in the travel and expense canvas app: mynamespace.statusChanged
and mynamespace.tripCancelled
. When the mynamespace.statusChanged
event is received by the approvals app, function handler1
is called. When the anothernamespace.tripCancelled
event is received by the approvals app, function handler2
is called.
SEE ALSO:
Implementing Canvas App Events
Unsubscribing from a Canvas App Event
47
Force.com Canvas SDK Unsubscribing from a Canvas App Event
Unsubscribing from a Canvas App Event
Unsubscribing from a Custom Event
The following code example shows how to call the unsubscribe
method to unsubscribe from a canvas app event.
// Unsubscribe from a custom event.
Sfdc.canvas(function() { sr = JSON.parse( '<%=signedRequestJson%>' );
Sfdc.canvas.client.unsubscribe(sr.client, {name : "mynamespace.statusChanged" });
});
Unsubscribing from Multiple Custom Events
The following code example shows how to call the unsubscribe
method to unsubscribe from multiple canvas app events. The events you subscribe to can be in different namespaces or might not have a namespace.
// Unsubscribe from multiple events.
Sfdc.canvas(function() { sr = JSON.parse( '<%=signedRequestJson%>' );
Sfdc.canvas.client.unsubscribe(sr.client, [ 'mynamespace.statusChanged' ,
"anothernamespace.tripCancelled" ]);
});
SEE ALSO:
Implementing Canvas App Events
Subscribing to a Canvas App Event
Using Streaming API in a Canvas App
Force.com Canvas provides an event and methods that enable canvas apps to listen for Streaming API notifications.
•
sfdc.streamingapi
—JavaScript event that you create and associate with a Streaming API channel defined by a PushTopic.
See
Using the Streaming API Event .
•
subscribe
—Subscribes to the sfdc.streamingapi
event that you define. See
Subscribing to a Streaming API Event
.
•
unsubscribe
—Unsubscribes from the sfdc.streamingapi
event. See Unsubscribing from a Streaming API Event
.
SEE ALSO:
Subscribing to a Streaming API Event
Unsubscribing from a Streaming API Event
Force.com Streaming API Developer's Guide
48
Force.com Canvas SDK Using the Streaming API Event
Using the Streaming API Event
The Force.com Canvas SDK contains an event called sfdc.streamingapi
that lets you define an event in your canvas app and associate that event with a Streaming API channel. You then use the subscribe
method to subscribe to the event and receive
Streaming API notifications.
For example, in Salesforce, you can create a Streaming API channel that receives notifications when an InvoiceStatement is updated and the Status changes to Closed. In your canvas app, you can then create an event associated with that channel and subscribe to it. In
Salesforce, whenever an invoice statement is closed, the activated canvas app receives the notification and can perform an action such as displaying a message to the user.
Here are some considerations when defining the Streaming API event:
•
The event takes a single parameter that contains the PushTopic name.
•
The PushTopic name must be prefaced by “/topic/.”
{name: "sfdc.streamingapi" , params:{topic: "/topic/myPushTopicName" }}
SEE ALSO:
Using Streaming API in a Canvas App
Subscribing to a Streaming API Event
Subscribing to a Streaming API Event
This code example shows how to call the subscribe
method so that a canvas app can subscribe to a Streaming API event. When you subscribe to an event, you call the standard sfdc.canvas.client.subscribe
method that you use to subscribe to a canvas app event. When you call the subscribe
method, you must pass in the client and the Streaming API event. Only canvas apps that are open and subscribed to the event can receive Streaming API notifications.
In this example, the onComplete
method specifies the function that runs after the code successfully subscribes to the event. The onData
method specifies the function that runs when a Streaming API notification is received by the event.
// Subscribe to Streaming API events.
// The PushTopic to subscribe to must be passed in.
// The 'onComplete' method may be defined,
// and will fire when the subscription is complete.
Sfdc.canvas(function() { sr = JSON.parse( '<%=signedRequestJson%>' ); var handler1 = function(){ console.log( "onData done" );}, handler2 = function(){ console.log( "onComplete done" );};
Sfdc.canvas.client.subscribe(sr.client,
{name : 'sfdc.streamingapi' , params:{topic: "/topic/InvoiceStatements" }}, onData : handler1, onComplete : handler2}
);
});
When you call the subscribe
method, a REST call is made to ensure that the canvas app has the OAuth scope needed to connect to the Streaming API. Therefore, each time a canvas app subscribes to a Streaming API event, one API call is used and is counted against the organization’s total API requests limits. The canvas app needs at least the “Access and Manage Your Data (API)” OAuth scope to connect to the Streaming API.
If the call to the subscribe
method is successful, the onComplete
method is called with a payload of
{success:true,handle:handle}
. The handle
is an array that contains the name of the Streaming API channel being
49
Force.com Canvas SDK Unsubscribing from a Streaming API Event subscribed to and the subscriptionId
is an integer that contains a unique ID. For example,
["/topics/InvoiceStatements", subscriptionId]
. If the call to the subscribe
method fails, the onComplete method is called with a payload of
{success:false,errorMessage:msg}
. The msg
is a string that contains the cause of the error.
To receive Streaming API notifications, you must create a channel defined by a PushTopic. For more information, see “Step 2: Create a
PushTopic” in the Streaming API Developer Guide .
SEE ALSO:
Unsubscribing from a Streaming API Event
Unsubscribing from a Streaming API Event
This code example shows how to call the unsubscribe
method so that a canvas app can unsubscribe from a Streaming API event.
//Unsubscribe from Streaming API events.
//The PushTopic to unsubscribe from must be passed in.
Sfdc.canvas(function() { sr = JSON.parse( '<%=signedRequestJson%>' );
Sfdc.canvas.client.unsubscribe(sr.client, {name : 'sfdc.streamingapi' , params:{topic: "/topic/InvoiceStatements" }});
});
SEE ALSO:
Subscribing to a Streaming API Event
Debugging in a Canvas App
You must use Chrome, Firefox, or Safari to follow these steps.
When using the Force.com Canvas SDK, you can enable debug mode to make troubleshooting easier.
1. With your canvas app open in your browser, open the console.
2. Type
Sfdc.canvas.console.enable();
and press return.
3. Refresh your browser.
Use data from this screen to debug canvas-related problems.
Using the
<select>
Tag in a Canvas App
If you use
HTML <select>
tags in your canvas web application and intend to make your canvas app available in the Salesforce app, keep in mind that behavior can be unpredictable on some devices. Consider using a jQuery or CSS alternative to using
<select>
.
50
CHAPTER 5
Canvas Apps and Visualforce Pages
In this chapter ...
•
•
•
•
Visualforce Page and a Canvas App
In addition to standard canvas apps, Force.com Canvas also lets you expose a canvas app on a Visualforce page. This means you can display a canvas app anywhere you can display a Visualforce page.
Developers can use Visualforce pages to:
•
Override standard buttons, such as the New button for accounts, or the Save button for contacts
•
Override tab overview pages, such as the Accounts tab home page
•
Define custom tabs
•
Embed components in detail page layouts
•
Create dashboard components or custom help pages
•
Customize, extend, or integrate the sidebars in the Salesforce Console (custom console components)
To host a canvas app on a Visualforce page, use the
<apex:canvasApp>
component.
Note: The Force.com Canvas framework includes methods that you can use to circumvent the navigational limitations of the iframe that contains a canvas app, without using Visualforce pages.
These methods offer a streamlined alternative for controlling navigation to or from canvas apps
in the Salesforce app. For details, see Salesforce App Navigation Methods for Use with Canvas Apps
on page 75.
SEE ALSO:
Visualforce Page Code Examples
Visualforce Considerations apex:canvasApp Component
51
Canvas Apps and Visualforce Pages Visualforce Page Code Examples
Visualforce Page Code Examples
You can display a canvas app on a Visualforce page in a number of ways. These examples show the different ways to reference the canvas app using applicationName
, developerName
, and namespacePrefix
.
Object Detail Page
The following code snippet is an example of how to display a canvas app on an Account page. The code specifies the size of the canvas app to be 400 pixels high and 750 pixels wide. This examples specifies the canvas app using the applicationName
and namespacePrefix
.
<apex:page standardController= "Account" >
<apex:canvasApp applicationName= "Test Inline Visualforce" namespacePrefix= "testorg" height= "400px" width= "750px" />
</apex:page >
Standard Page
The following code snippet is an example of how to display a canvas app on a Visualforce page. The code specifies the size of the canvas app to be 1,000 pixels high and 800 pixels wide. In addition, the code passes three custom parameters to the canvas app. This examples specifies the canvas app using the developerName
and namespacePrefix
.
<apex:page >
<apex:canvasApp developerName= "Test_Standard_Visualforce" namespacePrefix= "testorg" height= "1000px" width= "800px" parameters= "{p1:'value1',p2:'value2',p3:'value3'}" />
</apex:page >
Standard Page with a Border and Scrolling
The following code snippet is an example of how to display a canvas app with some additional UI enhancements on a Visualforce page.
The code specifies the size of the canvas app to be 100 pixels high and 500 pixels wide. In addition, the code specifies that there should be a border of 2 pixels around the canvas app and that scrolling should be enabled. This examples specifies the canvas app using only the applicationName
(this is only valid in the organization in which the canvas app was created, and if that organization doesn’t have a namespacePrefix
.
<apex:page >
<apex:canvasApp applicationName= "Test Scrolling Visualforce" height= "100px" width= "500px" border= "2" scrolling= "yes" />
52
Canvas Apps and Visualforce Pages Visualforce Considerations
</apex:page >
SEE ALSO:
Canvas Apps and Visualforce Pages
Visualforce Developer's Guide
Visualforce Considerations
Keep the following considerations in mind when using the
<apex:canvasApp>
component:
•
The
<apex:canvasApp>
component is available only in organizations that have Force.com Canvas enabled and in Visualforce pages at version 27.0 or higher.
•
If you include a canvas app on an object detail layout, you must provide the height of the canvas app in the page layout as well as in the
<apex:canvasApp>
component.
•
Location—If the canvas app is in a Visualforce page, then the
Environment.displayLocation
field contains the value
Visualforce
.
SEE ALSO:
Canvas Apps and Visualforce Pages
apex:canvasApp Component
Use this component to display a canvas app on a Visualforce page. The table below lists the component attributes.
Pass parameters that contain non-alphanumeric characters such as quotation marks, apostrophes, and so on, as JavaScript-safe objects.
To do this, write an Apex class that uses the methods of the Apex JSONGenerator class to build the JSON string. Call the Apex class from the parameters
value:
<apex:page controller= "JSONGeneratorSample" >
<apex:canvasApp developerName= "mycanvas" parameters= "{!generateJSON}" />
</apex:page>
Alternatively, you can also use the JSENCODE function to escape the strings :
<apex:page standardController= "Account" >
<apex:canvasApp developerName= "mycanvas" parameters= "{!JSENCODE(Account.Description)}"
/>
</apex:page>
Attribute
applicationName
Type
String
Description
Name of the canvas app. Either applicationName
or developerName
is required.
53
Canvas Apps and Visualforce Pages
Attribute
border canvasId containerId
Type
String
String
String developerName entityFields
String
String apex:canvasApp Component
Description
Width of the canvas app border, in pixels. If not specified, defaults to 0 pixels.
Unique ID of the canvas app window. Use this attribute when targeting events to the canvas app.
ID of the HTML element in which the canvas app is rendered. If not specified, defaults to null. The container specified by this attribute can’t appear after the
<apex:canvasApp>
component. These code examples show valid usage of the
<div>
container and the containerId
attribute:
<apex:page>
<div id="container1"></div>
<apex:canvasApp applicationName="myApp" containerId="container1"/>
</apex:page>
<apex:page>
<div id="container1">
<apex:canvasApp applicationName="myApp" containerId="container1"/>
</div>
</apex:page>
This code example shows invalid usage of the
<div>
container and the containerId
attribute:
<apex:page>
<apex:canvasApp applicationName="myApp" containerId="container1"/>
<div id="container1">
</div>
</apex:page>
Internal name of the canvas app. You specify this value in the
API
Name
field when you expose the canvas app by creating a connected app. Either developerName
or applicationName
is required.
Specifies the fields returned in the signed request Record object when the component appears on a Visualforce page placed on an object. If this attribute isn’t specified or is blank, then only the Id field is returned. Valid attribute values include:
•
Comma-separated list of field names. For example, to return the
Account Phone and Fax fields, the attribute would look like: entityFields="Phone,Fax"
•
Asterisk “*” to return all fields from the associated object.
54
Canvas Apps and Visualforce Pages
Attribute
height id maxHeight maxWidth namespacePrefix
Type
String
String
String
String
String onCanvasAppError onCanvasAppLoad parameters
String
String
String rendered scrolling
Boolean
String apex:canvasApp Component
Description
Canvas app window height, in pixels. If not specified, defaults to 900 pixels.
Unique identifier that allows the
<apex:canvasApp> component to be referenced by other components on the page.
The maximum height of the Canvas app window in pixels. Defaults to 2000 px; 'infinite' is also a valid value.
The maximum width of the Canvas app window in pixels. Defaults to 1000 px; 'infinite' is also a valid value.
Namespace value of the Developer Edition organization in which the canvas app was created. You can set a namespace only in a
Developer Edition organization, so this is optional if the canvas app was created in a different type of organization. If not specified, defaults to null.
Name of the JavaScript function to be called if the canvas app fails to render.
Name of the JavaScript function to be called after the canvas app loads.
Object representation of parameters passed to the canvas app.
Supply in JSON format or as a JavaScript object literal. Here’s an example of parameters in a JavaScript object literal:
{param1: 'value1' ,param2: 'value2' }
. If not specified, defaults to null.
Specifies whether the component is rendered on the page. If not specified, defaults to true.
Specifies whether the canvas app window uses scroll bars. Valid values are:
•
auto
•
no
•
yes
If not specified, defaults to no
. If this attribute contains an invalid value, it’s treated the same as no
to prevent browser errors.
Canvas app window width, in pixels. If not specified, defaults to 800 pixels.
width
String
SEE ALSO:
Canvas Apps and Visualforce Pages
Visualforce Developer's Guide
Visualforce Page Code Examples
Returning Fields in the Record Object
55
Canvas Apps and Visualforce Pages Returning Fields in the Record Object
Returning Fields in the Record Object
When you use the
<apex:canvasApp>
component to display a canvas app on a Visualforce page, and that page is associated with an object (placed on the page layout, for example), you can specify fields to be returned from the related object. To do this, use the entityFields
attribute. You can use this attribute in one of the following ways.
Return Specific Object Fields
You can return specific object fields in the Record object by setting the entityFields
attribute to a comma-separated list of field names. If there’s an invalid field name in the list, then that field name is ignored and the valid fields are returned in the Record object.
<apex:canvasApp applicationName="MyApp" entityFields="Phone,Fax,BillingCity" containerId="canvasAppDiv"/> returns a Record object that looks like this:
"record":{
"attributes":{
"type":"Account",
"url":"/services/data/v41.0/sobjects/Account/001xx000003DGWiAAO"
},
"Id":"001xx000003DGWiAAO",
"Phone":"(555) 555-5555",
"Fax":"(555) 555-5555",
"BillingCity":"Seattle"
}
Return All Object Fields
You can return all object fields in the Record object by setting the entityFields
attribute to the wildcard "*".
<apex:canvasApp applicationName="MyApp" entityFields="*" containerId="canvasAppDiv"/> returns a Record object that looks like this:
"record":{
"attributes":{
"type":"Account",
"url":"/services/data/v41.0/sobjects/Account/001xx000003DGWiAAO"
},
"Id":"001xx000003DGWiAAO",
"IsDeleted":false,
"MasterRecordId":null,
"Name":"Edge Communications",
"Type":"Customer - Channel",
"ParentId":null,
"BillingStreet":"123 Main Street",
"BillingCity":"Seattle",
"BillingState":"WA",
"BillingPostalCode":"98121",
"BillingCountry":"USA",
...
}
56
Canvas Apps and Visualforce Pages Using Events between a Visualforce Page and a Canvas App
Return the Id Field
If the
<apex:canvasApp>
component doesn’t have the entityFields
attribute or if the attribute is blank, then only the Id field is returned in the Record object.
<apex:canvasApp applicationName="MyApp" containerId="canvasAppDiv"/> returns a Record object that looks like this:
"record":{
"attributes":{
},
"Id":"001xx000003DGWiAAO"
}
"type":"Account",
"url":"/services/data/v41.0/sobjects/Account/001xx000003DGWiAAO"
SEE ALSO:
Controlling Canvas App Behavior
Using Events between a Visualforce Page and a Canvas App
Force.com Canvas provides methods that you can use to publish and subscribe to events between your canvas app and the parent
Visualforce page. This process includes publishing events from your Visualforce page, listening for events on your Visualforce page, unsubscribing from events on your Visualforce page, and resizing the Visualforce page that contains the canvas app. This process for resizing a canvas app differs from the process where the canvas app resizes itself, which is described in
. Full reference documentation for these methods can be found in the SDK and here .
•
publish
•
resize
•
subscribe
—Used by a Visualforce page to subscribe to events that the canvas app might publish. See
.
•
unsubscribe
—Used by a Visualforce page to unsubscribe to parent events that the canvas app might publish. See
Unsubscribing from Events in a Visualforce Page .
The
object is needed for the Visualforce page to use these methods. Your script in the Visualforce page might look something like this:
<script type= "text/javascript" src= " https://
yourDomain
.my.salesforce.com/canvas/sdk/js/30.0/controller.js
">
Note:
You can use Force.com methods to smoothly integrate navigation between a canvas app and the Salesforce app, without using Visualforce. The methods are events that reside in the JavaScript library within the Force.com Canvas framework. When you call one of the navigation methods from your canvas code, you send an event into Salesforce that reads the payload and directs
57
Canvas Apps and Visualforce Pages Publishing a Canvas Event from a Visualforce Page the user to the specified destination. For more information, see
Salesforce App Navigation Methods for Use with Canvas Apps
on page 75.
SEE ALSO:
Publishing a Canvas Event from a Visualforce Page
Resizing a Canvas App in a Visualforce Page
Unsubscribing from Events in a Visualforce Page
Publishing a Canvas Event from a Visualforce Page
The following code example shows how to call the publish
method to publish the myevent
event from a Visualforce page. Any canvas app that subscribes to this event will receive the event.
// Target all canvas apps.
Sfdc.canvas.controller.publish({name : 'mynamespace.myevent' , payload : {}});
The following code example shows how to call the publish
method to publish an event to a specified canvas app from the Visualforce page.
If an event is published to specific canvas apps, even if other canvas apps on a Visualforce page are subscribed to it, only the canvas apps specified will receive that event. Using this code example, if the Visualforce page contained canvas apps app1, app2, and app3, and they all subscribed to myevent
, only app1 would receive the event.
// Target a specific canvas app
// where "app1" is the canvasId specified in the canvas component.
// For example: <apex:canvasApp canvasId="app1">
Sfdc.canvas.controller.publish({name : 'mynamespace.myevent' , payload : {}, target : {canvas : 'app1' }});
In the target
parameter, you can specify multiple canvas apps by passing in an array of canvas apps: target : [{canvas :
'app1'}, {canvas: 'app2'}]
.
SEE ALSO:
Using Events between a Visualforce Page and a Canvas App
Resizing a Canvas App in a Visualforce Page
Unsubscribing from Events in a Visualforce Page
58
Canvas Apps and Visualforce Pages Resizing a Canvas App in a Visualforce Page
Resizing a Canvas App in a Visualforce Page
The following code example shows how to call the resize
method to explicitly set the height and width on a specific canvas app within a Visualforce page.
// Set the height and width explicitly and target a canvas app
// Where 'mycanvas0' is the canvasId on the canvas component
// <apex:canvasApp canvasId="mycanvas0"/> var target = {canvas : "mycanvas0" };
Sfdc.canvas.controller.resize( {height : "1000px" , width : "900px" }, target);
The following code example shows how to call the resize
method to set the height on all canvas apps within a Visualforce page.
//Set only the height on all canvas apps
Sfdc.canvas.controller.resize( {height : "1000px" });
SEE ALSO:
Using Events between a Visualforce Page and a Canvas App
Publishing a Canvas Event from a Visualforce Page
Unsubscribing from Events in a Visualforce Page
Subscribing to Events
The following code example shows how to call the subscribe
method within a Visualforce page to subscribe to specified events published from a canvas app.
// Subscribe to a single event.
Sfdc.canvas.controller.subscribe({name : 'mynamespace.myevent0' , onData : function (e) {}});
// Subscribe to multiple events in a single call.
Sfdc.canvas.controller.subscribe([
{name : 'mynamespace.myevent1' , onData : function(e) {}},
{name : 'mynamespace.myevent2' , onData : function(e) {}}
]);
SEE ALSO:
Using Events between a Visualforce Page and a Canvas App
Publishing a Canvas Event from a Visualforce Page
Resizing a Canvas App in a Visualforce Page
Unsubscribing from Events in a Visualforce Page
Implementing Canvas App Events
59
Canvas Apps and Visualforce Pages Unsubscribing from Events in a Visualforce Page
Unsubscribing from Events in a Visualforce Page
The following code example shows how to call the unsubscribe
method within a Visualforce page to unsubscribe from two events.
Sfdc.canvas.controller.unsubscribe([ 'mynamespace.myevent2' , 'mynamespace.myevent2' ]);
SEE ALSO:
Using Events between a Visualforce Page and a Canvas App
Publishing a Canvas Event from a Visualforce Page
Resizing a Canvas App in a Visualforce Page
60
CHAPTER 6
Canvas Apps in a Page Layout or a Mobile Card
In this chapter ...
•
•
Add a Canvas App to a Page Layout
You can add a canvas app to a page layout for any standard or custom object. For the Canvas Apps category to appear in the palette when you edit a page layout, you must set the canvas app location to
Layouts and Mobile Cards when you create the canvas app in the Salesforce application.
SEE ALSO:
Add a Canvas App to a Page Layout
Where Canvas Apps Appear in a Page Layout
61
Canvas Apps in a Page Layout or a Mobile Card Where Canvas Apps Appear in a Page Layout
Where Canvas Apps Appear in a Page Layout
Depending on where you place the canvas app on the page layout, the canvas app might appear in the full Salesforce site or in the
Salesforce app.
This table describes where the canvas app appears when you add it to the page layout.
If the canvas app is added to the page layout in ...
Any section (other than the
Mobile Cards section)
Mobile Cards section
The canvas app appears in the full
Salesforce site?
Yes
No
The canvas app appears in the
Salesforce app?
Yes
Yes
Where the canvas app appears in the
Salesforce app
Record detail page
Mobile card
SEE ALSO:
Canvas Apps in a Page Layout or a Mobile Card
Add a Canvas App to a Page Layout
Add a Canvas App to a Page Layout
Follow these steps to add a canvas app to the page layout for an Account.
1. Use the Heroku Quick Start to create a canvas app by following the steps in Create the App .
2. In the Salesforce application, from Setup, enter
Apps
in the
Quick Find
box, then select Apps.
3. In the Connected Apps related list, click Edit next to the app that you just created.
4. In the Canvas Apps Settings section, in the
Locations
field, select Layouts and Mobile Cards.
5. Click Save.
6. From the object management settings for accounts, go to Page Layouts.
7. Click Edit next to Account Layout.
You’ll see the Canvas Apps category in the palette and the canvas app, because you set the location of the canvas app to Layouts and Mobile Cards.
8. Drag the canvas app element to where you’d like it to appear in the page layout, and then click Save.
•
If you add the canvas app to any section other than the Mobile Cards section, the canvas app appears in the page layout in the full Salesforce site or in the record detail page in the Salesforce app.
•
If you add the canvas app to the Mobile Cards section, the canvas app appears only in the mobile card.
62
Canvas Apps in a Page Layout or a Mobile Card Add a Canvas App to a Page Layout
9. To see your changes, click the Accounts tab, and then click an account. You’ll see the canvas app on the page layout where you added it.
You can modify additional properties of the canvas app in the page layout by clicking the wrench icon .
•
Width (in pixels or %)
—The width of the canvas app; defaults to 100%. Changes to the width of the canvas app appear in both the full Salesforce site and the Salesforce app. However, canvas apps are displayed in a single-column layout, so we recommend that you leave the width at 100%.
•
Height (in pixels)
—The height of the canvas app; defaults to 200 pixels. Changes to this field appear to the user for canvas apps that appear in both the full Salesforce site and the Salesforce app.
•
Show scrollbars
—Whether scrollbars are displayed on the canvas app iFrame. Changes to this field render for canvas apps that appear in the full Salesforce site but not for canvas apps that appear in the Salesforce app.
•
Show label
—Whether to display the page layout section label. Changes to this field appear to the user for canvas apps that appear in both the full Salesforce site and in the Salesforce app.
SEE ALSO:
Canvas Apps in a Page Layout or a Mobile Card
Where Canvas Apps Appear in a Page Layout
Salesforce Help: Find Object Management Settings
63
CHAPTER 7
Canvas Apps in the Publisher
In this chapter ...
•
Location and Create the Action
•
•
•
•
Force.com Canvas enables you to expose your canvas apps as quick actions. The publisher allows users access to the most common actions in your organization. You can expand the publisher to include a canvas app so that users can leverage the common custom actions of a canvas app. These actions can then integrate with the feed and create a feed post specific to the action that was performed.
Developers can use canvas apps in the publisher to:
•
Add content from a Web application into the Chatter publisher.
•
Create a custom action that exposes a canvas app.
•
Integrate your canvas app directly into the publisher life cycle: post from your canvas app into the
Chatter feed, use the Share button functionality, and designate where to post your message.
For example, you might have a canvas app that your users use to log their hours worked. You can create a quick action that allows a user to open that canvas app in the publisher so they can quickly submit a time record, all right from within the publisher.
Users can still access the canvas app in the standard way for full functionality; but the canvas app in the publisher provides quick access to the most common functions of your app. A user can select the quick action and create a Chatter feed item that can be a text post, a link post, or even a canvas post.
SEE ALSO:
Set Canvas App Location and Create the Action
Canvas Apps in the Chatter Feed
64
Canvas Apps in the Publisher Set Canvas App Location and Create the Action
Set Canvas App Location and Create the Action
To add a canvas app to the publisher or action bar, you must set the location and create the action when you create the canvas app.
1. In Salesforce, from Setup, enter
Apps
in the
Quick Find
box, then select Apps.
2. In the Connected Apps related list, click New. Fill out the basic fields for your canvas app. See
3. In the Canvas App settings, select Force.com Canvas and in the
Locations
field, select Publisher. You must select this location for your canvas app to appear in both the publisher in the full Salesforce site and in the action bar in the Salesforce app.
4. Select the
Create Actions Automatically
field. This creates a quick action for the canvas app.
5. To hide the publisher header, which contains the "What are you working on?" text, select
Hide Publisher Header
. This hides the header in both the full Salesforce site and in the Salesforce app.
6. To hide the publisher Share button from users in both the full Salesforce site and in the Salesforce app, select
Hide Publisher
Share Button
. This checkbox is enabled only if
Hide Publisher Header
has been selected.
For the canvas app to appear as an action, you must add the action to the global publisher layout. See “Customizing Global Publisher
Layouts” in the Salesforce Help.
SEE ALSO:
Create the Action Manually
If you didn’t select the
Create Actions Automatically
field when you created the canvas app, then you’ll need to create the action manually.
1. From Setup, enter
Actions
in the
Quick Find
box, then select Global Actions
2. Click New Action.
3. In the
Action Type
field, select Custom Canvas.
4. In the
Canvas App
field, select the canvas app that you want to appear as an action.
Only canvas apps that have a location of Publisher will appear in this field.
5. In the
Height
field, enter the height of the canvas app in pixels.
This is the initial height of the canvas app when it appears in the publisher. You can use the Force.com Canvas SDK resize() method to change the height up to a maximum of 500 pixels.
6. In the
Label
field, enter a value.
This value appears as the quick action title in the user interface.
7. In the
Name
field, enter a unique value with no spaces.
8. Optionally, in the
Icon
field, you can upload an icon by clicking Change Icon. You must upload the icon as a static resource before you can change it here.
9. Click Save.
65
Canvas Apps in the Publisher Force.com Canvas SDK Publisher Events
For the canvas app to appear as a quick action, you must add the action to the global layout. See “Customizing Global Publisher Layouts” in the Salesforce Help.
SEE ALSO:
Set Canvas App Location and Create the Action
Publisher Context Considerations
Force.com Canvas SDK Publisher Events
When you expose a canvas app in the publisher, you can use well-defined events to enable communication between the canvas app and the publisher.
Your canvas app can subscribe and publish these events to more tightly integrate with the publisher framework. For example, you can activate the standard Chatter
Share
button to post a Chatter feed item. You can also access the post text that the user enters in the
What are you working on?
field in the publisher and combine that with content from your app.
Field
publisher.clearPanelState
publisher.failure
publisher.getPayload
publisher.setupPanel
publisher.setPayload
Description
Fired by the publisher when the canvas app is deactivated or hidden. This can happen when the user selects a different application in the publisher or after the Share button has been clicked. A Visualforce page can also listen for this event.
Fired by the publisher when an error condition is encountered such as when invalid data has been submitted. For example:
•
The text in the feed is too long
•
The canvas app you’re attempting to publish to the feed doesn’t exist
•
The canvas app URL is invalid
The canvas app should listen for this event and alert the user that an error occurred and the post didn’t get created.
Fired by the publisher when the Share button is clicked. The payload contains information such as the text entered into the
What are you working on?
field and who the feed item is being shared with.
Fired by the publisher when the Chatter feed page is initially loaded.
Fired by the canvas app to indicate to the publisher that the content being sent to the publisher should be shared in the feed item. This event is in response to publisher.getPayload
and contains information about the feed item you’re trying to create. You can create three feed item types:
•
TextPost
•
LinkPost
•
CanvasPost
66
Canvas Apps in the Publisher Publisher Context Considerations
Field
publisher.setValidForSubmit
publisher.showPanel
publisher.success
Description
Fired by the canvas app to indicate to the publisher that the canvas app is ready to submit a payload. After this event fires, the Share button becomes active.
This code snippet enables the Share button:
$$.client.publish(sr.client,
{name : 'publisher.setValidForSubmit', payload : true});
Fired by the publisher when the user selects a canvas app in the publisher.
This event indicates that the canvas app is being displayed. A Visualforce page can also listen for this event.
Fired by the publisher after the Share button is clicked and data is successfully submitted.
Sequence of Publisher Events
Here’s the order of publisher events from the perspective of the canvas app:
1. The canvas app listens for publisher.setupPanel
.
2. The canvas app listens for publisher.showPanel
.
3. The user interacts with the canvas app, for example, clicks a button or enters some text. The canvas app does any validation required and then fires publisher.setValidForSubmit
. As a result, the publisher then enables the Share button.
4. The canvas app listens for publisher.getPayload
.
5. The canvas app fires publisher.setPayload
.
6. The canvas app listens for publisher.success
.
7. The canvas app listens for publisher.failure
.
8. The canvas app listens for publisher.clearPanelState
.
SEE ALSO:
Publisher Context Considerations
Publisher Context Considerations
When you display a canvas app inside the publisher, the context information you receive from the signed request or from a getContext()
call contains information specific to the publisher:
•
Location—If the canvas app is in the publisher, then the
Environment.displayLocation
field contains the value
Publisher
.
•
Size—The
Environment.Dimensions
object contains information about the size of the canvas app.
–
The canvas app height will be the height you specify in the quick action that you created.
67
Canvas Apps in the Publisher Publisher Canvas App Access Considerations
–
If you selected
Create Actions Automatically
when you created the canvas app, the canvas app height defaults to 200 pixels.
–
The canvas app width defaults to 521 pixels, which is the same as the maximum width of a canvas app in the publisher.
–
The maximum height of a canvas app in the publisher is 500 pixels.
–
The maximum width of a canvas app in the publisher is 521 pixels.
–
This code snippet shows the default size values of a canvas app in the publisher:
"dimensions":
{
"width": "521px",
"height": "200px",
"maxHeight": "500px",
"maxWidth": "521px"
}
–
The publisher is a fixed width of 521 pixels. For example, if you resize your canvas app to be 400 pixels, the publisher width remains 521 pixels.
–
You can use the resize()
method in the Force.com Canvas SDK to change the values of your canvas app up to the maxHeight
and maxWidth
.
SEE ALSO:
Publisher Canvas App Access Considerations
Canvas Apps in the Chatter Feed
Publisher Canvas App Access Considerations
When modifying a canvas app that appears in the publisher, keep these considerations in mind:
•
If the canvas app has a quick action associated with it, then you can’t delete the canvas app or remove the Publisher location. You must first delete the quick action.
•
If the user doesn’t have access to the canvas app through profiles or permission sets and they select the app in the publisher, then they’ll receive an error.
•
If the canvas app attempts to perform an action for which the user doesn’t have permissions, then that action will fail and the canvas app will receive an error. For example, if the app tries to create a Merchandise record but the user doesn’t have create permission on Merchandise, then the app will receive an error. The canvas app should then relay the error to the user.
68
CHAPTER 8
Canvas Apps in the Chatter Feed
In this chapter ...
•
•
Force.com Canvas enables you to expose your canvas apps as feed items. The feed gives users information about what’s happening inside of Salesforce and information about records and groups they’re following.
Developers can use canvas apps in the feed to:
•
Post to the Chatter feed from a canvas app in the publisher or through the Chatter API.
•
Display a canvas app inside a Chatter feed item.
When you create a canvas app Chatter feed item, it contains a thumbnail image, a link title, and a description. When the user clicks on the link or the description, the canvas app opens up in the feed. If the user clicks the link again, the content is collapsed, giving users a seamless experience for working in their feed.
For example, you might have a canvas app that allows a user to log their hours worked. You can now programmatically create a feed item that displays a canvas app which shows the user their currently logged hours.
In addition, the feed item could display actions depending on the current user. So the canvas app could then post a feed item to the user’s manager, and the manager could approve or deny the hours logged.
Since the content is served from the canvas app, the developer has full control over the behavior.
SEE ALSO:
Publisher Context Considerations
Chatter Feed Context Considerations
69
Canvas Apps in the Chatter Feed Chatter Feed Context Considerations
Chatter Feed Context Considerations
When you display a canvas app inside of a feed item, the context information you receive from the signed request or from a getContext()
call contains information specific to the feed:
•
Location—If the canvas app is in the feed, then the
Environment.displayLocation
field contains the value
ChatterFeed
.
•
Parameters—When you create a feed item that contains a canvas app, you can specify a JSON string as the parameters value. When the canvas app receives the context, the parameters in the feed item will be contained in the
Environment.Parameters
object.
•
Size—The
Environment.Dimensions
object contains information about the size of the canvas app.
–
The canvas app height defaults to 100 pixels.
–
The canvas app width defaults to 420 pixels, which is the same as the maximum width of a canvas app in the feed.
–
The maximum height of a canvas app in the feed is 400 pixels.
–
The maximum width of a canvas app in the feed is 420 pixels.
–
This code snippet shows the default size values of a canvas app in the feed:
"dimensions":
{
"width": "420px",
"height": "100px",
"maxHeight": "400px",
"maxWidth": "420px"
}
–
The feed is a fixed width of 420 pixels. For example, if you resize your canvas app to be 200 pixels, the feed width remains 420 pixels.
–
You can use the resize()
method in the Force.com Canvas SDK to change the values of your canvas app up to the maxHeight
and maxWidth
.
SEE ALSO:
Canvas Apps in the Chatter Feed
Chatter Feed Canvas App Access Considerations
Chatter Feed Canvas App Access Considerations
When modifying a canvas app that appears in the feed, keep these considerations in mind:
•
If the canvas app is deleted and that app is in feed items, those feed items will remain. If a user accesses one of those feed items, they’ll receive an error that the canvas app doesn’t exist.
•
If you remove a user’s access to a canvas app and that app is in feed items, those feed items will remain. If a user accesses one of those feed items, they’ll receive an error that they don’t have permissions to access the canvas app.
70
Canvas Apps in the Chatter Feed Chatter Feed Canvas App Access Considerations
•
When creating a canvas app feed item either through a publisher action or through the Chatter API, Salesforce checks to see if the canvas app exists and if the user has permissions to it.
–
If the canvas app doesn’t exist, the feed item can’t be created and an error is returned.
–
If the canvas app exists, but the user attempting to create the feed item doesn’t have access to the canvas app, the feed item is created. However, the user won’t be able to view the feed item and an error is returned.
•
If the canvas app attempts to perform an action for which the user doesn’t have permissions, then that action will fail and the canvas app will receive an error. For example, if the app tries to create a Merchandise record but the user doesn’t have create permission on Merchandise, then the app will receive an error. The canvas app should then relay the error to the user.
SEE ALSO:
Chatter Feed Context Considerations
71
CHAPTER 9
Canvas in the Salesforce App
In this chapter ...
•
Location and Add it to the Navigation
•
•
•
•
Navigation Methods for Use with Canvas
Force.com Canvas enables you to expose your canvas apps in the Salesforce app. The Salesforce app is
Salesforce on the go. This enterprise-class mobile app gives you real-time access to the same information that you see in the office, but it’s organized for getting work done when you’re away from your desk.
Just like in the full Salesforce site, users can access publisher and Chatter feed items, including Force.com
Canvas apps.
Developers can use canvas apps in the Salesforce app to:
•
Expose a canvas app as an action. An icon indicates a canvas app. You can use either the default puzzle icon or upload a custom icon for the related action.
•
Post to the feed from a canvas app in Salesforce or through the Chatter API.
•
Display a canvas app inside a feed item from within the Salesforce app. An icon indicates a canvas app. You can use either the default puzzle icon or provide a thumbnail URL in the feed item to display a custom icon.
•
Add a canvas app as an option in the navigation menu. An icon indicates a canvas app. You can use the default puzzle icon or provide a custom icon URL in the connected app settings of your canvas app.
Note: Canvas apps don’t appear in the app navigation menu in Salesforce for Android. To see canvas apps in the navigation menu, log in to Salesforce mobile web.
For example, you might have a canvas app that warehouse employees use to process orders on a mobile device. You can create an action that accesses the app from the icon of the device, allowing employees to pull up a list of customer orders. After an order is processed, the app sets the order status in Salesforce and posts a feed item to the associated customer account.
Users can still access your canvas app from within Salesforce on a desktop machine. The additional functionality for mobile devices that Salesforce offers doesn’t impact or limit existing functionality.
SEE ALSO:
Canvas Apps in the Chatter Feed
Salesforce App Access Considerations
Salesforce App Context Considerations
72
Canvas in the Salesforce App Set Canvas App Location and Add it to the Navigation Menu
Set Canvas App Location and Add it to the Navigation Menu
To add a canvas app to appear in the Salesforce app navigation menu, you must set the location and add it to the mobile navigation.
1. In Salesforce, from Setup, enter
Apps
in the
Quick Find
box, then select Apps.
2. In the Connected Apps related list, click the app you want to make available in the navigation pane and click Edit.
3. In the Canvas App Settings section, select Force.com Canvas.
4. In the
Locations
field, select Mobile Nav and click Add.
5. Click Save.
6. For the canvas app to appear in the navigation menu you must add it to the mobile navigation. From Setup, enter
Navigation
in the
Quick Find
box, then select Salesforce Navigation.
7. From the available menu items, select your app and click Add.
8. Click Save.
Salesforce App Context Considerations
Keep these considerations in mind when you display a canvas app inside of the Salesforce app.
When you display a canvas app inside of the feed or publisher, the canvas context you receive (either from the Signed Request or from the getContext
call) contains information specific to the Salesforce app publisher.
•
You can verify you’re on either the feed or publisher by looking at the displayLocation
value in the environment section.
For publisher, displayLocation
is set to
Publisher
. For the feed, displayLocation
is set to
ChatterFeed
.
•
When creating a Canvas feed item, you can specify a
JSON
string as the parameter’s value. When the context is sent, any value in the parameter’s field on the feed item is sent in the parameters of the environment section of the context.
•
As with any canvas app, the context contains information about the app’s dimensions. Since Salesforce is designed for mobile, the sizes we provide for it are different than the ones we provide for the full Salesforce sites.
•
To create a single-finger touch scrolling experience:
–
Ensure that the outermost div
elements contain the following properties.
•
min-height: 250px;
•
overflow: scroll;
•
width: 100%;
•
-webkit-overflow-scrolling: touch;
•
-webkit-transform: translated(0%,0px,0px);
–
Set the height
attribute to the clientHeight
value delivered in the signed request. For example:
// Where sr is a parsed signed request object.
var h = parseInt(sr.context.environment.dimensions.clientHeight, 10);
Sfdc.canvas.byId('divElementId').style.height = h;
–
The clientHeight
value can be very small, particularly in a phone’s landscape mode, and users might not be able to see any content. Use min-height
set to the desired height in pixels to ensure a good user experience.
73
Canvas in the Salesforce App Salesforce App Access Considerations
–
In the navigation menu, the default puzzle icon size is 60 pixels by 60 pixels.
SEE ALSO:
Salesforce App Access Considerations
Salesforce App Access Considerations
Keep these considerations in mind when modifying a canvas app that appears in the Salesforce app.
By necessity, the Salesforce app layout is different than the full Salesforce site layout that you’re used to. Remember the following when creating a canvas app for use in the Salesforce app.
•
Because canvas apps are designed to display your third-party application inside of Salesforce, the device must have access to your canvas app URL. If your app is only accessible behind a firewall, the mobile device must be behind the firewall, too. If users don’t have access to the canvas URL, they receive an error—possibly a 404 or 500 error.
•
When accessing your canvas app as an action, if the canvas app uses the “What are you working on” header, the header is fixed at the top of the page and your canvas app scroll area falls below the header text box.
•
The canvas app link and description in the feed might display fewer characters than what is displayed in the full Salesforce site.
•
Depending on the device you use, the feed screen can change if the device is rotated. Your canvas app should support rotation if possible. Use the orientation event to handle changes in device orientation.
•
The heights used in the Salesforce app and the full Salesforce site are different. Use the Dimensions object in the signed request to render your actions correctly in the publisher.
•
In the action menu, long action labels might be truncated.
•
The feed layout is different than that of the full Salesforce site. Instead of an app opening in the feed, a page opens that displays the canvas app on the entire screen. To return to the Salesforce app, tap .
•
When you view the action bar or Feed, the default Force.com Canvas puzzle icon displays for canvas apps. You can override this default action icon with an image you provide.
•
When a canvas app appears as an option in the navigation menu, the default Force.com Canvas puzzle icon is used. You can customize the icon in the connected app settings of your canvas app.
•
Canvas apps aren’t available when the user accesses Salesforce offline.
SEE ALSO:
Salesforce App Context Considerations
Handling Orientation Changes in Your Canvas App
74
Canvas in the Salesforce App Salesforce App Custom Icons
Salesforce App Custom Icons
Custom icons help distinguish your app in the Salesforce app. If you don’t customize the icon for your app, you’ll get the default puzzle-piece icon.
You can customize the icon that is used in the Salesforce navigation menu. You set this icon in the Icon URL entry in the Basic Information section of the connected app settings for your canvas app. From Setup, enter
Apps
in the
Quick Find
box, then select Apps and click Edit for your connected app. The icon URL must be a secure HTTPS URL that points to an icon image file. The image file must be in the GIF, JPG, or PNG file format. For the Salesforce navigation menu, the icon cannot be larger than 60 pixels high by 60 pixels wide.
The custom icon that is used in the Salesforce navigation menu is also used in the Chatter tab and the Canvas App Previewer. If your canvas app will be shown in the navigation menu, we recommend that you use a 60x60 pixel size icon and let Salesforce automatically resize the icon to the smaller size that is needed for the Chatter tab and the Canvas App Previewer.
You can also customize the icon that is used in the Salesforce action bar and action menu for a canvas app. The action bar uses the custom icon set for the action that accesses the canvas app, not the custom icon that is associated with the connected app. You set the action icons by uploading a static resource file for your custom icon and then using this static resource as the icon for the global action.
The static resource icon file should be in the PNG format, with a size of 120 pixels high by 120 pixels wide. See “Custom Icon Guidelines and Best Practices” in the
Salesforce App Developer Guide
for more guidelines on custom action icons.
SEE ALSO:
Salesforce App Context Considerations
Salesforce App Navigation Methods for Use with Canvas Apps
The Force.com Canvas framework includes methods that you can use to smoothly integrate navigation between a canvas app and the
Salesforce app, without needing to use Visualforce.
Previously, the only way to circumvent the navigational limitations of the iframe that contains a canvas app was to use Visualforce pages.
These Force.com Canvas methods offer a simpler alternative for controlling navigation to or from canvas apps in the Salesforce app.
For example, your canvas app code can call Salesforce "create record" logic to navigate to the page where the Create Account button resides. Clicking the button triggers a navigation method to go to the record creation page, which is outside of the canvas app.
These methods within the Force.com Canvas framework are events that reside in the JavaScript library. When you call one of the navigation methods from your canvas code, you send an event into Salesforce that reads the payload and directs the user to the specified destination.
Calling the methods from your canvas app is slightly different than calling functions from a Visualforce page, because the methods are proxied to the Salesforce container through the Force.com Canvas cross-domain API.
Reference the navigation method as an event variable, with name and payload. For example: var event = {name:"s1.createRecord", payload: {entityName: "Account", recordTypeId:
"00h300000001234"}};
The following table shows the name, payload, and purpose of the navigation methods in Salesforce.
75
Canvas in the Salesforce App Salesforce App Navigation Methods for Use with Canvas
Apps
Function
back([refresh])
Description
Navigates to the previous state that’s saved in the sforce.one
history. It’s equivalent to clicking a browser’s Back button.
refresh
is optional. By default, the page doesn’t refresh. Pass true
to refresh the page if possible.
navigateToSObject(recordId
[, view])
Navigates to an sObject record, specified by recordId
. This record “home” has several views, which in the Salesforce app are available as slides that the user can swipe between.
view
is optional and defaults to detail
. view
specifies the slide within record home to display initially.
Note: Record IDs corresponding to ContentNote SObjects aren’t supported.
The possible values are as follows.
•
detail
: the record detail slide
•
chatter
: the Chatter slide
•
related
: the view of related slide navigateToURL(url[, isredirect])
Navigates to the specified URL.
Relative and absolute URLs are supported. Relative URLs are relative to the Lightning domain, and retain navigation history. External URLs—that is, URLs that are outside the Lightning domain—open in a separate browser window.
Note: Depending on the user’s device platform, device settings, version of Salesforce, and authentication requirements for the external URL being opened, the separate browser window might require authentication or re-authentication.
Use relative URLs to navigate to different screens within your app. Use external URLs to allow the user to access a different site or app, where they can take actions that don’t need to be preserved in your app. To return to your app, the separate window that’s opened by an external URL must be closed when the user is finished with the other app. The new window has a separate history from your app, and this history is discarded when the window is closed.
This also means that the user can’t click a Back button to go back to your app; the user must close the new window.
mailto:
, tel:
, geo:
, and other URL schemes are supported for launching external apps and attempt to “do the right thing.” However, support varies by mobile platform and device. mailto:
and tel:
are reliable, but we recommend that you test any other URLs on a range of expected devices.
isredirect
is optional and defaults to false
. Set it to true
to indicate that the new
URL should replace the current one in the navigation history.
Note:
URLs corresponding to ContentNote SObjects aren’t supported.
76
Canvas in the Salesforce App Salesforce App Navigation Methods for Use with Canvas
Apps
Function
navigateToFeed(subjectId, type)
Description
Navigates to the feed of the specified type
, scoped to the subjectId
. For some feed type s, the subjectId
is required but ignored. For those feed type s, pass the current user’s ID as the subjectId
.
type
is the feed type. The possible values are as follows.
•
BOOKMARKS
: Contains all feed items saved as bookmarks by the context user. Pass the current user’s ID as the subjectId
.
•
COMPANY
: Contains all feed items except feed items of type
TrackedChange
. To see the feed item, the user must have sharing access to its parent. Pass the current user’s
ID as the subjectId
.
•
FILES
: Contains all feed items that contain files posted by people or groups that the context user follows. Pass the current user’s ID as the subjectId
.
•
GROUPS
: Contains all feed items from all groups the context user either owns or is a member of. Pass the current user’s ID as the subjectId
.
•
NEWS
: Contains all updates for people the context user follows, groups the user is a member of, and files and records the user is following. Also contains all updates for records whose parent is the context user and every feed item and comment that mentions the context user or that mentions a group the context user is a member of.
Pass the current user’s ID as the subjectId
.
•
PEOPLE
: Contains all feed items posted by all people the context user follows. Pass the current user’s ID as the subjectId
.
•
RECORD
: Contains all feed items whose parent is a specified record, which could be a group, user, object, file, or any other standard or custom object. When the record is a group, the feed also contains feed items that mention the group. When the record is a user, the feed contains only feed items on that user. You can get another user’s record feed. Pass the record’s ID as the subjectId
.
•
TO
: Contains all feed items with mentions of the context user, feed items the context user commented on, and feed items created by the context user that are commented on. Pass the current user’s ID as the subjectId
.
•
TOPICS
: Contains all feed items that include the specified topic. Pass the topic’s ID as the subjectId
. This value is supported in Salesforce for mobile web only. Topics aren’t available in Salesforce for iOS or Salesforce for Android.
navigateToFeedItemDetail( feedItemId)
Navigates to the specific feed item, feedItemId
, and any associated comments.
navigateToRelatedList( relatedListId, parentRecordId)
Navigates to a related list for the parentRecordId
. For example, to display a related list for a Warehouse object, the parentRecordId
is
Warehouse__c.Id
.
relatedListId
is the API name or ID of the related list to display.
navigateToList(listViewId
, listViewName, scope)
Navigates to the list view that’s specified by the listViewId
, which is the ID of the list view to be displayed.
listViewName
sets the title for the list view. It doesn’t need to match the actual name that’s saved for the list view. To use the saved name, set listViewName
to null.
Set scope
to the name of the sObject in the view, for example, “Account” or “MyObject__c”.
77
Canvas in the Salesforce App Salesforce App Navigation Methods for Use with Canvas
Apps
Function
createRecord(entityName[, recordTypeId][, defaultFieldValues])
Description
Opens the page to create a record for the specified entityName
, for example, “Account” or “MyObject__c”.
recordTypeId
is optional and specifies the record type for the created object. Calling createRecord
without providing a recordTypeId
may result in an error.
defaultFieldValues
is optional and, if provided, prepopulates fields on a record create panel, including fields not displayed on the panel. Users must have create access to fields with prepopulated values. Errors during saving that are caused by field access limitations don’t display error messages.
editRecord(recordId)
Opens the page to edit the record specified by recordId
.
For information about navigation methods for use with Visualforce, see the Salesforce App Developer’s Guide.
SEE ALSO:
78
CHAPTER 10 Customizing Your App Lifecycle
In this chapter ...
•
•
CanvasLifecycleHandler with Your App
•
•
•
•
•
By providing a custom Apex class, you can control the context information that’s sent to your canvas app and add custom behavior when your app is rendered.
Salesforce provides several Apex interfaces and classes in the Canvas namespace that provide additional control over the canvas app lifecycle. You can use the Canvas namespace and the CanvasLifecycleHandler interface to:
•
Control what sections of the CanvasRequest Context data get sent to your app. You can, for example, require that Salesforce never send the
Organization information in the CanvasRequest data. Excluding
sections of context data improve performance by reducing the amount of data that’s sent in the request and remove the need to process the organization data in your app.
•
Retrieve application context data when the app is rendered and alter the behavior of your app accordingly. You can obtain the application version and, depending on the version, change how the app runs.
•
Modify some of the context data, such as the canvas app URL, custom parameters, or the list of object
fields that are returned in the Record
data when the app is rendered.
•
Present a well-formed error message to the user in the Salesforce UI if something goes wrong.
Salesforce also provides a Test class in the Canvas namespace that you can use to create test context data and verify the behavior of your lifecycle handler without having to run your app.
Reference documentation for the Apex Canvas namespace is provided in the
Force.com Apex Code
Developer’s Guide
.
79
Customizing Your App Lifecycle Creating a CanvasLifecycleHandler
Creating a CanvasLifecycleHandler
You can control your app lifecycle by providing an implementation of the Canvas.CanvasLifecycleHandler Apex interface that Salesforce can use.
The Apex Canvas.CanvasLifecycleHandler interface provides methods and callbacks for customizing app lifecycle behavior. Salesforce will use your implementation at runtime to let you run custom code. Use the following steps to create an implementation of the
Canvas.CanvasLifecycleHandler interface.
1. From Setup, enter
Apex Classes
in the
Quick Find
box, then select Apex Classes.
2. Click New to create a Apex class.
3. Create an Apex class that implements the Canvas.CanvasLifecycleHandler interface. You must implement the excludeContextTypes()
and onRender()
methods. Here’s a template example: public class MyCanvasLifecycleHandler implements Canvas.CanvasLifecycleHandler { public Set<Canvas.ContextTypeEnum> excludeContextTypes(){
Set<Canvas.ContextTypeEnum> excluded = new Set<Canvas.ContextTypeEnum>();
// Code goes here to add items to excluded list
// that should be excluded from Context data return excluded;
} public void onRender(Canvas.RenderContext renderContext) {
// Code goes here to customize behavior when the app is rendered
}
}
4. After you’ve finished adding your code, save the Apex class.
5. Optionally test your implementation by using the Canvas.Test class.
6. To let Salesforce know which implementation to use for your app, associate your Apex class with your app.
SEE ALSO:
Testing Your CanvasLifecycleHandler Implementation
Associating Your CanvasLifecycleHandler with Your App
Associating Your CanvasLifecycleHandler with Your App
After you’ve created an Apex implementation class for CanvasLifecycleHandler, you need to associate it with your canvas app by adding the class name to your canvas app configuration settings.
Use the following steps to associate a Canvas.CanvasLifecycleHandler implementation with your canvas app.
1. From Setup, enter
Apps
in the
Quick Find
box, then select Apps.
2. Under Connected Apps, select the canvas app that you need to modify and click Edit.
80
Customizing Your App Lifecycle Filtering CanvasRequest Context Data
3. On the connected app edit page, under Canvas App Settings, add the Apex CanvasLifecycleHandler class name that you created into the
Lifecycle Class
field.
Filtering CanvasRequest Context Data
To filter out parts of the CanvasRequest Context data that gets sent to your canvas app, you need to provide an implementation of
Canvas.CanvasLifecycleHandler.excludeContextTypes()
.
Salesforce calls your implementation of excludeContextTypes()
to determine what context information is sent to your app.
Your implementation returns a set of context data to exclude or returns null (or an empty set) if you need to receive all context data.
The set consists of values from the Canvas.ContextTypeEnum Apex enum type.
The enum values are used as follows::
•
ORGANIZATION: Exclude context information about the organization in which the canvas app is running.
•
RECORD_DETAIL: Exclude context information about the object record on which the canvas app appears.
•
USER: Exclude context information about the current user.
Here’s an example excludeContextTypes()
implementation that excludes the Organization and User context data: public Set<Canvas.ContextTypeEnum> excludeContextTypes(){
Set<Canvas.ContextTypeEnum> excluded = new Set<Canvas.ContextTypeEnum>();
// Exclude the Organization and User context data excluded.add(Canvas.ContextTypeEnum.ORGANIZATION); excluded.add(Canvas.ContextTypeEnum.USER); return excluded;
}
When your canvas app receives CanvasRequest Context data, the JSON data does not include the “organization” and “user” sections.
Reference documentation for the Apex Canvas.ContextTypeEnum is provided in the
Force.com Apex Code Developer’s Guide
.
Controlling Canvas App Behavior
To modify the default behavior of the signed request, you need to provide an Apex class that implements
Canvas.CanvasLifecycleHandler.onRender()
and associate this class with your canvas app. In your onRender() implementation, you can control app behavior with custom code.
Salesforce calls your implementation of onRender()
just before your app is rendered. Current context information is passed to this method in the Canvas.RenderContext parameter.
In your onRender()
implementation, you can retrieve the following context information.
•
Application context data, such as the canvas app name, URL, version, and namespace.
•
Environment context data, such as the display location and sublocation, object field names, and custom parameters.
You can set the following context information.
•
The portion of the canvas app URL after the app domain.
•
The list of object fields for which Salesforce will return
Record context data if the canvas app appears on an object page. One way a
canvas app can appear on an object page is if the canvas app appears on a Visualforce page through the use of the
<apex:canvasApp >
component and that Visualforce page is associated with an object.
81
Customizing Your App Lifecycle Presenting User Error Messages
•
The custom parameters that are passed to the canvas app.
You can also use Canvas.CanvasRenderException to present an error message to the user in the Salesforce by throwing a
Canvas.CanvasRenderException.
Here’s an example onRender()
implementation that:
•
Checks the app version information and, if the version is unsupported, throws a CanvasRenderException.
•
Overrides the current canvas app URL, appending ‘/alternatePath’ to the domain portion of the original URL.
•
Sets the list of object fields to include Name, BillingAddress, and YearStarted, anticipating that the canvas app will appear on the
Account page.
•
Overrides the set of custom parameters by adding a new ‘newCustomParam’ parameter. Note that the current set of parameters is first retrieved and cached locally. The new parameter is added to the cached list to ensure that you don’t lose the current set of custom parameters when you call setParametersAsJSON()
.
public void onRender(Canvas.RenderContext renderContext) {
// Get the Application and Environment context from the RenderContext
Canvas.ApplicationContext app = renderContext.getApplicationContext();
Canvas.EnvironmentContext env = renderContext.getEnvironmentContext();
// Check the application version
Double currentVersion = Double .valueOf(app.getVersion()); if (currentVersion <= 5){
// Versions lower than 5 are no longer supported in this example throw new Canvas.CanvasRenderException( 'Error: Versions earlier than 5 are no longer supported.' );
}
// Override app URL, replacing portion after domain with '/alternatePath' app.setCanvasUrlPath( '/alternatePath' );
// Add Name, BillingAddress and YearStarted to fields
// (assumes we'll run from a component on the Account detail page)
Set< String > fields = new Set< String >{ 'Name' , 'BillingAddress' , 'YearStarted' }; env.addEntityFields(fields);
// Add a new custom param to the set of custom params
// First, get the current custom params
Map< String , Object > previousParams =
(Map< String , Object >) JSON.deserializeUntyped(env.getParametersAsJSON());
// Add a 'newCustomParam' to our Map previousParams.put( 'newCustomParam' , 'newValue' );
// Now, replace the parameters env.setParametersAsJSON(JSON.serialize(previousParams));
}
Presenting User Error Messages
You can use Canvas.CanvasRenderException to display error messages to the user.
If you throw a CanvasRenderException from your onRender()
implementation, the error message in that exception will be displayed to the user in the Salesforce UI. This exception will be managed only within the onRender()
method.
82
Customizing Your App Lifecycle Testing Your CanvasLifecycleHandler Implementation
CanvasRenderException supports all the standard Apex exception class methods and constructors. See ”Exception Class and Build-In
Exceptions” in the
Force.com Apex Code Developer’s Guide
for more information on Apex exceptions.
Here’s an example onRender()
implementation that throws a Canvas.CanvasRenderException. Salesforce uses this exception and displays “Error: Could not set URL” as the user error message.
public void onRender(Canvas.RenderContext renderContext) {
// Code omitted that determines if the error condition occured
...
throw new Canvas.CanvasRenderException( 'Error: Could not set URL.' );
}
If the canvas app is run from the Salesforce Chatter tab, the error message resembles:
Testing Your CanvasLifecycleHandler Implementation
You can use the Canvas.Test class to test your
Canvas.CanvasLifecycleHandler.onRender()
implementation without having to run your canvas app.
Use Canvas.Test to create a test Canvas.RenderContext with mock application and environment context data. Call
Canvas.Test.testCanvasLifecycle()
with the mock RenderContext and your CanvasLifecycleHandler implementation to verify that your CanvasLifecycleHandler is being invoked correctly.
Use
Canvas.Test.mockRenderContext()
to create a mock RenderContext. You can provide initial mock application and environment context data or let Canvas.Test use a default set of mock data. You provide initial mock application and environment context data in two Maps of key-value pairs. Use the predefined Canvas.Test key name constants as your keys. The following example sets the app name in the application context data and the sublocation in the environment context data.
Map< String , String > appValues = new Map< String , String >(); appValues.put(Canvas.Test.KEY_NAME, 'AppName' );
Map< String , String > envValues = new Map< String , String >(); envValues.put(Canvas.Test.KEY_SUB_LOCATION, 'mobileDevice' );
For the full list of context keys that Canvas.Test provides, see “Test Constants” in the
Force.com Apex Code Developer’s Guide
.
When you’ve got a mock RenderContext, you can call
Canvas.Test.testCanvasLifecycleHandler()
with the
RenderContext and your CanvasLifecycleHandler. This call invokes the handler’s onRender()
method, and passies the mock
RenderContext as context data.
Here’s an example test class that uses Canvas.Test. The test class has three methods.
83
Customizing Your App Lifecycle Distributing Your CanvasLifecycleHandler Class
•
testDefaultMockValues()
invokes MyCanvasLifecycleHandler, using the default Canvas.Test mock context data.
•
testOverriddenAppValues()
invokes MyCanvasLifecycleHandler, using a custom mock RenderContext with mock app
URL and version application context data.
•
testOverriddenEnvironmentValues()
invokes MyCanvasLifecycleHandler, using a custom mock RenderContext with mock display location, location URL, and custom parameter environment context data. The custom parameters are set through the
Canvas.EnvironmentContext interface after the mock RenderContext is created.
@isTest global class MyCanvasLifecycleHandlerTest { static testMethod void testDefaultMockValues(){
// Test handler using the default mock RenderContext Canvas.Test creates
MyCanvasLifecycleHandler handler = new MyCanvasLifecycleHandler();
Canvas.Test.testCanvasLifecycle(handler, null );
} static testMethod void testOverriddenAppValues(){
// Test handler with some mock application context values
Map< String , String > appValues = new Map< String , String >(); appValues.put(Canvas.Test.KEY_CANVAS_URL, 'https://myserver.com:6000/myAppPath' ); appValues.put(Canvas.Test.KEY_VERSION, '3.0' );
Canvas.RenderContext mock = Canvas.Test.mockRenderContext(appValues, null );
MyCanvasLifecycleHandler handler = new MyCanvasLifecycleHandler();
Canvas.Test.testCanvasLifecycle(handler,mock);
} static testMethod void testOverriddenEnvironmentValues(){
// Test handler with some mock environment context values
Map< String , String > envValues = new Map< String , String >(); envValues.put(Canvas.Test.KEY_DISPLAY_LOCATION, 'Chatter' ); envValues.put(Canvas.Test.KEY_LOCATION_URL,
'https://myinstance.salesforce.com/_ui/core/chatter/ui/ChatterPage' );
MyCanvasLifecycleHandler handler = new MyCanvasLifecycleHandler();
Canvas.RenderContext mock = Canvas.Test.mockRenderContext( null ,envValues);
// Directly update the mock RenderContext and set the custom parameters mock.getEnvironmentContext().setParametersAsJSON(
'{\"one\":1,\"two\":2,\"bool\":true,\"stringVal\":\"some string\"}' );
Canvas.Test.testCanvasLifecycle(handler,mock);
}
}
Distributing Your CanvasLifecycleHandler Class
If you package and distribute your canvas app, make sure to include your CanvasLifecycleHandler class in your package.
Use the following steps to include your CanvasLifecycleHandler implementation in your canvas app package.
1. In Salesforce, from Setup, enter
Packages
in the
Quick Find
box, then select Packages.
2. Find the package for your canvas app, and then click the package name to go to the package detail page.
3. On the package detail page, under Components, click Add.
84
Customizing Your App Lifecycle Distributing Your CanvasLifecycleHandler Class
4. In the Add to Package page, in the
Component Type
field, select Apex Class. A list of available Apex classes is shown.
5. Select the checkbox next to your Apex class for your CanvasLifecycleHandler implementation, and then click Add To Package.
85
REFERENCE
CHAPTER 11 Objects
Force.com Canvas provides an SDK that contains objects that enable communication between your canvas app and Salesforce.
SEE ALSO:
CanvasRequest
When you use a signed request for authentication in your canvas app, you receive a CanvasRequest object in the initial POST message
from Salesforce. This object contains fields related to the request, and also contains the Context
and Client objects. The CanvasRequest
object is returned in JSON format and contains the following fields.
Field
algorithm issuedAt userId
Description
The algorithm used to sign the request.
The timestamp when the oauthToken
was issued.
The context user’s ID.
The following code snippet shows an example of the CanvasRequest object.
{
"context":
{
"application":
{
"applicationId":"06Px000000003ed",
"authType":"SIGNED_REQUEST",
"canvasUrl":"http:// instance .salesforce.com:8080
/canvas_app_path/canvas_app.jsp
",
"developerName":"my_java_app",
"isInstalledPersonalApp": false,
"name":"My Java App",
"namespace":"org_namespace",
"options":[],
"referenceId":"09HD00000000AUM",
"samlInitiationMethod":"None",
"version":"1.0.0"
},
86
Objects CanvasRequest
"user":
{
"accessibilityModeEnabled":false,
"currencyISOCode":"USD",
"email":"[email protected]",
"firstName":"Sean",
"fullName":"Sean Forbes",
"isDefaultNetwork":false,
"language":"en_US",
"lastName":"Forbes",
"locale":"en_US",
"networkId":"0DBxx000000001r",
"profileId":"00ex0000000jzpt",
"profilePhotoUrl":"/profilephoto/005/F",
"profileThumbnailUrl":"/profilephoto/005/T",
"roleId":null,
"siteUrl":"https:// mydomain .force.com/",
"siteUrlPrefix":"/ mycommunity ",
"timeZone":"America/Los_Angeles",
"userId":"005x0000001SyyEAAS",
"userName":"[email protected]",
"userType":"STANDARD"
},
"environment":
{
"parameters":
{
"complex":
{
"key1":"value1",
"key2":"value2"
},
"integer":10,
},
"dimensions":
{
"simple":"This is a simple string.",
"boolean":true
"clientHeight":"50px",
"clientWidth":"70px",
"height":"900px",
"width":"800px",
"maxHeight":"2000px",
"maxWidth":"1000px"
},
"record":
{
"attributes":
{
"type":"Account",
"url":"/services/data/v41.0/sobjects/Account/001xx000003DGWiAAO"
},
"Id":"001xx000003DGWiAAO",
87
Objects
"Phone":"(555) 555-5555",
"Fax":"(555) 555-5555",
"BillingCity":"Seattle"
},
"displayLocation":"Chatter",
"locationUrl":"http://www.salesforce.com/some/path/index.html",
"subLocation":null,
"uiTheme":"Theme3",
"version":
{
"api":"41.0",
"season":"SUMMER"
},
},
"organization":
{
"currencyIsoCode":"USD",
"multicurrencyEnabled":true,
"name":"Edge Communications",
"namespacePrefix":"org_namespace",
"organizationId":"00Dx00000001hxyEAA"
},
"links":
{
"chatterFeedItemsUrl":"/services/data/v41.0/chatter/feed-items",
"chatterFeedsUrl":"/services/data/v41.0/chatter/feeds",
"chatterGroupsUrl":"/services/data/v41.0/chatter/groups",
"chatterUsersUrl":"/services/data/v41.0/chatter/users",
"enterpriseUrl":"/services/Soap/c/41.0/00Dx00000001hxy",
"loginUrl":"http://login.salesforce.com",
"metadataUrl":"/services/Soap/m/41.0/00Dx00000001hxy",
"partnerUrl":"/services/Soap/u/41.0/00Dx00000001hxy",
"queryUrl":"/services/data/v41.0/query/",
"recentItemsUrl":"/services/data/v41.0/recent/",
"restUrl":"/services/data/v41.0/",
}
},
"client":
{
"searchUrl":"/services/data/v41.0/search/",
"sobjectUrl":"/services/data/v41.0/sobjects/",
"userUrl":"/005x0000001SyyEAAS"
"instanceId":"06Px000000002JZ",
"instanceUrl":"http:// instance
.salesforce.com:8080",
"oauthToken":"00Dx0000X00Or4J!ARQAQJ34YL8gKowP65p8FDHkvk.Uq5...",
"refreshToken":"00DD0000000K1NM!ARAAQGJVGOyMjh1jjqvShRpLuAq0...",
"targetOrigin":"http:// instance .salesforce.com:8080"
},
"algorithm":"HMACSHA256",
"userId":"005x0000001SyyEAAS",
CanvasRequest
88
Objects
"issuedAt":null
}
SEE ALSO:
Client
The Client object is a JSON-formatted object returned by the signed request in the
object. It contains context information about the client app.
Field
instanceId instanceUrl oauthToken refreshToken targetOrigin
Description
The ID of a canvas app exposed on a Visualforce page. Used internally for canvas app instance management.
The URL of the Salesforce instance. For example, http://instance.salesforce.com
. Used to preface the URLs
object.
The OAuth access token that’s returned to the caller.
The token that the client uses to authenticate a session. This value is returned only if the canvas app has “Perform requests on your behalf at any time
(refresh_token, offline_access)” as one of the selected OAuth scopes; otherwise null
is returned.
The URL of the canvas app. Used internally for cross-domain communication between the page and the iFrame that contains the canvas app.
The following code snippet shows an example of the Client object.
"client":
{
"instanceId":"06Px000000002JZ",
"instanceUrl":"http:// instance
.salesforce.com:8080",
"oauthToken":"00Dx0000X00Or4J!ARQAQJ34YLUq54RMTrQbxVoWUgorjFi3...",
"refreshToken":"00DD0000000K1NM!ARAAQGJVGOyMjh1jjqvShRpLuAq0ke...",
"targetOrigin":"http:// instance .salesforce.com:8080"
}
SEE ALSO:
Client
89
Objects
Context
When you add your canvas app as a connected app in Salesforce, you can retrieve information about the current environment by using the Context object. The Context object provides information to your app about how and by whom it’s being consumed. You can use this information to make subsequent calls for information and code your app so that it appears completely integrated with the Salesforce user interface. This object is returned in JSON format and contains the following objects:
•
Application —Information about the canvas app, such as version, access method, URL, and so on.
•
Environment —Information about the environment, such as location, UI theme, and so on.
•
—Links, such as the metadata URL, user URL, Chatter groups URL, and so on. You can use these links to make calls into Salesforce from your app.
•
—Information about the organization, such as name, ID, currency code, and so on.
•
—Information about the currently logged-in user, such as locale, name, user ID, email, and so on.
The following code is an example of the Context object. The Context object is returned in the CanvasRequest object when you authenticate using signed request. You can also explicitly make a call to get this object.
"context":{
"application":
{
"applicationId":"06Px000000003ed",
"authType":"SIGNED_REQUEST",
"canvasUrl":"http:// instance .salesforce.com:8080
/canvas_app_path/canvas_app.jsp
",
"developerName":"my_java_app",
"isInstalledPersonalApp": false,
"name":"My Java App",
"namespace":"org_namespace",
"options":[],
"referenceId":"09HD00000000AUM",
"samlInitiationMethod": "None",
"version":"1.0.0"
},
"user":
{
"accessibilityModeEnabled":false,
"currencyISOCode":"USD",
"email":"[email protected]",
"firstName":"Sean",
"fullName":"Sean Forbes",
"isDefaultNetwork":false,
"language":"en_US",
"lastName":"Forbes",
"locale":"en_US",
"networkId":"0DBxx000000001r",
"profileId":"00ex0000000jzpt",
"profilePhotoUrl":"/profilephoto/005/F",
"profileThumbnailUrl":"/profilephoto/005/T",
"roleId":null,
"siteUrl":"https:// mydomain .force.com/",
"siteUrlPrefix":"/ mycommunity
",
"timeZone":"America/Los_Angeles",
"userId":"005x0000001SyyEAAS",
Context
90
Objects
},
"environment":
{
"userName":"[email protected]",
"userType":"STANDARD"
"parameters":{},
"dimensions":
{
"clientHeight": "50px",
"clientWidth": "70px",
"height":"900px",
"width":"800px",
"maxHeight":"2000px",
"maxWidth":"1000px"
},
"record":
{
"attributes":
{
"type":"Account",
"url":"/services/data/v41.0/sobjects/Account/001xx000003DGWiAAO"
},
"Id":"001xx000003DGWiAAO",
"Phone":"(555) 555-5555",
"Fax":"(555) 555-5555",
"BillingCity":"Seattle"
},
"displayLocation":"Chatter",
"locationUrl":"http:// instance .salesforce.com:8080 /canvas_app_path ",
"subLocation":null,
"uiTheme":"Theme3",
"version":
{
"api":"41.0",
"season":"SUMMER"
}
},
"organization":
{
"currencyIsoCode":"USD",
"multicurrencyEnabled":true,
"name":"Edge Communications",
"namespacePrefix":"org_namespace",
"organizationId":"00Dx00000001hxyEAA"
},
"links":
{
"chatterFeedItemsUrl":"/services/data/v41.0/chatter/feed-items",
"chatterFeedsUrl":"/services/data/v41.0/chatter/feeds",
"chatterGroupsUrl":"/services/data/v41.0/chatter/groups",
"chatterUsersUrl":"/services/data/v41.0/chatter/users",
"enterpriseUrl":"/services/Soap/c/41.0/00Dx00000001hxy",
"loginUrl":"http://login.salesforce.com",
91
Context
Objects
"metadataUrl":"/services/Soap/m/41.0/00Dx00000001hxy",
"partnerUrl":"/services/Soap/u/41.0/00Dx00000001hxy",
"queryUrl":"/services/data/v41.0/query/",
"restUrl":"/services/data/v41.0/",
"recentItemsUrl":"/services/data/v41.0/recent/",
"searchUrl":"/services/data/v41.0/search/",
"sobjectUrl":"/services/data/v41.0/sobjects/",
"userUrl":"/005x0000001SyyEAAS"
}
}
You can request Salesforce exclude portions of the context data that you don’t need. To control the amount of data that’s excluded, you must implement your own Canvas.CanvasLifecycleHandler in Apex and provide a list of excluded context sections in your implementation of excludeContextTypes()
.
SEE ALSO:
Getting Context in Your Canvas App
Filtering CanvasRequest Context Data
Application
The Application object is a JSON-formatted object returned by the signed request in the
Context object. The Application object contains
specific canvas app information obtained after you’ve added your app as a connected app in Salesforce from Setup by entering
Connected Apps
in the
Quick Find
box, then selecting Connected Apps.
Field
applicationId authType canvasUrl developerName name namespace options
Description
The ID of the canvas app.
The access method of the canvas app. You specify this value when you expose the canvas app by creating a connected app.
The URL of the canvas app, for example: http://instance.salesforce.com:8080/canvas_app_path/canvas_app.jsp
.
The internal name of the canvas app. You specify this value in the
API Name
field when you expose the canvas app by creating a connected app.
The name of the canvas app.
The Salesforce namespace prefix associated with the canvas app.
An array that can contain one, two, or three of these values:
•
HideHeader
—Hides the publisher header which contains the “What are you working on?” text. This value is only used when the canvas app appears in the publisher.
•
HideShare
—Hides the publisher Share button. This value is only used when the canvas app appears in the publisher.
•
PersonalEnabled
—Enables the canvas app to be installed by users as a canvas personal app.
Context
92
Objects
Field
referenceId version
Description
The unique ID of the canvas app definition. Used internally.
The version of the canvas app. This value changes after you update and re-publish a canvas app in an organization.
The following code snippet shows an example of the Application object.
"application":
{
"applicationId":"06Px000000003ed",
"authType":"SIGNED_REQUEST",
"canvasUrl":"http:// instance
.salesforce.com:8080
/canvas_app_path/canvas_app.jsp
",
"developerName":"my_java_app",
"isInstalledPersonalApp": false,
"name":"My Java App",
"namespace":"org_namespace",
"options":["HideShare", "HideHeader"],
"referenceId":"09HD00000000AUM",
"samlInitiationMethod":"None",
"version":"1.0.0"
}
Context
SEE ALSO:
Environment
The Environment object is a JSON-formatted object containing context information about the canvas app environment. This object contains the
object, the
Version object, and parameters (if there are any) in the
Field
displayLocation
Description
The location in the application where the canvas app is currently being called from. Valid values are:
•
Chatter—The canvas app was called from the Chatter tab.
•
ChatterFeed—The canvas app was called from a Chatter canvas feed item.
•
MobileNav—The canvas app was called from the navigation menu.
•
OpenCTI—The canvas app was called from an Open CTI component.
•
PageLayout—The canvas app was called from an element within a page layout. If the displayLocation is PageLayout, one of the subLocation values might be returned.
•
Publisher—The canvas app was called from a canvas custom quick action.
•
ServiceDesk—The canvas app was called from a Salesforce Console component.
93
Objects
Field
locationUrl subLocation uiTheme
Description
•
Visualforce—The canvas app was called from a Visualforce page.
•
None—The canvas app was called from the Canvas App Previewer.
The URL of the page in Salesforce where the user accesses the canvas app.
For example, if users access your canvas app by clicking a link on the Chatter tab, this field contains the URL of the Chatter tab.
The sublocation in the application where the canvas app was called from when the canvas app is loaded in a mobile device. The subLocation is related to the displayLocation. Valid values for this field when the displayLocation is PageLayout are:
•
S1MobileCardFullview—The canvas app was called from a mobile card.
•
S1MobileCardPreview—The canvas app was called from a mobile card preview. The user must click the preview to open the app.
•
S1RecordHomePreview—The canvas app was called from a record detail page preview. The user must click the preview to open the app.
•
S1RecordHomeFullview—The canvas app was called from a page layout.
The default theme for the context organization.
The following code snippet shows an example of the Environment object.
"environment":
{
"parameters":{},
"dimensions":
{
"clientHeight": "50px",
"clientWidth": "70px",
"height":"900px",
"width":"800px",
"maxHeight":"2000px",
"maxWidth":"1000px"
},
"record": {
"attributes": {
"type": "Account",
"url": "/services/data/v41.0/sobjects/Account/001xx000003DGWiAAO"
},
"Id": "001xx000003DGWiAAO",
"Phone": "(555) 555-5555",
"Fax": "(555) 555-5555",
"BillingCity": "Seattle"
},
"displayLocation":"PageLayout",
"locationUrl":"http://www.salesforce.com/some/path/index.html",
"subLocation":"S1MobileCardFullview",
"uiTheme":"Theme3",
Context
94
Objects
}
"version":
{
"api":"41.0",
"season":"SUMMER"
}
SEE ALSO:
Dimensions
The Dimensions object is a JSON-formatted object containing context information about dimensions of the iFrame on which the canvas app appears.
Field
clientHeight clientWidth height width maxHeight maxWidth
Description
The values of clientHeight
are sent to the canvas app within
SignedRequest and can be used to set the height of the outermost div element. This field is useful for setting the height of an app that’s accessed from a mobile device. The field can be referenced as sr.context.environment.dimensions.clientHeight
, where sr
is the parsed signed request JavaScript object.
The values of clientWidth
are sent to the canvas app within
SignedRequest and can be used to set the width of the outermost div element. This field is useful for setting the width of an app that’s accessed from a mobile device. The field can be referenced as sr.context.environment.dimensions.clientWidth
, where sr
is the parsed signed request JavaScript object.
The height of the iFrame in pixels.
The width of the iFrame in pixels.
The maximum height of the iFrame in pixels. Defaults to 2,000; “infinite” is also a valid value.
The maximum width of the iFrame in pixels. Defaults to 1,000; “infinite” is also a valid value.
The following code snippet shows an example of the Dimensions object.
"dimensions":
{
Context
95
Objects
},
"clientHeight": "50px",
"clientWidth": "70px",
"height": "900px",
"width": "800px",
"maxHeight": "2000px",
"maxWidth": "1000px"
SEE ALSO:
Record
The Record object is a JSON-formatted object that contains information about the object on which the canvas app appears. This could be a standard object like
Account
or a custom object like
Warehouse__c
. If the canvas app doesn’t appear on an object page or in the publisher or feed associated with an object, then the Record object is empty.
This object contains the
object.
Field
Id
Description
The ID of the related object. For example, if the canvas app appears on an
Account page, this field contains the
AccountId
.
If the canvas app appears on a Visualforce page through use of the
<apex:canvasApp>
component, and that Visualforce page is associated with an object (placed on the page layout, for example), you can use the entityFields
attribute on the component to return specific fields or all fields from the related object.
The following code snippet shows an example of the Record object returned from a canvas app that appears on an Account page. In this example, the Phone, Fax, and BillingCity fields were specified in the entityFields
attribute.
"record":{
"attributes":{
"type":"Account",
"url":"/services/data/v41.0/sobjects/Account/001xx000003DGWiAAO"
},
"Id":"001xx000003DGWiAAO",
"Phone":"(555) 555-5555",
"Fax":"(555) 555-5555",
"BillingCity":"Seattle"
}
SEE ALSO:
Returning Fields in the Record Object
Context
96
Objects
Attributes
The Attributes object is a JSON-formatted object that contains information about the object on which the canvas app appears.
Field
type url
Description
The object that the canvas app is associated with. This value could be a standard object like
Account
or a custom object like
Warehouse__c
.
If the canvas app appears in the publisher, then the type is the name of the associated object. For example,
CollaborationGroup
or
Account
.
If the canvas app appears in a user feed or the feed associated with an object, then the type is
FeedItem
.
The URL of the associated object. The format of the URL is the same as the
REST API resource for the given record.
Context
The following code snippet shows an example of the Attributes object.
"record":{
"attributes":{
"type":"Account",
"url":"/services/data/v41.0/sobjects/Account/001xx000003DGWiAAO"
},
"Id":"001xx000003DGWiAAO"
}
SEE ALSO:
Record Object Examples
These code examples demonstrate how the Record object contains different information depending on whether your canvas app appears in the publisher or the feed.
Canvas App in the Publisher
If your canvas app appears in the publisher, the Record object contains different information depending on whether the publisher appears on a user record, a group record, or an object record.
User Record
The Record object
Id
is the
User.Id
and the
Type
is
User
.
"record":{
"attributes":{
},
"Id":"001xx000003DGWiABC"
}
"type":"User",
"url":"/services/data/v41.0/sobjects/User/001xx000003DGWiABC"
97
Objects
Group Record
The Record object
Id
is the
CollaborationGroup.Id
and the
Type
is
CollaborationGroup
.
"record":{
"attributes":{
"type":"CollaborationGroup",
"url":"/services/data/v41.0/sobjects/CollaborationGroup/001xx000003DGWiXYZ"
},
"Id":"001xx000003DGWiXYZ"
}
Object Record
The Record object
Id
is the object
Id
and the
Type
is the object name, for example,
Account
.
"record":{
"attributes":{
"type":"Account",
"url":"/services/data/v41.0/sobjects/Account/001xx000003DGWiAAO"
},
"Id":"001xx000003DGWiAAO"
}
Canvas App in the Feed
If your canvas app appears in the feed, the Record object always contains the feed item information whether the feed is on a user record, a group record, or an object record.
The Record object
Id
is the
FeedItem.Id
and the
Type
is
FeedItem
.
"reoord":{
"attributes":{
"type":"FeedItem",
"url":"/services/data/v41.0/sobjects/FeedItem/001xx000003DGWiAAO"
},
"Id":"001xx000003DGWiAAO"
}
Parameters
The Parameters object is a JSON-formatted object containing context information specified by the developer. The Parameters object is specified in a Visualforce page by using the parameters
tag in the apex:canvasApp
component, or in a Chatter canvas feed item by using the parameters
variable when creating the feed item.
The following code snippet shows an example of the Parameters object.
"parameters":
{
"inventoryStatus":"Picked",
"stockPrice":"12.99",
"count":2,
Context
98
Objects
}
"address":{"street":"1 Market", "city":"San Francisco", "state":"CA"}
SEE ALSO:
Version
The Version object is a JSON-formatted object containing context information about the version of Salesforce running on the server.
Field
api season
Description
The API version of the server.
The season of the release running on the server.
The following code snippet shows an example of the Version object.
"version":
{
"api": "41.0",
"season": "WINTER"
}
SEE ALSO:
Links
The Links object is a JSON-formatted object containing URLs that can be helpful when integrating your canvas app. For example, use the enterpriseUrl
to make calls into Salesforce using the enterprise WSDL.
Note: The links that are listed here are the most commonly used links. They can be helpful when you’re building the REST endpoints for your canvas app. For a complete list of links and related functionality, see the
Force.com REST API Developer’s Guide
and the
Chatter REST API Developer Guide
.
Field
chatterFeedItemsUrl chatterFeedsUrl chatterGroupsUrl chatterUsersUrl
Description
URL to return Chatter feed items for the context organization. This link will still work for integrations created prior to API version 41.0, because the link only points to functionality within API versions 31.0 and earlier.
URL to return Chatter feeds for the context organization. This link will still work for integrations created prior to API version 41.0, because the link only points to functionality within API versions 31.0 and earlier.
URL to return Chatter groups for the context organization.
URL that returns Chatter users for the context organization.
Context
99
Objects
Field
enterpriseUrl loginUrl metadataUrl partnerUrl queryUrl recentItemsUrl restUrl searchUrl sobjectUrl userUrl
Description
URL to make API calls back to Salesforce using the enterprise WSDL.
URL of the login server for the instance the context user is logged into. Used internally.
URL to make calls to the Metadata API.
URL to make API calls back to Salesforce using the partner WSDL.
URL to issue a SOQL query.
URL to access recent items.
URL to return a list of REST API resources.
URL to issue a SOSL search.
URL that retrieves metadata or data from Salesforce objects.
URL for the context user.
The following code snippet shows an example of the Links object.
"links":
{
"chatterFeedItemsUrl":"/services/data/v31.0/chatter/feed-items",
"chatterFeedsUrl":"/services/data/v31.0/chatter/feeds",
"chatterGroupsUrl":"/services/data/v41.0/chatter/groups",
"chatterUsersUrl":"/services/data/v41.0/chatter/users",
"enterpriseUrl":"/services/Soap/c/41.0/00Dx00000001hxy",
"loginUrl":"http://login.salesforce.com",
"metadataUrl":"/services/Soap/m/41.0/00Dx00000001hxy",
"partnerUrl":"/services/Soap/u/41.0/00Dx00000001hxy",
"queryUrl":"/services/data/v41.0/query/",
"recentItemsUrl":"/services/data/v41.0/recent/",
"restUrl":"/services/data/v41.0/",
"searchUrl":"/services/data/v41.0/search/",
"sobjectUrl":"/services/data/v41.0/sobjects/",
"userUrl":"/005x0000001SyyEAAS"
}
Available Links and OAuth Scopes
Links that the canvas app can use depend on what OAuth scopes are selected when you create the connected app.
Scope
Access your basic information
Description
•
userUrl
•
loginUrl
Access and manage your data
•
enterpriseUrl
Context
100
Objects
Scope
Access and manage your Chatter data
Full access
Description
•
metadataUrl
•
partnerUrl
•
queryUrl
•
recentItemsUrl
•
restUrl
•
searchUrl
•
sobjectUrl
•
chatterFeedItemsUrl
•
chatterFeedsUrl
•
chatterGroupsUrl
•
chatterUsersUrl
All links
SEE ALSO:
Organization
The Organization object is a JSON-formatted object containing context information about the organization in which the canvas app is running.
Field
currencyIsoCode multicurrencyEnabled namespacePrefix name organizationId
Description
If multi-currency is enabled for the context organization, then the context user’s currency is returned. Defaults to the corporate currency if not set. If multi-currency is disabled for the context organization, the currency for the corporate currency locale is returned.
Indicates whether the context organization uses multiple currencies ( true
) or does not ( false
).
The Salesforce namespace prefix associated with the canvas app.
The name of the context organization.
The ID of the context organization.
The following code snippet shows an example of the Organization object.
"organization":
{
"currencyIsoCode":"USD",
"multicurrencyEnabled":true,
Context
101
Objects
"name":"Edge Communications",
"namespacePrefix":"org_namespace",
"organizationId":"00Dx00000001hxyEAA"
}
SEE ALSO:
User
The User object is a JSON-formatted object containing context information about the current user. This information can be used within the canvas app (for example, to display the user’s name) or to make subsequent calls to retrieve additional information (for example, to get role information for the current user).
Field
accessibilityModeEnabled currencyISOCode email firstName fullName isDefaultNetwork language lastName locale networkId profileId profilePhotoUrl
Description
For the context user, indicates whether user interface modifications for the visually impaired are on ( true
) or off ( false
).
Returns the context user's default currency code for multiple currency organizations or the organization's currency code for single currency organizations.
The context user’s email address.
The context user's first name.
The context user's full name. The format is: Firstname Lastname.
For the context user, indicates whether the user is in a community ( true
) or not ( false
).
The context user’s language. String is 2-5 characters long. The first two characters are always an ISO language code, for example “fr” or “en.” If the value is further qualified by country, then the string also has an underscore
(_) and another ISO country code, for example “US” or “UK.” For example, the string for the United States is “en_US,” and the string for French Canadian is “fr_CA.”
The context user's last name.
The context user’s locale.
The ID of the context user’s currently logged-in community.
The ID of the profile associated with the role currently assigned to the context user.
The URL for the photo of the context user’s profile photo if Chatter is enabled.
The URL is updated every time a photo is uploaded and reflects the most recent photo. URL returned for an older photo is not guaranteed to return a
Context
102
Objects
Field
profileThumbnailUrl roleId siteUrl siteUrlPrefix timeZone userId userName userType
The following code snippet shows an example of the User object.
"user":
{
"accessibilityModeEnabled":false,
"currencyISOCode":"USD",
"email":"[email protected]",
"firstName":"Sean",
"fullName":"Sean Forbes",
"isDefaultNetwork":false,
"language":"en_US",
"lastName":"Forbes",
"locale":"en_US",
"networkId":"0DBxx000000001r",
"profileId":"00ex0000000jzpt",
"profilePhotoUrl":"/profilephoto/005/F",
"profileThumbnailUrl":"/profilephoto/005/T",
"roleId":null,
"siteUrl":"https:// mydomain
.force.com/",
"siteUrlPrefix":"/ mycommunity ",
"timeZone":"America/Los_Angeles",
"userId":"005x0000001SyyEAAS",
"userName":"[email protected]",
"userType":"STANDARD"
}
SEE ALSO:
103
Description
photo if a newer photo has been uploaded. Always query this field for the
URL of the most recent photo.
The URL for a thumbnail of the context user’s profile photo if Chatter is enabled. The URL is updated every time a photo is uploaded and reflects the most recent photo. URL returned for an older photo is not guaranteed to return a photo if a newer photo has been uploaded. Always query this field for the URL of the most recent photo.
The ID of the context user’s currently assigned role.
The URL of the context user’s currently logged-in community.
The URL prefix of the context user’s currently logged-in community.
The context user’s time zone.
The context user’s ID.
The context user’s login name.
The type of user license assigned to the profile associated with the context user.
Context
Objects Controller
Controller
If your Visualforce page contains a canvas app, you can use methods in the Controller object to publish an event that the canvas app subscribes to. It contains these methods:
Method
publish resize subscribe unsubscribe
Signature
publish(String name, Object payload [, String[] target]) resize(String height, String width, String target)
Description
Used to publish an event that the canvas app subscribes to. The target
parameter is optional. It can contain a single canvas app name or an array of canvas app names.
Used by a Visualforce page to resize a canvas app iFrame.
subscribe(Subscriber event)
Used by a Visualforce page to subscribe to events that the canvas app might publish.
unsubscribe(Unsubscriber event)
Used by a Visualforce page to unsubscribe to parent events that the canvas app might publish.
SEE ALSO:
Using Events between a Visualforce Page and a Canvas App
SignedRequest
Force.com Canvas provides a SignedRequest object that has methods you can use to work with signed requests.
Method
verifyAndDecode verifyAndDecodeAsJson
Signature
public static CanvasRequest verifyAndDecode(String input,
String secret) throws
SecurityException
Description
Used to verify and decode a signed request;
returns a CanvasRequest Java object.
public static String verifyAndDecodeAsJson(String input, String secret) throws
SecurityException
Used to verify and decode a signed request; returns the
data in a JSON string.
SEE ALSO:
Verifying and Decoding a Signed Request
104
CHAPTER 12 Force.com Canvas Limits
Because Force.com Canvas runs in a multitenant environment, limits are enforced to ensure protection of shared resources.
Description
Number of canvas apps per user that can be displayed on the
Chatter tab. Only the first 50 canvas apps are displayed (sorted alphabetically).
Number of Force.com Canvas calls per day per user (24–hour period)
Limit
50
Heroku Quick Start calls per day per user
5,000
This includes SDK calls to get context and signed request calls.
Note that when you call a SignedRequest method, there are actually two calls that are made—one call for the method and one call for internal logging.
100
Heroku accounts have their own limits on the number of calls you can make.
SEE ALSO:
105
INDEX
A apex:canvasApp component entityFields attribute
Returning fields in the Record object
Application object
Associating a CanvasLifecycleHandler with an app
Attributes object
Authentication
OAuth
refresh signed request
SAML SSO
signed request
B
Browsers supported
C
Canvas app process overview
Canvas app user flow
OAuth
signed request
canvas apps
Canvas apps events
in a mobile card
in a page layout
in Chatter feed
in the publisher
listening for Streaming API events
resizing
Visualforce
Visualforce pages
where they appear in the user interface
where they can appear in a page layout
Canvas apps in Salesforce app set the location
Canvas apps in the publisher create the action manually
set the location and create the action
canvas personal apps administration of
distribution of
enabling in an organization
how users install
106 canvas personal apps (continued) revoking token for
uninstalling
Canvas Personal Apps about
creating
CanvasLifecycleHandler
Associating a CanvasLifecycleHandler with an app
Controlling canvas app behavior
Creating a new CanvasLifecycleHandler
Distributing your CanvasLifecycleHandler class
Filtering CanvasRequest context data
onRender()
Presenting user error messages
Testing your CanvasLifecycleHandler implementation
CanvasRequest object
CanvasRequest object
Chatter feed canvas apps in
Chatter Feed canvas app access considerations when exposing a canvas app in the feed
context considerations when exposing a canvas app in the feed
Client object
Code examples events, creating an event
events, subscribing to an event
events, unsubscribing from an event
exposing canvas app on a Visualforce page
getting context
OAuth flow
publishing a canvas app in Visualforce by calling publish
resizing, automatically resizing a canvas app by calling autogrow
resizing, explicitly resizing a canvas app by calling resize
resizing, explicitly resizing a canvas app in a Visualforce page by calling resize
resizing, getting the size of a canvas app by calling size
resizing, handling orientation changes by subscribing to the orientation event
resizing, subscribing to events by calling subscribe
resizing, subscribing to parent events by calling subscribe
Index
Code examples (continued) resizing, unsubscribing from events by calling unsubscribe
Streaming API, creating a Streaming API event
Streaming API, subscribing to a Streaming API event by calling subscribe
Streaming API, unsubscribing from a Streaming API event by calling unsubscribe
verifying and decoding a signed request
XHR, getting a list of Chatter users
XHR, posting to a Chatter feed
Context
Application object
Attributes object
Client object
Dimensions object
Environment object
getting from canvas app
Links object
object
Organization object
Parameters object
Record object
Record object examples
User object
Version object
Context object
Controller
Controlling canvas app behavior
Creating a new CanvasLifecycleHandler
Cross-domain XHR
Customizing app lifecycle
Associating a CanvasLifecycleHandler with an app
Controlling canvas app behavior
Filtering CanvasRequest context data
Presenting user error messages
D
Debug
Dimensions object
Distributing your CanvasLifecycleHandler class
E
Editions supported
Environment object
Events considerations
creating, code example
subscribing to, code examples
Events (continued) unsubscribing from, code examples
Events code examples creating an event
subscribing to an event
unsubscribing from an event
F
Filtering CanvasRequest context data
Force.com Canvas scenarios
Force.com Canvas SDK hosted on Salesforce server
publisher events
I
Introduction to Force.com Canvas
L
Limits
Links object
M
Mobile card canvas apps, adding to
N navigation methods
O
OAuth initiating
OAuth authentication
Organization object
Orientation handling in your canvas app
P
Page layout add a canvas app
canvas apps, adding to
canvas apps, where they can appear
Parameters object
Presenting user error messages
Process for creating a canvas app
Publisher canvas app access considerations when exposing a canvas app in the publisher
canvas apps in
107
Index
Publisher (continued) context considerations when exposing a canvas app in the publisher
Publisher events
Publishing code examples publishing a canvas app in Visualforce by calling publish
Q
Quick start create the app
introduction
prerequisites
set the app location
Quick start—advanced clone the “hello world” project
configure who can access the canvas app
configure who can access the installed canvas app
create the canvas app
deploy the “hello world” Web app to Heroku
install the canvas app
introduction
package the canvas app
prerequisites
run the Web app locally
update the canvas app
upload the canvas app package
R
Record object
Record object examples
Resizing
Resizing code examples automatically resizing a canvas app by calling autogrow
explicitly resizing a canvas app by calling resize
explicitly resizing a canvas app in a Visualforce page by calling resize
getting the size of a canvas app by calling size
subscribing to events by calling subscribe
subscribing to parent events by calling subscribe
subscribing to the orientation event
unsubscribing from events by calling unsubscribe
S
Salesforce app access considerations when exposing a canvas app in
Salesforce app
canvas apps in
context considerations when exposing a canvas app in
Salesforce app
Salesforce app (continued) icon considerations when exposing a canvas app in
Salesforce app
SAML SSO
SDK Objects
select tag in a canvas app
sfdc.streamingapi event
Signed request verifying and decoding
Signed request authentication
SignedRequest object
SignedRequest object
Streaming API
Streaming API code examples subscribing to a Streaming API event by calling subscribe
unsubscribing from a Streaming API event by calling unsubscribe
Streaming API event
Supported browsers
Supported Salesforce Editions
T
Testing your CanvasLifecycleHandler implementation
U
User interface considerations
User object
User permissions required
V
Version object
Visualforce apex:canvasApp component
apex:canvasApp component entityFields attribute
canvas app code examples
canvas apps, exposing
considerations when exposing a canvas app
W
Where canvas apps appear
X
XHR
XHR code example getting a list of Chatter users
posting to a Chatter feed
108
Preuzimanje
Reklama