# Ultron SDK

Ultron SDK for integrating AI features into your web application.

## Installation

To install the package, use npm:

```
npm install ultronai
```

### Methods Documentation

#### `initUltronAI(divId: string, iframeLink: string, loadingElementId: string): void`

Initializes the Ultron AI by embedding an iframe into the specified div.

- `divId`: The ID of the div where the iframe should be embedded.
- `iframeLink`: The URL of the iframe content.
- `loadingElementId`: The ID of the loading element to be hidden once the iframe is loaded.

#### `sendMessageContent(iframe: HTMLIFrameElement, message: string, speak: boolean, lipsync: boolean, url: string): void`

Sends a text message to the iframe.

- `iframe`: The iframe element.
- `message`: The text message to send.
- `speak`: Whether the message should be spoken.
- `lipsync`: Whether lipsync should be enabled.
- `url`: The URL of the iframe content.

#### `sendSubmitEvent(iframe: HTMLIFrameElement, url: string): void`

Sends a submit event to the iframe.

- `iframe`: The iframe element.
- `url`: The URL of the iframe content.

#### `sendAudioMessage(iframe: HTMLIFrameElement, audioData: string, url: string): void`

Sends an audio message to the iframe.

- `iframe`: The iframe element.
- `audioData`: The audio data to send.
- `url`: The URL of the iframe content.

#### `sendAudioUrlMessage(iframe: HTMLIFrameElement, audioUrl: string, url: string): void`

Sends an audio URL message to the iframe.

- `iframe`: The iframe element.
- `audioUrl`: The URL of the audio to send.
- `url`: The URL of the iframe content.

#### `setupMessageListener(iframe: HTMLIFrameElement, iframeLink: string, callback: (data: any) => void): void`

Sets up a message listener to receive messages from the iframe.

- `iframe`: The iframe element.
- `iframeLink`: The URL of the iframe content.
- `callback`: The callback function to handle the received messages.

### Iframe Messages

When using the package, you can receive the following messages from the iframe:

1. `{type: "avatarLoaded"}`

   - Indicates that the avatar has been successfully loaded.

2. `{type: "avatarSpeaking", message: <text>, status: "started"}`

   - Indicates that the avatar has started speaking the provided message.

3. `{type: "error", message: "Unauthorized request: Session not found", status: 401}`

   - Indicates that the session was not found and the request is unauthorized.

4. `{type: "error", message: "Unauthorized request: Session expired", status: 401}`
   - Indicates that the session has expired and the request is unauthorized.

## Usage

To use the package, import the necessary functions in your TypeScript or JavaScript file:

```typescript
import {
  initUltronAI,
  sendMessageContent,
  sendSubmitEvent,
  sendAudioMessage,
  setupMessageListener,
  sendAudioUrlMessage,
} from "ultronai";
```

### Initializing Ultron AI

To initialize the Ultron AI, call the `initUltronAI` function with the ID of the div where the iframe should be embedded, the link to the iframe content, and the ID of the loading element:

```typescript
const sessionId = "created_with_ultron_api"; // please refer docs.ultronai.me
initUltronAI(
  "metabrix-labs",
  `https://app.ultronai.me/chat/?avatarId=xxxx&sessionId=${sessionId}`,
  "metabrix-loader"
);
```

### Sending Messages

You can send messages to the iframe using the provided functions:

```typescript
const iframe = document.getElementById("metabrix-labs").querySelector("iframe");

// Send a text message
sendMessageContent(
  iframe,
  "Hello, Ultron!",
  true,
  false,
  "https://app.ultronai.me"
);

// Send a submit event
sendSubmitEvent(iframe, "https://app.ultronai.me");

// Send an audio URL message
sendAudioUrlMessage(
  iframe,
  "https://example.com/audio.mp3",
  "https://app.ultronai.me"
);
```

## Example Usage

```typescript
import { useEffect, useState, useRef } from "react";
import "./App.css";
import {
  initUltronAI,
  sendMessageContent,
  sendSubmitEvent,
  sendAudioMessage,
  setupMessageListener,
  sendAudioUrlMessage,
} from "ultronai";

function App() {
  const [count, setCount] = useState(0);
  const [message, setMessage] = useState("");
  const [audioData, setAudioData] = useState<string | null>(null);
  const [iframeMessage, setIframeMessage] = useState<any>(null);
  const iframeRef = useRef<HTMLIFrameElement | null>(null);

  useEffect(() => {
    const urlParams = new URLSearchParams(window.location.search);
    const sessionId = urlParams.get("sessionId");
    console.log("sessionId:", sessionId);

    const timer = setTimeout(() => {
      initUltronAI(
        "metabrix",
        `https://app.ultronai.me/chat/?avatarId=xxxx&sessionId=${sessionId}`,
        "metabrix-loader"
      );
      iframeRef.current = document.querySelector("#metabrix iframe");

      if (iframeRef.current) {
        setupMessageListener(
          iframeRef.current,
          iframeRef.current.src,
          setIframeMessage
        );
      }
    }, 2000);

    return () => clearTimeout(timer);
  }, []);
  const handleSendMessage = () => {
    if (iframeRef.current) {
      const userInteracted =
        document.body.classList.contains("user-interacted");
      if (userInteracted) {
        const finalMessage =
          message || "Hello, this is a metabrix test message";
        sendMessageContent(
          iframeRef.current,
          finalMessage,
          true,
          true,
          iframeRef.current.src
        );
      } else {
        alert("Please interact with the page first.");
      }
    }
  };

  const handleSendSubmitEvent = () => {
    if (iframeRef.current) {
      sendSubmitEvent(iframeRef.current, iframeRef.current.src);
    }
  };

  const handleSendAudioUrlMessage = () => {
    if (iframeRef.current && audioUrl) {
      sendAudioUrlMessage(iframeRef.current, audioUrl, iframeRef.current.src);
    } else {
      alert("Please enter an audio URL first.");
    }
  };

  const handleAudioUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (file) {
      const reader = new FileReader();
      reader.onload = (e) => {
        const audioData = e.target?.result as string;
        setAudioData(audioData);
        if (iframeRef.current) {
          sendAudioMessage(iframeRef.current, audioData, iframeRef.current.src);
        }
      };
      reader.readAsDataURL(file);
    }
  };

  useEffect(() => {
    const handleUserInteraction = () => {
      document.body.classList.add("user-interacted");
    };

    document.addEventListener("click", handleUserInteraction);
    document.addEventListener("keydown", handleUserInteraction);

    return () => {
      document.removeEventListener("click", handleUserInteraction);
      document.removeEventListener("keydown", handleUserInteraction);
    };
  }, []);

  useEffect(() => {
    handleSendMessage();
  }, [message]);

  useEffect(() => {
    console.log("iframeMessage", iframeMessage);
  }, [iframeMessage]);

  return (
    <div className="app-container">
      <h2>SDK demo</h2>
      <div className="iframe-container">
        <div id="metabrix" className="iframe-wrapper">
        <div id="metabrix-loader" className=""></div>
        </div>
      </div>
      <div className="controls-container">
        <input
          type="text"
          placeholder="Enter your message"
          value={message}
          onChange={(e) => setMessage(e.target.value)}
          className="input-field"
        />
        <input
          type="file"
          accept="audio/*"
          onChange={handleAudioUpload}
          className="input-field"
        />
        <input
          type="text"
          placeholder="Enter audio URL"
          value={audioUrl}
          onChange={(e) => setAudioUrl(e.target.value)}
          className="input-field"
        />
        <button onClick={handleSendAudioUrlMessage} className="button">
          Send Audio URL Message
        </button>
        {/* <button onClick={handleSendMessage} className="button">Send Message</button> */}
        <button onClick={handleSendSubmitEvent} className="button">
          Send Submit Event
        </button>
        {/* <button onClick={handleSendAudioMessage} className="button">Send Audio Message</button> */}
      </div>
      {iframeMessage && (
        <div className="message-container">
          <h3>Message from iframe:</h3>
          <pre>{JSON.stringify(iframeMessage, null, 2)}</pre>
        </div>
      )}
    </div>
  );
}

export default App;
