Calibre N8N Chat Widget

Calibre N8N Chat Widget

As someone that is not very fond of the AI-hype, I still play around with it to look for some actual good use cases. The use case I am picturing is a simple "chat bot" that would give me decent answers, BUT (and this is important) it should source it's information from books I own. And reference what book it found the answers in.

This chat bot should also be integrated in my library, a Calibre web instance I am self hosting. And ideally, when i open a book to read in the browser, the chat should send the book ID from the URL to the N8N agent. So that the N8N agent can use that for reference when it is searching in the vector database.

Embedding the chat

The N8N documentation offer a simple solution to embed the chat, a js script file and a style.css file must be added to the static files folder of the Calibre web instance and the layout.html must be modified. The below code block must be added.

<link href="https://cdn.jsdelivr.net/npm/@n8n/chat/dist/style.css" rel="stylesheet" />
<script type="module">
	import { createChat } from 'https://cdn.jsdelivr.net/npm/@n8n/chat/dist/chat.bundle.es.js';

	createChat({
		webhookUrl: 'YOUR_PRODUCTION_WEBHOOK_URL'
	});
</script>

I did however also add {% if current_user.is_authenticated or g.allow_anonymous %} before the snippet so it only appears after we have logged in.

One problem I encountered was that the Calibre did not accept webhooks to another domain. So i needed to add my domain to the CORS bit of the Calibre app. In web.py file I added the lines n8n_host = os.getenv('N8N_HOST', 'https://example.domain.com') and csp += "; connect-src 'self' " + n8n_host This allows me to set the ENV variable of N8N_HOST to my N8N hostname. I am also not hardcoding in the webhook URL but using the N8N_WEBHOOK ENV variable.

What is still needed?

The most of the backend needs to be fixed to provide answers with sources as to what book it found the information in. And also to look up the specific book I am reading when chatting. I have added metadata fields to the JS file, this adds the url and book ID of current book.

Sending message when reading book
Message received in N8N

As we can see I can add the book ID in my messages. So now I need to add my books to the vector database with the correct ID. I suspect this will result in some manual labor. And then have the N8N agent use that reference when looking at specific books. And I also need it to reference the books when asking in general.

vector delivered by storage

The above result from vector DB includes the title and the book_ID. What I have yet to accomplish is to have it use the metadata title as reference when it uses the vectors. This will make it easier for me to look up the information in the books.

So there is still a lot of work that needs to be sorted out in the N8N instance. But the embedded chat widget all works. I think a solution like Cole Medin uses here might work for my use.

I have built a docker image and uploaded as enzanto/calibre-web-chat and the github files can be found here. I have simply mounted the css and js files inside the container, and modified the needed html and python files with sed during the docker build.