In-App Messaging
In-app messages are toaster-style, foreground-only messages rendered by the SDK while the app is in the foreground. They do not require OS-level notification permission, so deliverability is close to 100% of your app install base.
This guide covers how in-app messages work, lifecycle callbacks, email collection, and how to create campaigns in ZMP. The SDK renders the in-app UI itself — your app does not wire up a view. In-app messages are a different surface from push notifications — see Push Notifications for the push surface.
On this page
- How it works
- Start and stop in-app messaging
- Lifecycle callbacks
- Creating an in-app message in ZMP
- In-app email collection
How it works
The SDK uses a polling mechanism to fetch in-app messages. When a message is received, the SDK evaluates the app state to determine whether to display it. If the conditions are met, an in-app message is shown.
To monitor the lifecycle of a message (will appear, did appear, clicked, dismissed), implement the ZTInAppMessageLifeCycle interface and register it with ZetaClient.
Start and stop in-app messaging
In-app messaging is enabled by default. To stop displaying in-app messages:
ZetaClient.inApp.stop()
ZetaClient.INSTANCE.getInApp().stop();
To restart:
ZetaClient.inApp.start()
ZetaClient.INSTANCE.getInApp().start();
Note: The SDK does not persist the stop state; your app must manage this state. By default, the SDK starts displaying in-app messages on every launch.
Lifecycle callbacks
Implement ZTInAppMessageLifeCycle to react to message lifecycle events.
import net.zetaglobal.app.zetacore.inappmessage.ZTInAppMessageLifeCycle
class MyInAppListener : ZTInAppMessageLifeCycle {
override fun willAppear(message: ZTInAppMessage) {
// Called when the in-app message is about to be displayed
}
override fun didAppear(message: ZTInAppMessage) {
// Called after the in-app message has been displayed
}
override fun onClicked(message: ZTInAppMessage, deeplink: String?) {
// Called when the user clicks the in-app message
}
override fun onDismissed(message: ZTInAppMessage) {
// Called when the user dismisses the in-app message
}
}
ZetaClient.inApp.setCallBack(MyInAppListener())
import net.zetaglobal.app.zetacore.inappmessage.ZTInAppMessageLifeCycle;
ZetaClient.INSTANCE.getInApp().setCallBack(new ZTInAppMessageLifeCycle() {
@Override
public void willAppear(@NonNull ZTInAppMessage message) {
// Called when the in-app message is about to be displayed
}
@Override
public void didAppear(@NonNull ZTInAppMessage message) {
// Called after the in-app message has been displayed
}
@Override
public void onClicked(@NonNull ZTInAppMessage message, @Nullable String deeplink) {
// Called when the user clicks the in-app message
}
@Override
public void onDismissed(@NonNull ZTInAppMessage message) {
// Called when the user dismisses the in-app message
}
});
Creating an in-app message in ZMP
- Access the ZMP portal. Log in to ZMP.
- Configure the campaign.
- Open the campaign window.
- Select the channel Mobile InApp Push (the ZMP channel name for in-app messages).
- Compose the message. Click the In-App Messaging Setup content area, then:
- Title — provide a title.
- Body — provide the body.
- On-click action — choose one of:
- Deep Link — on tap, the SDK delivers the deep link URL through the lifecycle callback. Your app handles internal redirection.
- Dismiss — no action on tap.
- Web Link — the URL opens in one of:
- In-App Web View — opens inside the SDK using Chrome Custom Tabs.
- External Browser — opens in the device's default browser.
- Email Submission — the email entered by the user in a form template is available via the form data on the message.
- In-app message image — optional.
- Finalize. Click Done.
- Activate. Activate the campaign from the portal.
In-app email collection
In-app email collection prompts unknown users (users ZMP does not yet have email for) to submit their email via an in-app form.
- Email collection triggers only for unknown users in ZMP.
- Known users who already have an email identifier in ZMP skip this flow entirely.
The submitted email is available on the lifecycle callback payload:
override fun onClicked(message: ZTInAppMessage, deeplink: String?) {
val email = message.inAppMessageFormData?.email
if (email != null) {
// Persist, forward to your backend, etc.
}
}
@Override
public void onClicked(@NonNull ZTInAppMessage message, @Nullable String deeplink) {
ZTInAppMessageFormData formData = message.getInAppMessageFormData();
if (formData != null && formData.getEmail() != null) {
String email = formData.getEmail();
// Persist, forward to your backend, etc.
}
}
Next
- App Inbox — persistent, queryable messages you render in your own UI.
- Push Notifications — background, OS-delivered notifications.
- User Guide: In-App Messaging — campaign setup and message composition from ZMP.
See also
- Platform support -- feature availability by platform and SDK version.
