> ## Documentation Index
> Fetch the complete documentation index at: https://boxo.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Events System

<Accordion title="Handle custom event from miniapp">
  The custom events system is a powerful feature that enables bidirectional data communication between a **miniapp** and the **host app**. The **miniapp** can send data that the **host app** can recognize. Additionally, certain operations can be implemented at the native app level for enhanced functionality.

  [Custom events example](/miniapp/CES)

  <Tabs>
    <Tab title="iOS">
      ```swift theme={"system"}
      miniapp.delegate = self
      ...
      extension ViewController : MiniappDelegate {
          func didReceiveCustomEvent(miniapp: Miniapp, customEvent: CustomEvent) {
              customEvent.payload = [
                  "message" : "text",
                  "id" : 123,
                  "checked" : true
              ]
              miniapp.sendCustomEvent(customEvent: customEvent)
          }
      }
      ```
    </Tab>

    <Tab title="Android">
      ```kotlin theme={"system"}
      miniApp.setCustomEventListener { _, miniapp, customEvent ->
          //doSomething
          customEvent.payload = mapOf("message" to "text",
                                      "id" to 123,
                                      "checked" to true)
          miniapp.sendEvent(customEvent)
      }
      ```

      **java**

      ```java theme={"system"}
      miniapp.setCustomEventListener(new Miniapp.CustomEventListener() {
          @Override
          public void handle(@NotNull BoxoFragment boxoFragment, @NotNull MiniApp miniapp, @NotNull CustomEvent customEvent) {
              Map<String, Object> payload = new HashMap<>();
              payload.put("message", "message");
              payload.put("id", 123);
              payload.put("checked", true);
              customEvent.setPayload(payload);
              miniapp.sendEvent(customEvent);
          }
      });
      ```
    </Tab>

    <Tab title="Flutter">
      Handle custom events by listening to `.customEvents()`.

      Example receiving and sending back same event:

      ```
      Appboxo.customEvents().listen((CustomEvent event) {
        if (event.appId == 'app123456') {
          event.payload = {"foo": "bar"};
          Appboxo.sendEvent(event);
        }
      });
      ```

      For cases when you want to hide all miniapps when a custom event is received, you can call `Appboxo.hideMiniapps()`;

      Example:

      ```clike theme={"system"}
      import 'package:flutter/material.dart';
      import 'package:appboxo_sdk/appboxo_sdk.dart';

      void main() => runApp(MyApp());

      class MyApp extends StatefulWidget {
        @override
        _MyAppState createState() => _MyAppState();
      }

      class _MyAppState extends State<MyApp> {
        @override
        void initState() {
          super.initState();
          Appboxo.setConfig("CLIENT_ID");
          Appboxo.customEvents().listen((CustomEvent event) {
            if (event.appId == 'app123456') {
              Appboxo.hideMiniapps();
              Future.delayed(const Duration(milliseconds: 2000), () {
                Appboxo.openMiniapp("app123456", "");
                event.payload = {"complete": "ok"};
                Appboxo.sendEvent(event);
              });
            }
          });
        }

        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            home: Scaffold(
              appBar: AppBar(
                title: const Text('Appboxo SDK Test'),
              ),
              body: Center(
                child: RaisedButton(
                  onPressed: () {
                    Appboxo.openMiniapp("app123456", "");
                  },
                  child: Text("Miniapp"),
                ),
              ),
            ),
          );
        }
      }
      ```
    </Tab>

    <Tab title="React Native">
      Handling custom events in React Native is straightforward. Use customEvents to both subscribe to and send custom events between the miniapp and the host app.

      Example:

      ```clike theme={"system"}
         appboxo.customEvents
            .subscribe<'eventType', { payloadKey: 'payloadData' }>(event => {
              const modifiedEvent = {
                app_id: '[miniap_id]', // miniapp id
                custom_event: {
                  error_type: undefined, // throw the error with non empty 'error_type'
                  payload: {payloadKey: 'payloadData'}, // payload data to send to miniapp
                  request_id: '1', // event requet id
                  type: 'eventType', // event type
                },
              }
              appboxo.customEvents.send(modifiedEvent) // your data that you want to send back to miniapp
            })
      ```

      > TIP
      >
      > Please don't forget to unsubscribe from events

      Usage:

      ```clike theme={"system"}
      import React from 'react';
      import appboxo from '@appboxo/react-native-sdk';
      import { StyleSheet, View, Button } from 'react-native';

      type eventType = 'eventType';
      type eventPayload = { payloadKey: 'payload' };

      export default function App() {

        React.useEffect(() => {
          appboxo.setConfig('[client_id]');  //set your Appboxo client_id

          const eventPayloadData = { payloadKey: 'payload' };

          const subscription = appboxo.customEvents
            .subscribe<eventType, eventPayload>( //listen custom event from miniapp
              event => {
                const modifiedEvent = {
                  app_id: '[miniap_id]', // miniapp id
                  custom_event: {
                    request_id: event.custom_event.request_id, // event requet id
                    payload: eventPayloadData, // payload data to send to miniapp
                    type: eventType, // event type
                  },
                };
                appboxo.customEvents.send(modifiedEvent); //send custom event to miniapp
              },
              (errorType?: string) => {
                console.error(errorType || 'Something went wrong!'); //handle error
              }     
            );

          return () => subscription(); //unsubscribe from custom events

        }, []);

        const handleOpenMiniapp = () => {
          appboxo.openMiniapp('[miniapp_id]', '[auth_payload]');  //launch miniapp by id with auth payload
        }

        return (
          <View style={styles.container}>
            <Button
              color="#841584"
              title="Launch miniapp"
              onPress={handleOpenMiniapp}
              accessibilityLabel="Launch miniapp"
            />
          </View>
        );
      }

      const styles = StyleSheet.create({
        container: {
          flex: 1,
          alignItems: 'center',
          backgroundColor: '#fff',
          justifyContent: 'center',
        },
      });
      ```
    </Tab>
  </Tabs>
</Accordion>

# Boxo Event Bridge

***

<Accordion title="Introduction">
  Boxo Event Bridge is a bidirectional communication functionality that enables host apps and miniapps to exchange events and information seamlessly within the Boxo ecosystem.

  ### Event Bridge flow

  Here is a sequence flow for event communication process between a miniapp and a host app.

  1. An app (either hostapp or miniapp) creates an event with a specific event type and payload
  2. The app sends the event to the Boxo Platform via the Event Bridge API
  3. The Boxo Platform validates the event and authenticates the sender
  4. The Boxo Platform forwards the event to the recipient's event receiver URL
  5. The recipient processes the event and returns a response
  6. The Boxo Platform captures the response and forwards it to the original sender
  7. The original sender receives the response and can take appropriate actions
</Accordion>

<Accordion title="Setting up the backend">
  \*Note: Feature must be enabled in [Dashboard](https://dashboard.boxo.io/host-apps/)

  **Data format**

  JSON is used for data exchange. Event payloads can contain any valid JSON structure that both the sender and receiver agree upon.

  <Accordion title="1. Event Receiver Endpoint">
    This endpoint allows your app to receive events from the Boxo Platform.

    **URL and METHOD:**

    This endpoint must handle a HTTPS POST request
    URL to endpoint must be provided in [Dashboard](https://dashboard.boxo.io/host-apps/)

    **Headers:**

    | Key             | Value                                                             |
    | --------------- | ----------------------------------------------------------------- |
    | `Authorization` | `<prefix> <base64 encoded(hostapp_client_id:hostapp_secret_key)>` |
    | `Content-type`  | `application/json`                                                |

    * Default `<prefix>`: `Token`. Access token prefix can be set in [Boxo Connect](https://dashboard.boxo.io/host-apps/).
    * `hostapp_client_id` and `hostapp_secret_key` must be provided in [Dashboard](https://dashboard.boxo.io/host-apps/)

    **Body**

    | Field        | Data type | Description                                             |
    | ------------ | --------- | ------------------------------------------------------- |
    | `app_id`     | String    | Miniapp identifier                                      |
    | `client_id`  | String    | Hostapp identifier                                      |
    | `event_type` | String    | Event type identifying the purpose of the event         |
    | `payload`    | Object    | Event data containing information specific to the event |

    **Response:**

    * Response status must be `200` in all cases
    * Response body can contain any valid JSON that will be forwarded to the event sender

    **Request Example:**

    ```
    curl --location --request POST '[YOUR_SERVER_URL]/api/event-receiver/'\
    --header 'Content-Type: application/json' \
    --header 'Authorization: Basic {{BASE64_ENCODED_CLIENT_ID_AND_CLIENT_SECRET}}' \
    --data-raw '{
        "app_id": "{{MINIAPP_ID}}",
        "client_id": "{{CLIENT_ID}}",
        "event_type": "user_profile_updated",
        "payload": {
            "user_id": "user123",
            "name": "John Doe",
            "email": "john@example.com"
        }
    }'
    ```
  </Accordion>

  <Accordion title="2. Sending Events API">
    This endpoint allows your app to send events to miniapps through the Boxo Platform.

    **URL and METHOD**

    This is HTTPS POST `/api/v1/events/hostapp/` endpoint

    **Headers**

    | Key             | Value                                                             |
    | --------------- | ----------------------------------------------------------------- |
    | `Authorization` | `<prefix> <base64 encoded(hostapp_client_id:hostapp_secret_key)>` |
    | `Content-type`  | `application/json`                                                |

    * Default `<prefix>`: `Token`. Access token prefix can be set in [Boxo Connect](https://dashboard.boxo.io/host-apps/).
    * `hostapp_client_id` and `hostapp_secret_key` must be provided in [Dashboard](https://dashboard.boxo.io/host-apps/)

    **Body**

    | Field               | Data type        | Description                                             |
    | ------------------- | ---------------- | ------------------------------------------------------- |
    | `app_id`            | String           | Miniapp identifier (recipient)                          |
    | `client_id`         | String           | Hostapp identifier (sender)                             |
    | `event_type`        | String           | Event type identifying the purpose of the event         |
    | `external_event_id` | String(Optional) | Event ID from Hostapp                                   |
    | `payload`           | Object           | Event data containing information specific to the event |

    **Response**

    * Response status will be `200` if the event was delivered successfully
    * Response body will contain the response from the miniapp's event receiver endpoint

    **Request Example**

    ```
    curl --location --request POST 'https://api.boxo.io/api/v1/events/hostapp/' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Basic {{BASE64_ENCODED_CLIENT_ID_AND_CLIENT_SECRET}}' \
    --data-raw '{
        "app_id": "{{MINIAPP_ID}}",
        "client_id": "{{CLIENT_ID}}",
        "event_type": "payment_completed",
        "payload": {
            "transaction_id": "tx_12345",
            "amount": 100.50,
            "currency": "USD",
            "status": "completed"
        }
    }'
    ```
  </Accordion>
</Accordion>

<Accordion title="Common Event Types">
  Here are some common event types that can be used for communication between host apps and miniapps:

  ### Host App to Miniapp Events

  | Event Type             | Description                               | Example Payload                                             |
  | ---------------------- | ----------------------------------------- | ----------------------------------------------------------- |
  | `user_profile_updated` | User profile information has been updated | `{"user_reference": "123", "email": "example@example.com"}` |

  ### Miniapp to Host App Events

  | Event Type            | Description                      | Example Payload                                                         |
  | --------------------- | -------------------------------- | ----------------------------------------------------------------------- |
  | `order_status_update` | Miniapp order fulfillment status | `{"order_payment_id": "order_123", "fulfillment_status": "delivering"}` |
</Accordion>

<Accordion title="Error Handling">
  If an error occurs during event processing, the Boxo Platform will return an appropriate error response:

  | Error Code                | Description                                     |
  | ------------------------- | ----------------------------------------------- |
  | `EVENT_RECEIVER_DISABLED` | Event receiver is not enabled for the recipient |
  | `INVALID_EVENT_DATA`      | The event data format is invalid                |
  | `EVENT_DELIVERY_FAILED`   | Failed to deliver the event to the recipient    |
  | `UNAUTHORIZED`            | Sender is not authorized to send events         |
</Accordion>

<Accordion title="Best Practices">
  1. **Event Types**: Use consistent event types that clearly indicate the purpose of the event
  2. **Minimal Payloads**: Keep event payloads as small as possible, including only necessary information
  3. **Error Handling**: Implement proper error handling for event processing failures
  4. **Idempotency**: Design event handlers to be idempotent to handle potential duplicate events
  5. **Timeouts**: Implement reasonable timeouts for event processing to avoid blocking operations

  By following these guidelines, you can create a robust event-driven communication system between your host app and miniapps using Boxo Event Bridge.
</Accordion>
