# In-App Message Event Listener

{% hint style="info" %}
This feature is supported in React Native SDK version 3.15.0 and above.
{% endhint %}

## Interfaces

### HackleInAppMessageListener

```typescript
interface HackleInAppMessageListener {
  beforeInAppMessageOpen?(inAppMessage: HackleInAppMessage): void;
  afterInAppMessageOpen?(inAppMessage: HackleInAppMessage): void;
  beforeInAppMessageClose?(inAppMessage: HackleInAppMessage): void;
  afterInAppMessageClose?(inAppMessage: HackleInAppMessage): void;
  onInAppMessageClick?(
    inAppMessage: HackleInAppMessage,
    view: HackleInAppMessageView,
    action: HackleInAppMessageAction
  ): boolean;
}
```

#### onInAppMessageClick

You can control the behavior of the in-app message through the boolean value returned by the `onInAppMessageClick` method.

* Returning `true` overrides the original action of the in-app message.
  * For example, if the original click action was `Do not show for a day`, that action will not execute.
* Returning `false` allows the original action of the in-app message to proceed.

{% hint style="warning" %}
Calling `view.close()` inside `onInAppMessageClick`

Calling `view.close()` inside the listener is treated the same as returning `true`.

```typescript
onInAppMessageClick(inAppMessage, view, action) {
  view.close();

  // return false를 하더라도 true한 것과 동일하게 처리됨.
  return true;
},
```

{% endhint %}

### HackleInAppMessage

```typescript
interface HackleInAppMessage {
  key: number;
}
```

* Returns the key of the in-app message.

### HackleInAppMessageView

```typescript
interface HackleInAppMessageView {
  close(): void;
}
```

* You can close the in-app message directly within the listener function by calling `close()`.

### HackleInAppMessageAction

```typescript
type HackleInAppMessageActionType = 'CLOSE' | 'LINK';

interface HackleInAppMessageAction {
  type: HackleInAppMessageActionType;
  close?: {
    hideDurationMillis: number | null;
  };
  link?: {
    url: string;
    shouldCloseAfterLink: boolean;
  };
}

```

<table><thead><tr><th width="250">property</th><th>description</th></tr></thead><tbody><tr><td><code>close?.hideDurationMillis</code></td><td>If the action hides the message for a specific period, returns that duration in milliseconds.</td></tr><tr><td><code>link?.url</code></td><td>Returns the link if one is included. e.g) https://hackle.io</td></tr><tr><td><code>link?.shouldCloseAfterLink</code></td><td>Returns true if the close-after-link option is <code>ON</code>.</td></tr></tbody></table>

## Usage Example

### Registering a Listener

```typescript
hackleClient.setInAppMessageListener({
  beforeInAppMessageOpen(inAppMessage) {
    console.log('beforeInAppMessageOpen key:', inAppMessage.key);
  },
  afterInAppMessageOpen(inAppMessage) {
    console.log('afterInAppMessageOpen key:', inAppMessage.key);
  },
  beforeInAppMessageClose(inAppMessage) {
    console.log('beforeInAppMessageClose key:', inAppMessage.key);
  },
  afterInAppMessageClose(inAppMessage) {
    console.log('afterInAppMessageClose key:', inAppMessage.key);
  },
  onInAppMessageClick(inAppMessage, view, action) {
    console.log('onInAppMessageClick inAppMessage:', inAppMessage.key);
    console.log('onInAppMessageClick action:', action);
    view.close();
    return true;
  },
});
```

### Removing a Listener

* Pass `null` to `setInAppMessageListener()` to remove the registered listener.

```typescript
hackleClient.setInAppMessageListener(null);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hackle.io/en/development-guide/react-native/react-native-in-app-message-listener.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
