From 760a9e38950623cd0c9b6192c10bfa2e472cf0ce Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Mon, 13 Oct 2025 11:18:08 -0700 Subject: [PATCH 1/3] feat: add syncEmbeddedMessages method --- .../reactnative/RNIterableAPIModuleImpl.java | 5 ++++ .../newarch/java/com/RNIterableAPIModule.java | 5 ++++ .../oldarch/java/com/RNIterableAPIModule.java | 5 ++++ example/src/components/Embedded/Embedded.tsx | 8 +++++++ src/api/NativeRNIterableAPI.ts | 1 + src/core/classes/IterableApi.ts | 8 +++++++ .../classes/IterableEmbeddedManager.ts | 23 +++++++++++++++++++ 7 files changed, 55 insertions(+) diff --git a/android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java b/android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java index ece9d8737..0d332fddf 100644 --- a/android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java +++ b/android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java @@ -651,6 +651,11 @@ public void onInboxUpdated() { // --------------------------------------------------------------------------------------- // region Embedded messaging + public void syncEmbeddedMessages() { + IterableLogger.d(TAG, "syncEmbeddedMessages"); + IterableApi.getInstance().getEmbeddedManager().syncMessages(); + } + public void startEmbeddedSession() { IterableLogger.d(TAG, "startEmbeddedSession"); IterableApi.getInstance().getEmbeddedManager().getEmbeddedSessionManager().startSession(); diff --git a/android/src/newarch/java/com/RNIterableAPIModule.java b/android/src/newarch/java/com/RNIterableAPIModule.java index 4c67af4e5..ceb653958 100644 --- a/android/src/newarch/java/com/RNIterableAPIModule.java +++ b/android/src/newarch/java/com/RNIterableAPIModule.java @@ -224,6 +224,11 @@ public void pauseAuthRetries(boolean pauseRetry) { moduleImpl.pauseAuthRetries(pauseRetry); } + @Override + public void syncEmbeddedMessages() { + moduleImpl.syncEmbeddedMessages(); + } + @Override public void startEmbeddedSession() { moduleImpl.startEmbeddedSession(); diff --git a/android/src/oldarch/java/com/RNIterableAPIModule.java b/android/src/oldarch/java/com/RNIterableAPIModule.java index 868f4051d..6ce874896 100644 --- a/android/src/oldarch/java/com/RNIterableAPIModule.java +++ b/android/src/oldarch/java/com/RNIterableAPIModule.java @@ -228,6 +228,11 @@ public void pauseAuthRetries(boolean pauseRetry) { moduleImpl.pauseAuthRetries(pauseRetry); } + @ReactMethod + public void syncEmbeddedMessages() { + moduleImpl.syncEmbeddedMessages(); + } + @ReactMethod public void startEmbeddedSession() { moduleImpl.startEmbeddedSession(); diff --git a/example/src/components/Embedded/Embedded.tsx b/example/src/components/Embedded/Embedded.tsx index efedac721..7f92c154c 100644 --- a/example/src/components/Embedded/Embedded.tsx +++ b/example/src/components/Embedded/Embedded.tsx @@ -6,6 +6,11 @@ import styles from './Embedded.styles'; export const Embedded = () => { const [placementIds, setPlacementIds] = useState([]); + + const syncEmbeddedMessages = useCallback(() => { + Iterable.embeddedManager.syncMessages(); + }, []); + const getPlacementIds = useCallback(() => { Iterable.embeddedManager.getPlacementIds().then((ids: unknown) => { console.log(ids); @@ -40,6 +45,9 @@ export const Embedded = () => { Placement ids: [{placementIds.join(', ')}] + + Sync embedded messages + Get placement ids diff --git a/src/api/NativeRNIterableAPI.ts b/src/api/NativeRNIterableAPI.ts index 931be6f29..f6c1249e5 100644 --- a/src/api/NativeRNIterableAPI.ts +++ b/src/api/NativeRNIterableAPI.ts @@ -119,6 +119,7 @@ export interface Spec extends TurboModule { pauseAuthRetries(pauseRetry: boolean): void; // Embedded Messaging + syncEmbeddedMessages(): void; startEmbeddedSession(): void; endEmbeddedSession(): void; getEmbeddedPlacementIds(): Promise; diff --git a/src/core/classes/IterableApi.ts b/src/core/classes/IterableApi.ts index 84c8f3a7a..9f6c90ec7 100644 --- a/src/core/classes/IterableApi.ts +++ b/src/core/classes/IterableApi.ts @@ -510,6 +510,14 @@ export class IterableApi { // ======================= EMBEDDED ===================== // // ====================================================== // + /** + * Syncs embedded local cache with the server. + */ + static syncEmbeddedMessages() { + IterableLogger.log('syncEmbeddedMessages'); + return RNIterableAPI.syncEmbeddedMessages(); + } + /** * Starts an embedded session. */ diff --git a/src/embedded/classes/IterableEmbeddedManager.ts b/src/embedded/classes/IterableEmbeddedManager.ts index 5515cb6ab..5a31284ff 100644 --- a/src/embedded/classes/IterableEmbeddedManager.ts +++ b/src/embedded/classes/IterableEmbeddedManager.ts @@ -20,6 +20,29 @@ export class IterableEmbeddedManager { */ isEnabled = false; + /** + * Syncs embedded local cache with the server. + * + * When your app first launches, and each time it comes to the foreground, + * Iterable's iOS SDK automatically refresh a local, on-device cache of + * embedded messages for the signed-in user. These are the messages the + * signed-in user is eligible to see. + * + * At key points during your app's lifecycle, you may want to manually refresh + * your app's local cache of embedded messages. For example, as users navigate + * around, on pull-to-refresh, etc. + * + * However, do not poll for new embedded messages at a regular interval. + * + * @example + * ```typescript + * IterableEmbeddedManager.syncMessages(); + * ``` + */ + syncMessages() { + return IterableApi.syncEmbeddedMessages(); + } + /** * Retrieves a list of placement IDs for the embedded manager. * From 1986caa0442ee36e657e875dce788c81f7763edd Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Mon, 13 Oct 2025 12:24:15 -0700 Subject: [PATCH 2/3] feat: implement getEmbeddedMessages method and add example on embedded --- .../reactnative/RNIterableAPIModuleImpl.java | 35 ++++++++ .../iterable/reactnative/Serialization.java | 11 +++ .../newarch/java/com/RNIterableAPIModule.java | 5 ++ .../oldarch/java/com/RNIterableAPIModule.java | 5 ++ example/src/components/Embedded/Embedded.tsx | 81 +++++++++++++------ src/api/NativeRNIterableAPI.ts | 30 +++++++ src/core/classes/IterableApi.ts | 13 +++ .../classes/IterableEmbeddedManager.ts | 13 +++ src/embedded/index.ts | 1 + src/embedded/types/IterableEmbeddedMessage.ts | 14 ++++ .../types/IterableEmbeddedMessageElements.ts | 25 ++++++ .../IterableEmbeddedMessageElementsButton.ts | 10 +++ .../IterableEmbeddedMessageElementsText.ts | 8 ++ .../types/IterableEmbeddedMessageMetadata.ts | 19 +++++ src/embedded/types/index.ts | 5 ++ src/index.tsx | 5 +- 16 files changed, 255 insertions(+), 25 deletions(-) create mode 100644 src/embedded/types/IterableEmbeddedMessage.ts create mode 100644 src/embedded/types/IterableEmbeddedMessageElements.ts create mode 100644 src/embedded/types/IterableEmbeddedMessageElementsButton.ts create mode 100644 src/embedded/types/IterableEmbeddedMessageElementsText.ts create mode 100644 src/embedded/types/IterableEmbeddedMessageMetadata.ts create mode 100644 src/embedded/types/index.ts diff --git a/android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java b/android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java index 0d332fddf..61781ecd2 100644 --- a/android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java +++ b/android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java @@ -683,6 +683,41 @@ public void getEmbeddedPlacementIds(Promise promise) { } } + public void getEmbeddedMessages(@Nullable ReadableArray placementIds, Promise promise) { + IterableLogger.d(TAG, "getEmbeddedMessages for placements: " + placementIds); + + try { + List allMessages = new ArrayList<>(); + + if (placementIds == null || placementIds.size() == 0) { + // If no placement IDs provided, we need to get messages for all possible placements + // Since the Android SDK requires a placement ID, we'll use 0 as a default + // This might need to be adjusted based on the actual SDK behavior + List messages = IterableApi.getInstance().getEmbeddedManager().getMessages(0L); + if (messages != null) { + allMessages.addAll(messages); + } + } else { + // Convert ReadableArray to individual placement IDs and get messages for each + for (int i = 0; i < placementIds.size(); i++) { + long placementId = placementIds.getInt(i); + List messages = IterableApi.getInstance().getEmbeddedManager().getMessages(placementId); + if (messages != null) { + allMessages.addAll(messages); + } + } + } + + JSONArray embeddedMessageJsonArray = Serialization.serializeEmbeddedMessages(allMessages); + IterableLogger.d(TAG, "Messages for placements: " + embeddedMessageJsonArray); + + promise.resolve(Serialization.convertJsonToArray(embeddedMessageJsonArray)); + } catch (JSONException e) { + IterableLogger.e(TAG, e.getLocalizedMessage()); + promise.reject("", "Failed to fetch messages with error " + e.getLocalizedMessage()); + } + } + // --------------------------------------------------------------------------------------- // endregion } diff --git a/android/src/main/java/com/iterable/reactnative/Serialization.java b/android/src/main/java/com/iterable/reactnative/Serialization.java index bace4c16c..2f0c4e1ca 100644 --- a/android/src/main/java/com/iterable/reactnative/Serialization.java +++ b/android/src/main/java/com/iterable/reactnative/Serialization.java @@ -138,6 +138,17 @@ static JSONArray serializeInAppMessages(List inAppMessages return inAppMessagesJson; } + static JSONArray serializeEmbeddedMessages(List embeddedMessages) { + JSONArray embeddedMessagesJson = new JSONArray(); + if (embeddedMessages != null) { + for (IterableEmbeddedMessage message : embeddedMessages) { + JSONObject messageJson = IterableEmbeddedMessage.Companion.toJSONObject(message); + embeddedMessagesJson.put(messageJson); + } + } + return embeddedMessagesJson; + } + static IterableConfig.Builder getConfigFromReadableMap(ReadableMap iterableContextMap) { try { JSONObject iterableContextJSON = convertMapToJson(iterableContextMap); diff --git a/android/src/newarch/java/com/RNIterableAPIModule.java b/android/src/newarch/java/com/RNIterableAPIModule.java index ceb653958..ade1996f6 100644 --- a/android/src/newarch/java/com/RNIterableAPIModule.java +++ b/android/src/newarch/java/com/RNIterableAPIModule.java @@ -244,6 +244,11 @@ public void getEmbeddedPlacementIds(Promise promise) { moduleImpl.getEmbeddedPlacementIds(promise); } + @Override + public void getEmbeddedMessages(@Nullable ReadableArray placementIds, Promise promise) { + moduleImpl.getEmbeddedMessages(placementIds, promise); + } + public void sendEvent(@NonNull String eventName, @Nullable Object eventData) { moduleImpl.sendEvent(eventName, eventData); } diff --git a/android/src/oldarch/java/com/RNIterableAPIModule.java b/android/src/oldarch/java/com/RNIterableAPIModule.java index 6ce874896..468c2e4e4 100644 --- a/android/src/oldarch/java/com/RNIterableAPIModule.java +++ b/android/src/oldarch/java/com/RNIterableAPIModule.java @@ -248,6 +248,11 @@ public void getEmbeddedPlacementIds(Promise promise) { moduleImpl.getEmbeddedPlacementIds(promise); } + @ReactMethod + public void getEmbeddedMessages(@Nullable ReadableArray placementIds, Promise promise) { + moduleImpl.getEmbeddedMessages(placementIds, promise); + } + public void sendEvent(@NonNull String eventName, @Nullable Object eventData) { moduleImpl.sendEvent(eventName, eventData); } diff --git a/example/src/components/Embedded/Embedded.tsx b/example/src/components/Embedded/Embedded.tsx index 7f92c154c..a824a3f24 100644 --- a/example/src/components/Embedded/Embedded.tsx +++ b/example/src/components/Embedded/Embedded.tsx @@ -1,20 +1,27 @@ import { Text, TouchableOpacity, View } from 'react-native'; import { useCallback, useState } from 'react'; -import { Iterable } from '@iterable/react-native-sdk'; +import { + Iterable, + type IterableEmbeddedMessage, +} from '@iterable/react-native-sdk'; import styles from './Embedded.styles'; export const Embedded = () => { const [placementIds, setPlacementIds] = useState([]); + const [embeddedMessages, setEmbeddedMessages] = useState< + IterableEmbeddedMessage[] + >([]); const syncEmbeddedMessages = useCallback(() => { Iterable.embeddedManager.syncMessages(); }, []); const getPlacementIds = useCallback(() => { - Iterable.embeddedManager.getPlacementIds().then((ids: unknown) => { + return Iterable.embeddedManager.getPlacementIds().then((ids: unknown) => { console.log(ids); setPlacementIds(ids as number[]); + return ids; }); }, []); @@ -32,31 +39,57 @@ export const Embedded = () => { Iterable.embeddedManager.endSession(); }, []); + const getEmbeddedMessages = useCallback(() => { + getPlacementIds() + .then((ids: number[]) => Iterable.embeddedManager.getMessages(ids)) + .then((messages: IterableEmbeddedMessage[]) => { + setEmbeddedMessages(messages); + console.log(messages); + }); + }, [getPlacementIds]); + return ( EMBEDDED - - Does embedded class exist? {Iterable.embeddedManager ? 'Yes' : 'No'} - - - Is embedded manager enabled? - {Iterable.embeddedManager.isEnabled ? 'Yes' : 'No'} - - - Placement ids: [{placementIds.join(', ')}] - - - Sync embedded messages - - - Get placement ids - - - Start embedded session - - - End embedded session - + + + Does embedded class exist? {Iterable.embeddedManager ? 'Yes' : 'No'} + + + Is embedded manager enabled? + {Iterable.embeddedManager.isEnabled ? 'Yes' : 'No'} + + + Placement ids: [{placementIds.join(', ')}] + + + Sync embedded messages + + + Get placement ids + + + Start embedded session + + + End embedded session + + + Get embedded messages + + + + + {embeddedMessages.map((message) => ( + + Embedded message + metadata.messageId: {message.metadata.messageId} + metadata.placementId: {message.metadata.placementId} + elements.title: {message.elements?.title} + elements.body: {message.elements?.body} + + ))} + ); }; diff --git a/src/api/NativeRNIterableAPI.ts b/src/api/NativeRNIterableAPI.ts index f6c1249e5..a9b32a400 100644 --- a/src/api/NativeRNIterableAPI.ts +++ b/src/api/NativeRNIterableAPI.ts @@ -1,6 +1,33 @@ import type { TurboModule } from 'react-native'; import { TurboModuleRegistry } from 'react-native'; +// NOTE: No types can be imported because of the way new arch works, so we have +// to re-define the types here. +interface EmbeddedMessage { + metadata: { + messageId: string; + placementId: number; + campaignId?: number | null; + isProof?: boolean; + }; + elements: { + buttons?: + | { + id: string; + title?: string | null; + action: { type: string; data?: string } | null; + }[] + | null; + body?: string | null; + mediaUrl?: string | null; + mediaUrlCaption?: string | null; + defaultAction?: { type: string; data?: string } | null; + text?: { id: string; text?: string | null; label?: string | null }[] | null; + title?: string | null; + } | null; + payload?: { [key: string]: string | number | boolean | null } | null; +} + export interface Spec extends TurboModule { // Initialization initializeWithApiKey( @@ -123,6 +150,9 @@ export interface Spec extends TurboModule { startEmbeddedSession(): void; endEmbeddedSession(): void; getEmbeddedPlacementIds(): Promise; + getEmbeddedMessages( + placementIds: number[] | null + ): Promise; // Wake app -- android only wakeApp(): void; diff --git a/src/core/classes/IterableApi.ts b/src/core/classes/IterableApi.ts index 9f6c90ec7..52f54db80 100644 --- a/src/core/classes/IterableApi.ts +++ b/src/core/classes/IterableApi.ts @@ -12,6 +12,7 @@ import { IterableAttributionInfo } from './IterableAttributionInfo'; import type { IterableCommerceItem } from './IterableCommerceItem'; import { IterableConfig } from './IterableConfig'; import { IterableLogger } from './IterableLogger'; +import type { IterableEmbeddedMessage } from '../../embedded/types/IterableEmbeddedMessage'; /** * Contains functions that directly interact with the native layer. @@ -542,6 +543,18 @@ export class IterableApi { return RNIterableAPI.getEmbeddedPlacementIds(); } + /** + * Get the embedded messages. + * + * @returns A Promise that resolves to an array of embedded messages. + */ + static getEmbeddedMessages( + placementIds: number[] | null + ): Promise { + IterableLogger.log('getEmbeddedMessages: ', placementIds); + return RNIterableAPI.getEmbeddedMessages(placementIds); + } + // ---- End EMBEDDED ---- // // ====================================================== // diff --git a/src/embedded/classes/IterableEmbeddedManager.ts b/src/embedded/classes/IterableEmbeddedManager.ts index 5a31284ff..1e2806e68 100644 --- a/src/embedded/classes/IterableEmbeddedManager.ts +++ b/src/embedded/classes/IterableEmbeddedManager.ts @@ -1,4 +1,5 @@ import { IterableApi } from '../../core/classes/IterableApi'; +import type { IterableEmbeddedMessage } from '../types/IterableEmbeddedMessage'; /** * Manages embedded messages from Iterable. @@ -52,6 +53,18 @@ export class IterableEmbeddedManager { return IterableApi.getEmbeddedPlacementIds(); } + /** + * Retrieves a list of embedded messages the user is eligible to see. + * + * @param placementIds - The placement IDs to retrieve messages for. + * @returns A Promise that resolves to an array of embedded messages. + */ + getMessages( + placementIds: number[] | null + ): Promise { + return IterableApi.getEmbeddedMessages(placementIds); + } + /** * Starts a session. * diff --git a/src/embedded/index.ts b/src/embedded/index.ts index d7d17c691..15eb796c9 100644 --- a/src/embedded/index.ts +++ b/src/embedded/index.ts @@ -1 +1,2 @@ export * from './classes'; +export * from './types'; diff --git a/src/embedded/types/IterableEmbeddedMessage.ts b/src/embedded/types/IterableEmbeddedMessage.ts new file mode 100644 index 000000000..2f0778305 --- /dev/null +++ b/src/embedded/types/IterableEmbeddedMessage.ts @@ -0,0 +1,14 @@ +import type { IterableEmbeddedMessageElements } from './IterableEmbeddedMessageElements'; +import type { IterableEmbeddedMessageMetadata } from './IterableEmbeddedMessageMetadata'; + +/** + * An embedded message. + */ +export interface IterableEmbeddedMessage { + /** Identifying information about the campaign. */ + metadata: IterableEmbeddedMessageMetadata; + /** What to display, and how to handle interaction. */ + elements?: IterableEmbeddedMessageElements | null; + /** Custom JSON data included with the campaign. */ + payload?: Record | null; +} diff --git a/src/embedded/types/IterableEmbeddedMessageElements.ts b/src/embedded/types/IterableEmbeddedMessageElements.ts new file mode 100644 index 000000000..7eb41056f --- /dev/null +++ b/src/embedded/types/IterableEmbeddedMessageElements.ts @@ -0,0 +1,25 @@ +import type { IterableAction } from '../../core/classes/IterableAction'; +import type { IterableEmbeddedMessageElementsButton } from './IterableEmbeddedMessageElementsButton'; +import type { IterableEmbeddedMessageElementsText } from './IterableEmbeddedMessageElementsText'; + +/** + * The elements of an embedded message. + * + * Includes what to display, and how to handle interaction. + */ +export interface IterableEmbeddedMessageElements { + /** The message's title text. */ + title?: string | null; + /** The message's body text. */ + body?: string | null; + /** The URL of an image associated with the message. */ + mediaUrl?: string | null; + /** Text description of the image. */ + mediaUrlCaption?: string | null; + /** What to do when a user clicks on the message (outside of its buttons). */ + defaultAction?: IterableAction | null; + /** Buttons to display. */ + buttons?: IterableEmbeddedMessageElementsButton[] | null; + /** Extra data fields. Not for display. */ + text?: IterableEmbeddedMessageElementsText[] | null; +} diff --git a/src/embedded/types/IterableEmbeddedMessageElementsButton.ts b/src/embedded/types/IterableEmbeddedMessageElementsButton.ts new file mode 100644 index 000000000..785d5932d --- /dev/null +++ b/src/embedded/types/IterableEmbeddedMessageElementsButton.ts @@ -0,0 +1,10 @@ +import type { IterableAction } from '../../core/classes/IterableAction'; + +export interface IterableEmbeddedMessageElementsButton { + /** The ID. */ + id: string; + /** The title. */ + title?: string | null; + /** The action. */ + action?: IterableAction | null; +} diff --git a/src/embedded/types/IterableEmbeddedMessageElementsText.ts b/src/embedded/types/IterableEmbeddedMessageElementsText.ts new file mode 100644 index 000000000..00b6a8449 --- /dev/null +++ b/src/embedded/types/IterableEmbeddedMessageElementsText.ts @@ -0,0 +1,8 @@ +export interface IterableEmbeddedMessageElementsText { + /** The ID. */ + id: string; + /** The text. */ + text?: string | null; + /** The label. */ + label?: string | null; +} diff --git a/src/embedded/types/IterableEmbeddedMessageMetadata.ts b/src/embedded/types/IterableEmbeddedMessageMetadata.ts new file mode 100644 index 000000000..a4b5ff953 --- /dev/null +++ b/src/embedded/types/IterableEmbeddedMessageMetadata.ts @@ -0,0 +1,19 @@ +/** + * Metadata for an embedded message. + * + * Consists of identifying information about the campaign. + */ +export interface IterableEmbeddedMessageMetadata { + /** The ID of the message. */ + messageId: string; + /** The ID of the placement associated with the message. */ + placementId: number; + /** The ID of the campaign associated with the message. */ + campaignId?: number | null; + /** + * Whether the message is a proof/test message. + * + * EG: Sent directly from a template or campaign edit page. + */ + isProof?: boolean; +} diff --git a/src/embedded/types/index.ts b/src/embedded/types/index.ts new file mode 100644 index 000000000..29b809ebf --- /dev/null +++ b/src/embedded/types/index.ts @@ -0,0 +1,5 @@ +export * from './IterableEmbeddedMessage'; +export * from './IterableEmbeddedMessageElements'; +export * from './IterableEmbeddedMessageElementsButton'; +export * from './IterableEmbeddedMessageElementsText'; +export * from './IterableEmbeddedMessageMetadata'; diff --git a/src/index.tsx b/src/index.tsx index c9a014340..75c8489ec 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -59,4 +59,7 @@ export { type IterableInboxProps, type IterableInboxRowViewModel, } from './inbox'; -export { IterableEmbeddedManager } from './embedded'; +export { + IterableEmbeddedManager, + type IterableEmbeddedMessage, +} from './embedded'; From 94e46a647c737151e1dc56ed5ffde73090270cb9 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Mon, 13 Oct 2025 12:30:35 -0700 Subject: [PATCH 3/3] feat: enhance Embedded component with ScrollView and button details display --- example/src/components/Embedded/Embedded.tsx | 36 +++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/example/src/components/Embedded/Embedded.tsx b/example/src/components/Embedded/Embedded.tsx index a824a3f24..2be959133 100644 --- a/example/src/components/Embedded/Embedded.tsx +++ b/example/src/components/Embedded/Embedded.tsx @@ -1,4 +1,4 @@ -import { Text, TouchableOpacity, View } from 'react-native'; +import { ScrollView, Text, TouchableOpacity, View } from 'react-native'; import { useCallback, useState } from 'react'; import { Iterable, @@ -79,17 +79,29 @@ export const Embedded = () => { - - {embeddedMessages.map((message) => ( - - Embedded message - metadata.messageId: {message.metadata.messageId} - metadata.placementId: {message.metadata.placementId} - elements.title: {message.elements?.title} - elements.body: {message.elements?.body} - - ))} - + + + {embeddedMessages.map((message) => ( + + Embedded message + metadata.messageId: {message.metadata.messageId} + metadata.placementId: {message.metadata.placementId} + elements.title: {message.elements?.title} + elements.body: {message.elements?.body} + {(message.elements?.buttons ?? []).map((button, buttonIndex) => ( + + Button {buttonIndex + 1} + button.id: {button.id} + button.title: {button.title} + button.action?.data: {button.action?.data} + button.action?.type: {button.action?.type} + + ))} + payload: {JSON.stringify(message.payload)} + + ))} + + ); };