Class Invites

java.lang.Object
com.codename1.analytics.invite.Invites

public final class Invites extends Object

Invite a friend, and follow the invitation through to what it caused.

Mint an invite, share it, and on the friend's device recover the invite that produced the install. Once attribution resolves it is written as persistent analytics dimensions, so every later event -- including the purchase event the framework already emits -- carries the campaign and the referrer, and revenue per campaign comes out of the reports you have.

Sending

Invite invite = Invites.create(InviteRequest.create()
        .campaign("spring")
        .channel("share_sheet")
        .build());
Invites.share(invite, "Come and try this with me");

create(InviteRequest) returns immediately and works with no network, so the share sheet never waits on a server. Registration with the link service is retried in the background.

Receiving

Invites.setInviteListener(new InviteListener() {
    public void inviteReceived(InviteAttribution attribution) {
        // attribution.getCode(), getCampaign(), getPayload()
    }

    public void attributionUnavailable(String reason) {
    }
});
Invites.checkForInvite();

Call checkForInvite() from your start() method. It is a pull rather than a callback on purpose: Android delivers a link by replacing the activity intent and iOS by setting a property, and reading the launch argument is the one path that behaves the same on both.

Everything reported here is gated on the analytics consent category of Analytics, and nothing is transmitted until consent is granted.

One thing does happen before consent: on first launch a coarse device profile -- operating system version, hardware model, language, screen size -- is written to local storage so that a deferred match is still possible once consent arrives. It is never transmitted while consent is withheld, and it is deleted outright if consent is refused. There is no alternative that also works, because the window in which a deferred match can be made closes within the hour, long before a typical consent prompt is answered. setAttributionWindow(long) with 0 switches deferred attribution off entirely.

How exact the answer is

InviteAttribution.getMatchType() says how the attribution was made. MATCH_DIRECT and MATCH_REFERRER are exact. MATCH_FINGERPRINT is a statistical match made on the server, used where the platform's store carries no referrer, and it is occasionally wrong -- check InviteAttribution.getConfidence() and do not pay a referral bounty on it without saying so.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final String
    The analytics category every invite event is reported under.
    static final long
    The default attribution window: how long after a first launch a deferred invite may still be resolved.
    static final String
    Dimension carrying the campaign the invite belonged to.
    static final String
    Dimension carrying the channel the invite was sent through.
    static final String
    Dimension carrying the matched invite code.
    static final String
    Dimension carrying how the attribution was made.
    static final String
    The link opened an application that was already installed.
    static final String
    The server matched this install to a click statistically, because the platform's store carries no referrer.
    static final String
    The invite code made the whole trip through the application store and came back verbatim.
    static final String
    Analytics consent was refused, so attribution was abandoned.
    static final String
    The attribution window closed before an answer arrived.
    static final String
    No invite matched.
    static final String
    This platform cannot recover a deferred invite.
    static final int
    Attribution was abandoned because analytics consent was refused.
    static final int
    Nothing has been attributed and nothing is outstanding.
    static final int
    No invite will be attributed to this install.
    static final int
    An invite is being resolved; the answer has not arrived yet.
    static final int
    This install has been attributed to an invite.
  • Method Summary

    Modifier and Type
    Method
    Description
    static boolean
    Looks for an invite: first in the launch argument, then, when this looks like a fresh install, by asking the link service.
    static void
    Reports that the invited user reached the outcome the invite existed for -- signed up, joined the room, completed onboarding.
    static void
    conversion(String action, double value, String currency)
    Reports a conversion carrying a value, so revenue can be attributed to the campaign and the referrer.
    static Invite
    Mints an invite and returns it immediately.
    static void
    Retries anything queued: unregistered invites, and an outstanding deferred match.
    The attribution for this install, or null when there is none yet.
    static long
    The attribution window in milliseconds.
    The registered listener, or null.
    static String
    The link service base address in use.
    static int
    Where attribution has got to: one of the STATE_ constants.
    static boolean
    Offers a url to the invite machinery directly, for applications that consume the launch argument themselves or route it through com.codename1.router.
    static boolean
    Whether last touch attribution is enabled.
    static boolean
    Whether the link service has acknowledged this invite.
    static void
    Registers the platform hook that reads the application store's install referrer.
    static void
    Reports the outcome of a share your application performed itself, rather than through share(Invite, String).
    static void
    Forgets every trace of invite attribution on this device: the pending fingerprint, the resolved attribution and the referral dimensions.
    static void
    setAttributionWindow(long millis)
    How long after a first launch a deferred invite may still be resolved.
    static void
    Registers the listener that receives the invite behind this install.
    static void
    Points the invite machinery at a different link service.
    static void
    setReattribution(boolean value)
    Whether a later invite replaces an earlier attribution.
    static void
    share(Invite invite, String message)
    Shares an invite through the native share sheet.
    static void
    share(Invite invite, String message, Rectangle sourceRect, ShareResultListener resultListener)
    Shares an invite through the native share sheet and reports the outcome.

    Methods inherited from class Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • STATE_NONE

      public static final int STATE_NONE
      Nothing has been attributed and nothing is outstanding.
      See Also:
    • STATE_PENDING

      public static final int STATE_PENDING
      An invite is being resolved; the answer has not arrived yet.
      See Also:
    • STATE_RESOLVED

      public static final int STATE_RESOLVED
      This install has been attributed to an invite.
      See Also:
    • STATE_NONE_FOUND

      public static final int STATE_NONE_FOUND
      No invite will be attributed to this install.
      See Also:
    • STATE_DECLINED

      public static final int STATE_DECLINED
      Attribution was abandoned because analytics consent was refused.
      See Also:
    • MATCH_DIRECT

      public static final String MATCH_DIRECT
      The link opened an application that was already installed. Exact.
      See Also:
    • MATCH_REFERRER

      public static final String MATCH_REFERRER
      The invite code made the whole trip through the application store and came back verbatim. Exact.
      See Also:
    • MATCH_FINGERPRINT

      public static final String MATCH_FINGERPRINT
      The server matched this install to a click statistically, because the platform's store carries no referrer. Not exact.
      See Also:
    • REASON_NO_MATCH

      public static final String REASON_NO_MATCH
      No invite matched. The ordinary outcome for an uninvited install.
      See Also:
    • REASON_EXPIRED

      public static final String REASON_EXPIRED
      The attribution window closed before an answer arrived.
      See Also:
    • REASON_UNSUPPORTED

      public static final String REASON_UNSUPPORTED
      This platform cannot recover a deferred invite.
      See Also:
    • CATEGORY

      public static final String CATEGORY
      The analytics category every invite event is reported under.
      See Also:
    • DIMENSION_CODE

      public static final String DIMENSION_CODE
      Dimension carrying the matched invite code.
      See Also:
    • DIMENSION_CAMPAIGN

      public static final String DIMENSION_CAMPAIGN
      Dimension carrying the campaign the invite belonged to.
      See Also:
    • DIMENSION_CHANNEL

      public static final String DIMENSION_CHANNEL
      Dimension carrying the channel the invite was sent through.
      See Also:
    • DIMENSION_MATCH

      public static final String DIMENSION_MATCH
      Dimension carrying how the attribution was made.
      See Also:
    • DEFAULT_ATTRIBUTION_WINDOW

      public static final long DEFAULT_ATTRIBUTION_WINDOW
      The default attribution window: how long after a first launch a deferred invite may still be resolved.
      See Also:
  • Method Details

    • registerInstallReferrerSource

      public static void registerInstallReferrerSource(InstallReferrerSource source)

      Registers the platform hook that reads the application store's install referrer. The Codename One build calls this before the application starts on platforms that have one; an application does not.

      Parameters
      • source: the platform source, or null to remove it
    • create

      public static Invite create(InviteRequest request)

      Mints an invite and returns it immediately.

      This never blocks and never fails for want of a network. The code is generated on the device, so Invite.getUrl() is usable at once; registration with the link service is queued and retried until it lands. A link clicked before that registration arrives is still attributed, because the server records the click against the code and joins it when the registration turns up.

      Parameters
      • request: what to mint, must not be null
      Returns

      the invite, never null

    • share

      public static void share(Invite invite, String message)

      Shares an invite through the native share sheet.

      Parameters
      • invite: the invite to share, must not be null

      • message: text placed before the link, or null for the link alone

    • share

      public static void share(Invite invite, String message, Rectangle sourceRect, ShareResultListener resultListener)

      Shares an invite through the native share sheet and reports the outcome.

      The invite funnel's invite_shared event is emitted from here, and only when the platform confirms the user actually shared -- a dismissed sheet reports invite_share_dismissed instead. That is what makes the "shared" number a measurement rather than an assumption.

      Parameters
      • invite: the invite to share, must not be null

      • message: text placed before the link, or null for the link alone

      • sourceRect: popover anchor hint, may be null

      • resultListener: receives the share outcome, may be null

    • reportShareResult

      public static void reportShareResult(Invite invite, ShareResult result)

      Reports the outcome of a share your application performed itself, rather than through share(Invite, String). Use this when the invite goes out through your own user interface -- a contact picker, a message composer, a copy-link button -- so the funnel still records whether it was really sent.

      invite_shared is emitted only when result says the user actually shared; a dismissed sheet reports invite_share_dismissed instead. Calling this is optional and calling it twice for one share double counts, so call it once, from the share callback.

      Parameters
      • invite: the invite that was shared, must not be null

      • result: the outcome the platform reported, may be null

    • setInviteListener

      public static void setInviteListener(InviteListener l)

      Registers the listener that receives the invite behind this install.

      An answer that arrived before the listener was registered -- which happens routinely on a cold launch from a link, because the platform delivers the link before the application starts -- is delivered as soon as this is called.

      Parameters
      • l: the listener, or null to remove it
    • getInviteListener

      public static InviteListener getInviteListener()

      The registered listener, or null.

      Returns

      the listener

    • checkForInvite

      public static boolean checkForInvite()

      Looks for an invite: first in the launch argument, then, when this looks like a fresh install, by asking the link service.

      Safe and cheap to call on every start; it will not attribute twice and will not report twice.

      Returns

      true when the launch argument carried an invite link

    • handleUrl

      public static boolean handleUrl(String url)

      Offers a url to the invite machinery directly, for applications that consume the launch argument themselves or route it through com.codename1.router.

      Parameters
      • url: the url to inspect, may be null
      Returns

      true when the url carried an invite code

    • getAttribution

      public static InviteAttribution getAttribution()

      The attribution for this install, or null when there is none yet.

      Returns

      the attribution

    • getState

      public static int getState()

      Where attribution has got to: one of the STATE_ constants.

      Returns

      the current state

    • conversion

      public static void conversion(String action)

      Reports that the invited user reached the outcome the invite existed for -- signed up, joined the room, completed onboarding. No-op unless this install was attributed.

      Parameters
      • action: what the user did
    • conversion

      public static void conversion(String action, double value, String currency)

      Reports a conversion carrying a value, so revenue can be attributed to the campaign and the referrer. No-op unless this install was attributed.

      Parameters
      • action: what the user did

      • value: the value of the conversion

      • currency: the currency code, or null

    • setLinkBase

      public static void setLinkBase(String url)

      Points the invite machinery at a different link service. Defaults to the Codename One cloud, honouring the cloudServerURL display property.

      Parameters
      • url: the base address, with no trailing path
    • getLinkBase

      public static String getLinkBase()

      The link service base address in use.

      Returns

      the base address, never null

    • setAttributionWindow

      public static void setAttributionWindow(long millis)

      How long after a first launch a deferred invite may still be resolved. Clamped to at most 30 days. Zero switches deferred attribution off, which is the supported way to ship without the statistical match.

      Parameters
      • millis: the window in milliseconds
    • getAttributionWindow

      public static long getAttributionWindow()

      The attribution window in milliseconds.

      Returns

      the window

    • setReattribution

      public static void setReattribution(boolean value)

      Whether a later invite replaces an earlier attribution. Off by default: first touch stands, so a user's cohort does not change underneath the reports.

      Parameters
      • value: true for last touch
    • isReattribution

      public static boolean isReattribution()

      Whether last touch attribution is enabled.

      Returns

      true when a later invite replaces an earlier one

    • flush

      public static void flush()
      Retries anything queued: unregistered invites, and an outstanding deferred match. Called for you on the paths that matter; exposed for an application that knows it has just regained connectivity.
    • reset

      public static void reset()

      Forgets every trace of invite attribution on this device: the pending fingerprint, the resolved attribution and the referral dimensions.

      Analytics.resetClientId() triggers this for you, because an erasure that left the referral dimensions behind would re-link the fresh identity to the same inviter.

    • isRegistered

      public static boolean isRegistered(Invite invite)

      Whether the link service has acknowledged this invite.

      An unacknowledged invite is still shareable and still attributes -- registration is retried until it lands -- so this is a diagnostic rather than a gate.

      Parameters
      • invite: the invite to ask about, may be null
      Returns

      true once the server has acknowledged it