JavaScript API version 4
- Changelog
- Usage
- Methods
Changelog
In this release, we added ShowpadLib.share()
and ShowpadLib.getAssetPreviewUrl()
. We updated ShowpadLib.getDeviceInfo()
to also return the app.
Usage
The methods listed below are all available on the window.ShowpadLib
object after page load.
Simply call the desired method with the correct parameters.
When window.ShowpadLib
is created and ready to go, the method window.onShowpadLibLoaded()
will be called (if it exists).
Have a look at the examples to get some more context.
Methods
All methods returning a boolean
will return true
when the call was executed successfully and return false
when something went wrong.
The method returns false
when a required parameter was not set or when the method was called again before the previous method was completed.
Some methods return full objects or single values like getUserInfo()
or getVersion()
getVersion
Returns the version of the integration. If this function does not exist, we can assume that version 2 is available.
let version = null;
if (typeof window.ShowpadLib.getVersion === 'function') {
version = window.ShowpadLib.getVersion(); // Would be 4 in this case.
}
else {
version = 2;
}
getUserInfo
Returns the information of the active user.
const userInfo = window.ShowpadLib.getUserInfo();
// userInfo will look like this:
const userInfo = {
email: 'user@company.com',
id: '123',
user_name: 'user@company.com',
full_name: 'Firstname Lastname'
};
getDeviceInfo
Returns the information of the current device.
The locale
value is a 2-letter code following the ISO 639-1 standard.
The app
is one of the following values: web
, ios
, android
, windows
. It represents the app where this HTML Content is currently being viewed.
const deviceInfo = window.ShowpadLib.getDeviceInfo();
// userInfo will look like this:
const deviceInfo = {
locale: 'en', // language of the device, following ISO 639-1
app: 'web' // The app
};
hasFeature
Use this method to know if a specific feature is supported on the app your content is running in.
This method will (synchronously) return:
true
if the feature is supported.false
if the feature is known to the app but not supported.null
if the feature is unknown to this version of the application.
The list of features can be found in the table below.
Key | Description |
---|---|
shareEmail | Share content by sending an email. Useful in combination with the share() method |
shareLink | Share content by generating a link. Useful in combination with the share() method |
collections | Add content to a collection. Useful in combination with the addAssetsToCollection() method |
if (window.ShowpadLib.hasFeature('shareLink')) {
// The feature "shareLink" is supported on this platform.
}
share
Shows a modal view to share contents. The provided assets will be added so they can be shared.
The type of the modal is either email
or link
.
If some of the assets are not shareable (expired, deleted, unshareable, …), the modal will still be shown, but the callback function will be called with result partial
. In this case, the Showpad client will show a warning message to the user that some content cannot be shared.
If none of the provided assets can be shared, a warning will be shown, but no sharing modal will be displayed and the result will be error
const assetSlugs = ['asset1-slug','asset2-slug'];
const type = 'email'; // Can be 'email' or 'link'.
if (window.ShowpadLib.share(type, assetSlugs, callbackFn)) {
// Call went through, callbackFn will be called.
}
else {
// Something went wrong or the given type is not supported on this app.
}
function callbackFn (result) {
if (result == 'success') {
// all assets were added to the share dialog and the dialog is shown
}
else if (result == 'partial') {
// some assets were not added to the share dialog, because they could be expired, unshareable, deleted, ...
// the share-dialog is shown
}
else if (result == 'error') {
// no assets were added and the dialog is NOT shown
}
else {
// null was returned, something went wrong
}
}
getAssetPreviewUrl
Returns the url with which the asset preview image can be loaded. The assetId is always required. The assetSlug is required on mobile.
assetId
is the actual asset-id, eg. “74d51a49c063fdf8a4ef6c5be4c032fc”assetSlug
is the last part of theappLink
, eg. ‘18c6236ced7d’ in ‘showpad://file/18c6236ced7d’. You can find this in the Online-Platform or retrieve it via our API.size
is the maximum dimension for the width or height.
var assetId = 'asset1-id';
var assetSlug = 'asset1-slug';
var size = 400;
var imageEl = document.getElementById('image');
imageEl.src = ShowpadLib.getAssetPreviewUrl(assetId, assetSlug, size);
// The asset preview image should now be loaded in the image element.
getCollections
Invokes the callback function with a list of collection data ([{ id, name }]
) or null
when something went wrong.
if (window.ShowpadLib.getCollections(callbackFn)) {
// Call went through, callbackFn will be called.
}
else {
// Something went wrong
}
function callbackFn (collections) {
if (collections) {
// Collections might look like this:
const collections = [
{
id: '1',
name: 'Collection Name 1',
},
{
id: '2',
name: 'Collection Name 2'
}
];
}
else {
// null was returned, something went wrong
}
}
openCollection
Shows a modal view with the contents of the collection. This view allows for the collection to be shared
const collectionId = '...' ;
if (window.ShowpadLib.openCollection(collectionId)) {
// Modal will be opened
}
else {
// Something went wrong
}
createCollection
Creates a new collection with the specified name, will invoke the callback function with the id of the new collection or null
when an error occured
const name = 'My Collection Name';
if (window.ShowpadLib.createCollection(name, callbackFn)) {
// Call went through, callbackFn will be called.
}
else {
// Something went wrong
}
function callbackFn (collectionId) {
if (collectionId) {
// Do something with collection id
}
else {
// Something went wrong
}
}
addAssetsToCollection
Shows the modal which prompts the user the select the collection to add the assets to.
Will call the callback method with the id of the collection the assets were added to or null
if the flow was canceled or an error occured
const assets = [];
assets.push('asset1-slug');
assets.push('asset2-slug');
if (window.ShowpadLib.addAssetsToCollection(assets, callbackFn)) {
// Call went through, modal will be shown.
// callbackFn will be called
}
else {
// Something went wrong
}
function callbackFn (collectionId) {
if (collectionId) {
// Assets were added to the collection with provided collectionId
}
else {
// Something went wrong or the user canceled the flow or
// none of the given asset-slugs were found.
}
}
addAssetsToCollectionWithId
Will add the given assets to the collection with the given id. If the collection does not exist, nothing will happen.
const collectionId = '...';
const assets = ['asset1-slug', 'asset2-slug'];
if (window.ShowpadLib.addAssetsToCollectionWithId(collectionId, assets, callbackFn)) {
// Call went through, callbackFn will be called
}
else {
// Something went wrong
}
function callbackFn (collectionId) {
if (collectionId) {
// Assets were added to the collection with provided collectionId
}
else {
// Something went wrong or the user canceled the flow
}
}
clearCollection
Removes all the items from the given collection
const collectionId = '...';
if (window.ShowpadLib.clearCollection(collectionId)) {
// Call went through, items will be cleared
}
else {
// Something went wrong
}
getShowpadApi
Invokes the callback function with an object with the required information to do an HTTP request to the Showpad API.
If the Showpad API returns a 401, it means your access token has expired, and you’ll need to request a new one.
Do this using the refreshShowpadApi()
method.
if (window.ShowpadLib.getShowpadApi(callbackFn)) {
// Call went through, callbackFn will be called
}
else {
// Something went wrong
}
function callbackFn (apiConfig) {
if (apiConfig) {
// apiConfig can look like this:
const apiConfig = {
accessToken: 'xyz',
url: 'https://subdomain.showpad.biz', // no trailing slash
error: null // or a string with the actual error
};
if (apiConfig.accessToken && apiConfig.url) {
// Do an api-call
}
else if (apiConfig.error) {
if (apiConfig.error === 'unavailable') {
// no api key available
}
else {
// something else went wrong
}
}
else {
// Something went wrong
}
}
else {
// Something went wrong or the user canceled the flow
}
}
refreshShowpadApi
This method will refresh the Showpad access token and call the callback function with the same object as the getShowpadApi
call
function doApiCall (url, config) {
fetch(url, config)
.then(response => {
if (response.status < 200 || response.status >= 400) {
const error = new Error();
error.statusCode = response.status;
throw error;
}
})
.catch(onApiCallFailed);
}
function onApiCallFailed (error) {
if (error.statusCode === 401) {
// Unauthorized, let's refresh the token
refreshToken(url, config);
}
}
function refreshToken (url, config) {
if (window.ShowpadLib.refreshShowpadApi(apiConfig => {})) {
// Call went through, callbackFn will be called
}
else {
// Something went wrong
}
function callbackFn (apiConfig) {
if (apiConfig) {
// apiConfig can look like this:
const apiConfig = {
accessToken: 'xyz',
url: 'https://subdomain.showpad.biz', // no trailing slash
error: null // or a string with the actual error
};
if (apiConfig.accessToken && apiConfig.url) {
// Refresh succeeded, retry the failed call.
config.headers['Authorization'] = `Bearer ${apiConfig.accessToken}`;
doApiCall(url, config);
}
else if (apiConfig.error) {
if (apiConfig.error === 'unavailable') {
// no api key available
}
else if (apiConfig.error === 'expired') {
// Refresh Token has expired, no further calls can be made.
}
else {
// Something went wrong
}
}
else {
// Something went wrong
}
}
else {
// Something went wrong
}
}
}
getSalesforceApi
Invokes the callback function with an object with the required information to do an HTTP request to the Salesforce API.
If the Salesforce API returns a 401, it means your access token has expired, and you’ll need to request a new one.
Do this using the refreshSalesforceApi()
method.
if (window.ShowpadLib.getSalesforceApi(callbackFn)) {
// Call went through, callbackFn will be called
}
else {
// Something went wrong
}
function callbackFn (apiConfig) {
if (apiConfig) {
// apiConfig can look like this:
const apiConfig = {
accessToken: 'xyz',
url: 'https://login.salesforce.com', // no trailing slash
error: null // or a string with the actual error
};
if (apiConfig.accessToken && apiConfig.url) {
// Do an api-call to Salesforce
}
else if (apiConfig.error) {
if (apiConfig.error === 'unavailable') {
// no Salesforce access token available
// Possibly, the user is not connected to Salesforce.
}
else {
// something else went wrong
}
}
else {
// Something went wrong
}
}
else {
// Something went wrong or the user canceled the flow
}
}
Particularities with the Salesforce API and HTML Content
To call an api on a different domain (eg. “https://login.salesforce.com”), that service needs to have CORS enabled. More info about CORS or (Cross-Origin Resource Sharing) can be found here .
Salesforce has a specific settings-page to enable specific domains for your Salesforce instance. Salesforce requires this to be an “https://”-url. The problem is that your HTML Content is also rendered in our mobile apps, and they don’t use an “https://”-scheme, but something specific for the platform (eg. “ms-appx-package://” on Windows).
So calling the Salesforce API directly from your HTML Content, will probably result in a CORS error by Salesforce.
To circumvent this, we suggest to proxy all api-calls to Salesforce through an iframe. This iframe would link to a webpage hosted on a CORS-enabled domain. The javascript in the HTML Content would just call some javascript in that iframe, which would send it through to Salesforce and send the response back. The communication between the HTML Content and the iframe needs to happen with “postMessage” https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage.
The diagram below might make things more clear.
refreshSalesforceApi
This method will refresh the Salesforce access token and call the callback function with the same object as the getSalesforceApi
call.
function doSalesforceApiCall (url, config) {
fetch(url, config)
.then(response => {
if (response.status >= 200 && response.status < 300) {
return response;
}
const error = new Error();
error.statusCode = response.status;
throw error;
})
.catch(onSalesforceApiCallFailed);
}
function onSalesforceApiCallFailed (error) {
if (error.statusCode === 401) {
// Unauthorized, let's refresh the token
refreshSalesforceToken(url, config);
}
}
function refreshSalesforceToken (url, config) {
if (window.ShowpadLib.refreshSalesforceApi(apiConfig => {})) {
// Call went through, callbackFn will be called
}
else {
// Something went wrong
}
function callbackFn (apiConfig) {
if (apiConfig) {
// apiConfig can look like this:
const apiConfig = {
accessToken: 'xyz',
url: 'https://login.salesforce.com', // no trailing slash
error: null // or a string with the actual error
};
if (apiConfig.accessToken && apiConfig.url) {
// Refresh succeeded, retry the failed call.
config.headers['Authorization'] = `Bearer ${apiConfig.accessToken}`;
doApiCall(url, config);
}
else if (apiConfig.error) {
if (apiConfig.error === 'unavailable') {
// no Salesforce access token available
}
else if (apiConfig.error === 'expired') {
// Salesforce Refresh Token has expired, no further calls can be made.
}
else {
// Something went wrong
}
}
else {
// Something went wrong
}
}
else {
// Something went wrong
}
}
}