AppSuite:Upsell: Difference between revisions
(Shortened some sentences) |
(Added example widget) |
||
| Line 117: | Line 117: | ||
The second event '''"upsell:upgrade"''' can be understood as the final imperative to request the upsell server-side. | The second event '''"upsell:upgrade"''' can be understood as the final imperative to request the upsell server-side. | ||
==Example portal widget== | |||
Besides waiting for the user to click on such links, it's always a good idea to offer explicit controls to trigger an upsell. One option is creating a portal widget that advertises a premium subscription: | |||
<pre class="language-javascript"> | |||
/** | |||
* This work is provided under the terms of the CREATIVE COMMONS PUBLIC | |||
* LICENSE. This work is protected by copyright and/or other applicable | |||
* law. Any use of the work other than as authorized under this license | |||
* or copyright law is prohibited. | |||
* | |||
* http://creativecommons.org/licenses/by-nc-sa/2.5/ | |||
* © 2013 Open-Xchange Inc., Tarrytown, NY, USA. info@open-xchange.com | |||
* | |||
* @author Matthias Biggeleben <matthias.biggeleben@open-xchange.com> | |||
*/ | |||
define('plugins/portal/upsell/register', | |||
['io.ox/core/extensions', | |||
'io.ox/files/api', | |||
'gettext!plugins/portal'], function (ext, api, gt) { | |||
'use strict'; | |||
var title = gt('Upgrade to premium'); | |||
ext.point('io.ox/portal/widget/upsell').extend({ | |||
title: title, | |||
preview: function (baton) { | |||
this.addClass('hide-title').append( | |||
$('<div class="content centered" style="cursor: pointer; padding-top: 3em;">').append( | |||
$('<h2>').append( | |||
$.txt(title + ' '), | |||
$('<i class="icon-star">') | |||
), | |||
$('<div>').text(gt('Click here for free trial.')) | |||
) | |||
.on('click', function () { | |||
ox.trigger('upsell:upgrade', { | |||
type: 'widget', | |||
id: 'io.ox/portal/widget/upsell', | |||
missing: '' | |||
}); | |||
}) | |||
); | |||
} | |||
}); | |||
}); | |||
</pre> | |||
==Accessing upsell settings== | ==Accessing upsell settings== | ||
Revision as of 11:38, 12 April 2013
Introduction
The OX Upsell packages allow to show advertisements to end-users who are just using a free service (for example "Webmail"). They enable hosting companies to offer premium OX services via in-app upsell.
When free-mail users click on premium features like "OX Files", an upsell dialog can be shown where the missing feature can be advertised via text, screenshots, and/or videos. Based on your specific configuration, the end-user can request a free trial period and/or directly buy the feature within the upsell dialog. The customer never has to leave the application as it is a seamless in-app upsell.
It is also possible for hosting companies to easily integrate their own online shop into OX Upsell, since the internal mechanisms are loosely coupled via events.
TL;DR
Upsell is: End-user has a set of capabilities. UI offers more than what's just available in order to promote things. Actions, e.g. inline links, that require missing capabilities trigger the in-app upsell. This process leads to a trial period or a new subscription. Technical challenge for the UI developer is to check what the end-user has, what can be shown beyond that, and how to handle upsell.
Events
Whenever the user starts an app or clicks on an inline-action, a capability-check is performed. For example, all inline actions have native support for such checks:
new Action('io.ox/calendar/detail/actions/sendmail', {
// this action requires the capability "webmail"
capabilities: 'webmail',
action: function (baton) {
// send mail
}
});
If the end-user does not have "webmail" (e.g. in a files-only setup) but calls this action, a proper event is fired:
// if any action misses a capability
ox.trigger('upsell:requires-upgrade');
// which provides the following data for apps:
{
type: "app",
id: "io.ox/mail/main",
missing: "webmail"
}
// and for inline-actions:
{
type: "inline-action",
id: "io.ox/calendar/detail/actions/sendmail",
missing: "webmail"
}
Capabilities
There are lots of different capabilities. They are defined on the server-side and basically they are just strings. Let's keep it simple and understand them as either services (e.g. mobility), specific functionalities (e.g. multiple_mail_accounts) or applications (e.g. calendar). Some examples:
- calendar
- contacts
- infostore
- mailfilter
- multiple_mail_accounts
...
- webmail
// list all available capabilities
_(ox.serverConfig.capabilities).pluck('id').sort();
An example: Free-mail users might just have webmail and contacts. If infostore is enabled for upsell, end-users will see the link to store mail attachments. But since this capability is missing, the event "upsell:requires-upgrade" is triggered which starts the upsell process. Upon successful completion this process should unlock the capability infostore for the end-user.
Example dialog
Whenever the event "upsell:requires-upgrade" is triggered there should be some response for the end-user. Usually an upsell dialog should open. This can be implemented as follows:
function showUpgradeDialog(e, options) {
require(['io.ox/core/tk/dialogs'], function (dialogs) {
new dialogs.ModalDialog({ easyOut: true })
.build(function () {
this.getHeader().append(
$('<h4>').text('Upgrade required')
);
this.getContentNode().append(
$.txt('This feature is not available.'),
$.txt('You need to upgrade your account now.'),
$.txt(' '),
$.txt('The first 90 days are free.')
);
this.addPrimaryButton('upgrade', 'Get free upgrade');
this.addButton('cancel', 'Cancel');
})
.setUnderlayStyle({
opacity: 0.70,
backgroundColor: '#08C'
})
.on('upgrade', function () {
ox.trigger('upsell:upgrade', options);
})
.on('show', function () {
ox.off('upsell:requires-upgrade', showUpgradeDialog);
})
.on('close', function () {
ox.on('upsell:requires-upgrade', showUpgradeDialog);
})
.show();
});
}
function upgrade(e, options) {
console.debug('upgrade', options);
alert('User decided to upgrade! (global event: upsell:upgrade)');
}
ox.on('upsell:requires-upgrade', showUpgradeDialog);
/*
* convention: 'upsell:upgrade' is used to trigger final upsell
* the current user and user_id can be found in global variables ox.user and ox.user_id
*/
ox.on('upsell:upgrade', upgrade);
Hint: For simple demo purposes, you can enable an internal upsell configuration by appending "&demo=upsell" to the URL. Needs to reload page, of course.
The second event "upsell:upgrade" can be understood as the final imperative to request the upsell server-side.
Example portal widget
Besides waiting for the user to click on such links, it's always a good idea to offer explicit controls to trigger an upsell. One option is creating a portal widget that advertises a premium subscription:
/**
* This work is provided under the terms of the CREATIVE COMMONS PUBLIC
* LICENSE. This work is protected by copyright and/or other applicable
* law. Any use of the work other than as authorized under this license
* or copyright law is prohibited.
*
* http://creativecommons.org/licenses/by-nc-sa/2.5/
* © 2013 Open-Xchange Inc., Tarrytown, NY, USA. info@open-xchange.com
*
* @author Matthias Biggeleben <matthias.biggeleben@open-xchange.com>
*/
define('plugins/portal/upsell/register',
['io.ox/core/extensions',
'io.ox/files/api',
'gettext!plugins/portal'], function (ext, api, gt) {
'use strict';
var title = gt('Upgrade to premium');
ext.point('io.ox/portal/widget/upsell').extend({
title: title,
preview: function (baton) {
this.addClass('hide-title').append(
$('<div class="content centered" style="cursor: pointer; padding-top: 3em;">').append(
$('<h2>').append(
$.txt(title + ' '),
$('<i class="icon-star">')
),
$('<div>').text(gt('Click here for free trial.'))
)
.on('click', function () {
ox.trigger('upsell:upgrade', {
type: 'widget',
id: 'io.ox/portal/widget/upsell',
missing: ''
});
})
);
}
});
});
Accessing upsell settings
The upsell configuration is located in the namespace "io.ox/core", the path is "upsell/enabled". Example:
// get all capabilities that can trigger upsell
require('settings!io.ox/core').get('upsell/enabled');
// contains data like this
{
infostore: true,
portal: true,
tasks: true
}
If upsell is not enabled and the end-user lacks specific capabilities, the app or the inline-action is not shown. If upsell is enabled by the upper configuration, inline-actions are shown and trigger the upsell event "upsell:requires-upgrade" if clicked (but do not execute the action itself).
/*
* if you want to create your own controls, you can use the following helpers
*/
var upsell = require('io.ox/core/upsell');
// check capabilities (space-separated)
upsell.has('portal webmail');
// get missing capabilities (would return "calendar" in demo mode)
upsell.missing(['portal webmail', 'contacts', 'calendar']);
/* checks if upsell is enabled for a set of capabilities
* true if at least one set matches
*/
upsell.enabled(['portal webmail', 'webmail calendar']);
/* convenience function: "visible"
* checks if something should be visible depending on required capabilities
* true if any item matches requires capabilities
* true if any item does not match its requirements but is enabled for upsell
* this function is used for any inline link, for example, to decide whether or not showing it
*/
upsell.visible(['portal webmail', 'contacts', 'calendar']);
// likewise if neither capability set nor enabled for upsell, we get a false
upsell.visible(['foo']);
// in case something weird happens (usually bad configuration) debug() helps
upsell.debug();
// and this one
_(ox.serverConfig.capabilities).pluck('id').sort();
Server settings
In order to configure this server-side, just create a new file upsell.properties or append to existing appsuite.properties (mind the double-slash; this in not a typo!):
io.ox/core//upsell/enabled/infostore=true io.ox/core//upsell/enabled/portal=true io.ox/core//upsell/enabled/tasks=true
Upsell in OX6
Please also consider this article as it also covers backend aspects.