Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 51 additions & 7 deletions src/core/classes/Iterable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { IterableInAppMessage } from '../../inApp/classes/IterableInAppMessage';
import { IterableInAppCloseSource } from '../../inApp/enums/IterableInAppCloseSource';
import { IterableInAppDeleteSource } from '../../inApp/enums/IterableInAppDeleteSource';
import { IterableInAppLocation } from '../../inApp/enums/IterableInAppLocation';
import { IterableActionSource } from '../enums/IterableActionSource';
import { IterableAuthResponseResult } from '../enums/IterableAuthResponseResult';
import { IterableEventName } from '../enums/IterableEventName';
import type { IterableAuthFailure } from '../types/IterableAuthFailure';
Expand Down Expand Up @@ -967,7 +968,11 @@ export class Iterable {
*
* Event Handlers:
* - `handleUrlCalled`: Invokes the URL handler if configured, with a delay on Android to allow the activity to wake up.
* When the action source is a push notification, the last push payload is automatically fetched and
* attached to the `IterableActionContext` as `pushPayload`, making custom push data available in the handler.
* - `handleCustomActionCalled`: Invokes the custom action handler if configured.
* When the action source is a push notification, the last push payload is automatically fetched and
* attached to the `IterableActionContext` as `pushPayload`.
* - `handleInAppCalled`: Invokes the in-app handler if configured and sets the in-app show response.
* - `handleAuthCalled`: Invokes the authentication handler if configured and handles the promise result.
* - `handleAuthSuccessCalled`: Sets the authentication response callback to success.
Expand All @@ -988,13 +993,34 @@ export class Iterable {
const context = IterableActionContext.fromDict(dict.context);
Iterable.wakeApp();

if (Platform.OS === 'android') {
//Give enough time for Activity to wake up.
setTimeout(() => {
callUrlHandler(Iterable.savedConfig, url, context);
}, 1000);
// When the action originates from a push notification, fetch the last
// push payload and attach it to the context so that URL handlers can
// access custom push data (e.g. promo codes, deep link metadata).
const enrichAndHandle = (ctx: IterableActionContext) => {
if (Platform.OS === 'android') {
//Give enough time for Activity to wake up.
setTimeout(() => {
callUrlHandler(Iterable.savedConfig, url, ctx);
}, 1000);
} else {
callUrlHandler(Iterable.savedConfig, url, ctx);
}
};

if (context.source === IterableActionSource.push) {
Iterable.getLastPushPayload()
.then((payload) => {
if (payload && typeof payload === 'object') {
context.pushPayload = payload as Record<string, unknown>;
}
enrichAndHandle(context);
})
.catch(() => {
// If fetching the payload fails, proceed without it
enrichAndHandle(context);
});
} else {
callUrlHandler(Iterable.savedConfig, url, context);
enrichAndHandle(context);
}
});
}
Expand All @@ -1005,7 +1031,25 @@ export class Iterable {
(dict) => {
const action = IterableAction.fromDict(dict.action);
const context = IterableActionContext.fromDict(dict.context);
Iterable.savedConfig.customActionHandler!(action, context);

// When the action originates from a push notification, fetch the last
// push payload and attach it to the context so that custom action
// handlers can access custom push data.
if (context.source === IterableActionSource.push) {
Iterable.getLastPushPayload()
.then((payload) => {
if (payload && typeof payload === 'object') {
context.pushPayload = payload as Record<string, unknown>;
}
Iterable.savedConfig.customActionHandler!(action, context);
})
.catch(() => {
// If fetching the payload fails, proceed without it
Iterable.savedConfig.customActionHandler!(action, context);
});
} else {
Iterable.savedConfig.customActionHandler!(action, context);
}
}
);
}
Expand Down
22 changes: 22 additions & 0 deletions src/core/classes/IterableActionContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,28 @@ export class IterableActionContext {
*/
source: IterableActionSource;

/**
* The push notification payload, if the action originated from a push notification.
*
* This field is automatically populated when the action source is
* {@link IterableActionSource.push}. It contains the custom payload data
* from the push notification that triggered the action, allowing you to
* access campaign-specific metadata in your URL or custom action handlers.
*
* @example
* ```typescript
* const config = new IterableConfig();
* config.urlHandler = (url, context) => {
* if (context.pushPayload) {
* const promoCode = context.pushPayload.promoCode;
* // Use the custom payload data from the push notification
* }
* return true;
* };
* ```
*/
pushPayload?: Record<string, unknown>;

/**
* Creates an instance of IterableActionContext.
*/
Expand Down
Loading