diff --git a/embed/src/App.jsx b/embed/src/App.jsx
index 4973328b..0ce0a3e0 100644
--- a/embed/src/App.jsx
+++ b/embed/src/App.jsx
@@ -3,7 +3,7 @@ import useSessionId from "@/hooks/useSessionId";
import useOpenChat from "@/hooks/useOpen";
import Head from "@/components/Head";
import OpenButton from "@/components/OpenButton";
-import ChatWindow from "./components/ChatWindow";
+import ChatWindow, { ChatWindowFull } from "./components/ChatWindow";
import { useEffect } from "react";
export default function App() {
@@ -16,6 +16,22 @@ export default function App() {
}, [embedSettings.loaded]);
if (!embedSettings.loaded) return null;
+
+ if (embedSettings.iframe === 'enabled') {
+ return (
+ <>
+
+
+
+
+ >
+ )
+ }
+
+ // Renders the default bubble chat if nothing is defined
return (
<>
@@ -25,11 +41,10 @@ export default function App() {
width: isChatOpen ? 320 : "auto",
height: isChatOpen ? "93vh" : "auto",
}}
- className={`transition-all duration-300 ease-in-out ${
- isChatOpen
- ? "max-w-md p-4 bg-white rounded-lg border shadow-lg w-72"
- : "w-16 h-16 rounded-full"
- }`}
+ className={`transition-all duration-300 ease-in-out ${isChatOpen
+ ? "max-w-md p-4 bg-white rounded-lg border shadow-lg w-72"
+ : "w-16 h-16 rounded-full"
+ }`}
>
{isChatOpen && (
{
+ await ChatService.resetEmbedChatSession(settings, sessionId);
+ setChatHistory([]);
+ setShowOptions(false);
+ };
+
+ return (
+
+
+
+ {settings.loaded && (
+
+ )}
+
+
+
+ );
+}
+
function OptionsMenu({ showing, resetChat }) {
if (!showing) return null;
return (
diff --git a/embed/src/components/ChatWindow/index.jsx b/embed/src/components/ChatWindow/index.jsx
index 2e717cac..1e3645b0 100644
--- a/embed/src/components/ChatWindow/index.jsx
+++ b/embed/src/components/ChatWindow/index.jsx
@@ -1,4 +1,4 @@
-import ChatWindowHeader from "./Header";
+import ChatWindowHeader, { ChatFullWindowHeader } from "./Header";
import SessionId from "../SessionId";
import useChatHistory from "@/hooks/chat/useChatHistory";
import ChatContainer from "./ChatContainer";
@@ -30,6 +30,33 @@ export default function ChatWindow({ closeChat, settings, sessionId }) {
);
}
+export function ChatWindowFull({ settings, sessionId }) {
+ const { chatHistory, setChatHistory, loading } = useChatHistory(
+ settings,
+ sessionId
+ );
+
+ if (loading) return null;
+ setEventDelegatorForCodeSnippets();
+ return (
+
+
+ {/*
+ */}
+
+ );
+}
+
+
// Enables us to safely markdown and sanitize all responses without risk of injection
// but still be able to attach a handler to copy code snippets on all elements
// that are code snippets.
diff --git a/embed/src/hooks/useScriptAttributes.js b/embed/src/hooks/useScriptAttributes.js
index a3e5594b..9807745b 100644
--- a/embed/src/hooks/useScriptAttributes.js
+++ b/embed/src/hooks/useScriptAttributes.js
@@ -17,6 +17,7 @@ const DEFAULT_SETTINGS = {
// behaviors
openOnLoad: "off", // or "on"
+ iframe: null, // 'enabled' is the only valid option
};
export default function useGetScriptAttributes() {
diff --git a/server/index.js b/server/index.js
index 3d613191..52ede021 100644
--- a/server/index.js
+++ b/server/index.js
@@ -19,6 +19,8 @@ const { utilEndpoints } = require("./endpoints/utils");
const { developerEndpoints } = require("./endpoints/api");
const { extensionEndpoints } = require("./endpoints/extensions");
const { bootHTTP, bootSSL } = require("./utils/boot");
+const { renderIFrameResponse } = require("./utils/embed/render");
+const { validEmbedConfigUUID } = require("./utils/middleware/embedMiddleware");
const app = express();
const apiRouter = express.Router();
const FILE_LIMIT = "3GB";
@@ -90,6 +92,10 @@ if (process.env.NODE_ENV !== "development") {
});
}
+// Named embedded to not collide with public folder /embed/ directory
+// when in production
+app.get("/embedded/:embedId", [validEmbedConfigUUID], renderIFrameResponse);
+
app.all("*", function (_, response) {
response.sendStatus(404);
});
diff --git a/server/utils/embed/render.js b/server/utils/embed/render.js
new file mode 100644
index 00000000..cc651023
--- /dev/null
+++ b/server/utils/embed/render.js
@@ -0,0 +1,32 @@
+const HTML = ({ scriptLoc }) => `
+
+
+
+
+`
+
+
+function renderIFrameResponse(request, response) {
+ const embed = response.locals.embedConfig;
+ const settings = {
+ scriptLoc:
+ process.env.NODE_ENV === 'production' ?
+ `/embed/anythingllm-chat-widget.min.js` :
+ 'http://localhost:3080/dist/anythingllm-chat-widget.js', // Running yarn dev in embed folder
+ embedId: embed.id,
+ }
+ response.type('text/html');
+ response.header('Access-Control-Allow-Origin', '*');
+ response.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
+ response.header('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With, Authorization');
+ response.send(HTML(settings)).end();
+}
+
+module.exports = {
+ renderIFrameResponse
+}
\ No newline at end of file
diff --git a/server/utils/middleware/embedMiddleware.js b/server/utils/middleware/embedMiddleware.js
index c87d8771..5bd9bce3 100644
--- a/server/utils/middleware/embedMiddleware.js
+++ b/server/utils/middleware/embedMiddleware.js
@@ -27,6 +27,19 @@ function setConnectionMeta(request, response, next) {
next();
}
+async function validEmbedConfigUUID(request, response, next) {
+ const { embedId } = request.params;
+
+ const embed = await EmbedConfig.getWithWorkspace({ uuid: embedId });
+ if (!embed) {
+ response.sendStatus(404).end();
+ return;
+ }
+
+ response.locals.embedConfig = embed;
+ next();
+}
+
async function validEmbedConfigId(request, response, next) {
const { embedId } = request.params;
@@ -147,5 +160,6 @@ module.exports = {
setConnectionMeta,
validEmbedConfig,
validEmbedConfigId,
+ validEmbedConfigUUID,
canRespond,
};