Beta. In-App Messaging is in beta and open to every Gameball account. Send questions and feedback to support@gameball.co.
Display In-App Messages
One call after you identify the customer, and the Gameball SDK draws your dashboard campaigns over the current Activity: slide-ups, modals, and full screens, triggered by session start or by the events you already send. In-app messaging needs Gameball Android SDK 4.0.0 or later. It is entirely opt-in: until you call it, the module makes no requests, registers no callbacks, stores nothing, and draws nothing. For campaign options, triggers, filters, priority, cooldown, quiet hours, and how the analytics are defined, see In-App Messaging Campaigns.Requirements
Install
Add the repositories to your project-levelsettings.gradle, and the dependency to your app-level build.gradle:
settings.gradle
build.gradle
Application and identify the customer as you do today. Both must happen before messaging starts.
Start Messaging
Call it once you know who the customer is, typically right afterinitializeCustomer. Messages then appear on session start and when you send matching events.
Start early. The SDK learns which Activity to draw into from lifecycle callbacks it registers when you start messaging. If you start after the current Activity has resumed, for example from a login callback, the first message waits until an Activity next resumes, and the log shows
no Activity available; campaign N deferred. When the customer is already known at launch, start messaging in Application.onCreate.stopInAppMessaging() dismisses anything on screen, clears stored personalization values, sends pending analytics (waiting at most 800 ms), and unregisters the lifecycle callbacks. Call it on logout. Cached campaigns and frequency history stay on the device for that customer: the same customer picks them up after signing back in, and the next customer to start discards them. Analytics not sent in time go out after messaging starts again. Calling it when messaging was never started is safe, and isInAppMessagingStarted() reports the state.
Identifying a different customer through
initializeCustomer while messaging runs switches the module to that customer automatically, and keeps your options.Control Display and Actions
Every hook is optional and individually guarded. If yours throws, you lose the override for that call, never the message. Hooks run on the main thread, andbeforeDisplay is synchronous, so keep them fast.
InAppMessage exposes:
campaignId(Int) andvariationId(Int?)name(String?): the dashboard name, for logs onlymessageType(Int):1slide-up,2modal,3full screenheaderandbody(String?)buttons(List<InAppMessageButton>): always empty for a slide-upisTest(Boolean):truefor a dashboard test send, which displays normally and reports no analytics but still counts toward this device’s frequency history
header, body, and button text are the campaign’s copy before personalization, so they can contain {token} placeholders. Styling is applied by the SDK and is not exposed to the host.
Actions
GameballMessageAction is a sealed class, so an exhaustive when is safe. A tap on the message itself does nothing unless the campaign sets a click action, and a button with no action closes the message.
A campaign action this version does not support, such as request push permission, reaches your hook as
Dismiss and closes the message.
When the SDK runs a Navigate action itself, it first sends pending analytics, waiting at most 800 ms, and then calls onNavigate. A built-in OpenUrl opens immediately, and the same flush runs alongside it. Analytics are stored on the device either way, so a click that is not sent in time goes out with a later batch.
Events and Purchases
Events you already send throughsendEvent reach the trigger engine automatically, metadata included, so campaign filters work on them. The event name must match the campaign’s event name exactly, including letter case. A filter on a property the event does not carry fails, and number comparisons accept numbers or numeric strings, so send numbers as numbers where a campaign compares them.
logPurchase sends Gameball an event named purchase, with productId, price, currency, and quantity as metadata, whether or not messaging is running. Purchase-triggered campaigns can filter on those fields and on anything you pass in properties. If you already send a purchase event through sendEvent, replace it with logPurchase rather than sending both.
customerId is reported to callback as an error, and nothing is sent. callback and sessionToken behave as they do on sendEvent.
Language
There is no separate language setting for messages. Each sync requests the customer’s preferred language when your app set one, otherwise thelang you passed to init, and an unsupported code falls back to en. If you change the language with setLanguage, messages follow it from the next sync. Message copy comes from the campaign; the SDK’s only built-in text, the close button’s accessibility label, ships in English and Arabic.
Layouts use start and end alignment, so they mirror when your Activity’s layout direction is right-to-left. The SDK does not change direction based on the message language.
Personalization
Campaign text can contain placeholders such as{player_name} and {points_balance} in the header, body, and button labels. See In-App Messaging Campaigns for the list. Just before a message with a placeholder shows, the SDK fetches the customer’s current values, waiting at most 2 seconds, and reuses them for up to 60 seconds. Every event or purchase you send clears that cache, so a points balance reflects the action that triggered the message. The SDK removes any placeholder it cannot fill, and the message still shows.
Your hooks receive the text before substitution.
Push Permission
In-app messages cannot request notification permission in this version. A campaign button set to request push permission closes the message, and the SDK logsaction type 'request_push_permission' is not implemented.
Behavior Reference
The campaign rules themselves are described in In-App Messaging Campaigns. This is what they mean in an Android app.Logging and Troubleshooting
The SDK logs its decisions under the tagGameballIAM. Logging is on in debuggable builds and off in release builds, and nothing from this log leaves the device. To turn it on in a release build while you reproduce a problem, set it before or after you start messaging. The setting lasts until the app process ends.
GameballApp tag instead.
Nothing shows at all? Check in order:
- Logging is on. It is off in release builds unless you set
GameballApp.inAppMessagingLogging = true. initran with the API key, and the customer is initialized.startInAppMessagingwas called with a non-blank ID.parsed X/Y campaignsshows a usable campaign, and nosync failedline appears.- The campaign is live, targets Android, and the customer is in its audience.
- Its artwork loads over HTTPS.
- The account cooldown or quiet hours are not suppressing it.
- The customer has not already seen it.
ProGuard and R8
If you minify, keep the SDK and Gson as the SDK’s README already recommends:proguard-rules.pro
API Reference
Launch Checklist
1
Upgrade the SDK
com.github.gameballers:gb-mobile-android:4.0.0 and minSdk 24 or higher.2
Initialize and identify
init with the production API key in Application.onCreate, then initializeCustomer.3
Start and stop messaging
startInAppMessaging(customerId, options) as early as the customer is known, and stopInAppMessaging() on logout.4
Wire navigation
onNavigate wired if any campaign uses navigate.5
Declare RTL support
android:supportsRtl="true" if you serve right-to-left languages.6
Add keep rules and test
ProGuard keep rules in place for release builds, then run one campaign end to end on a fresh customer ID with
adb logcat -s GameballIAM open, in a debuggable build or with GameballApp.inAppMessagingLogging = true.Related Articles
In-App Messaging Campaigns
Campaign options, triggers, delivery rules, and analytics definitions.
Track Events
Send the events your campaigns are triggered by.
Push Notifications
Reach customers when the app is closed.
Go-Live Checklist
Verify the full Android integration before release.