|
|
(124 intermediate revisions by 8 users not shown) |
Line 1: |
Line 1: |
− | <div class="title">Upsell</div> | + | <!-- !!! --> |
− | __TOC__
| + | <!-- PLEASE APPLY CHANGES ONLY TO THE NEW TECHNICAL DOCUMENTATION: wd/frontend/web/documentation --> |
− | ==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.
| + | The content on this page has moved to http://oxpedia.org/wiki/index.php?title=AppSuite:OX_Upsell |
− | | |
− | ==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:
| |
− | | |
− | <pre class="language-javascript">
| |
− | new Action('io.ox/calendar/detail/actions/sendmail', {
| |
− | // this action requires the capability "webmail"
| |
− | capabilities: 'webmail',
| |
− | action: function (baton) {
| |
− | // send mail
| |
− | }
| |
− | });
| |
− | </pre>
| |
− | | |
− | If the end-user does not have "webmail" (e.g. in a files-only setup) but calls this action, a proper event is fired:
| |
− | | |
− | <pre class="language-javascript">
| |
− | // 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"
| |
− | }
| |
− | </pre>
| |
− | | |
− | ==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
| |
− | * facebook
| |
− | * infostore
| |
− | * mailfilter
| |
− | * multiple_mail_accounts
| |
− | ...
| |
− | * webmail
| |
− | | |
− | <pre class="language-javascript">
| |
− | // list all available capabilities
| |
− | _(ox.serverConfig.capabilities).pluck('id').sort();
| |
− | </pre>
| |
− | | |
− | 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:
| |
− | | |
− | <pre class="language-javascript">
| |
− | 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);
| |
− | | |
− | </pre>
| |
− | | |
− | 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:
| |
− | | |
− | <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==
| |
− | The upsell configuration is located in the namespace ''"io.ox/core"'', the path is ''"upsell/enabled"''. Example:
| |
− | | |
− | <pre class="language-javascript">
| |
− | // 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
| |
− | }
| |
− | </pre>
| |
− | | |
− | 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).
| |
− | | |
− | <pre class="language-javascript">
| |
− | /*
| |
− | * 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();
| |
− | | |
− | </pre>
| |
− | | |
− | ==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!):
| |
− | | |
− | <pre class="language-settings">
| |
− | io.ox/core//upsell/enabled/infostore=true
| |
− | io.ox/core//upsell/enabled/portal=true
| |
− | io.ox/core//upsell/enabled/tasks=true
| |
− | </pre>
| |
− | | |
− | ==Upsell in OX6==
| |
− | Please also consider [[Upsell|this article]] as it also covers backend aspects.
| |
− | | |
− | [[Category:AppSuite]]
| |
− | [[Category:UI]]
| |