233 lines
7.1 KiB
Markdown
233 lines
7.1 KiB
Markdown
# notebooklm-api
|
||
|
||
REST + WebSocket API server điều khiển **Google NotebookLM** qua Puppeteer — giả lập thao tác người dùng thật trong Chrome.
|
||
|
||
Dùng để tích hợp NotebookLM vào chatbot, n8n, Make, Python scripts, ERP, hoặc bất kỳ hệ thống nào cần xử lý tài liệu bằng AI.
|
||
|
||
---
|
||
|
||
## Tính năng
|
||
|
||
- **Xác thực** — Mở Google login một lần, session lưu vĩnh viễn
|
||
- **Notebooks** — Tạo, liệt kê, xoá notebooks
|
||
- **Sources** — Thêm nguồn từ URL website, file local (.pdf, .docx, .txt, ...) hoặc văn bản paste
|
||
- **Chat đồng bộ** — Gửi câu hỏi, nhận câu trả lời đầy đủ (`POST`)
|
||
- **Chat streaming** — Nhận câu trả lời theo từng chunk realtime (`WebSocket`)
|
||
- **Queue tự động** — Các request song song được xếp hàng, không race condition
|
||
- **Swagger UI** — Tài liệu API tương tác tại `/docs`
|
||
|
||
---
|
||
|
||
## Cài đặt nhanh
|
||
|
||
```bash
|
||
git clone <repo>
|
||
cd notebooklm-api
|
||
bash setup.sh
|
||
```
|
||
|
||
Hoặc thủ công:
|
||
|
||
```bash
|
||
npm install
|
||
cp .env.example .env # tuỳ chỉnh nếu cần
|
||
npm start
|
||
```
|
||
|
||
Server khởi động tại **http://localhost:3456**
|
||
Swagger UI tại **http://localhost:3456/docs**
|
||
|
||
---
|
||
|
||
## Đăng nhập lần đầu
|
||
|
||
```bash
|
||
# Mở browser để đăng nhập Google
|
||
curl -X POST http://localhost:3456/api/auth/login
|
||
```
|
||
|
||
Chrome sẽ mở → đăng nhập Google → API tự trả về khi xong. Session lưu trong `./chrome-profile/` — các lần sau tự động đăng nhập.
|
||
|
||
**Dừng server:** luôn dùng `Ctrl+C` (không dùng `kill -9` để tránh mất cookies).
|
||
|
||
---
|
||
|
||
## Biến môi trường
|
||
|
||
| Biến | Mặc định | Mô tả |
|
||
|------|----------|-------|
|
||
| `PORT` | `3456` | Cổng HTTP/WebSocket |
|
||
| `HEADLESS` | `false` | `true` = ẩn cửa sổ Chrome |
|
||
| `CHROME_PATH` | tự phát hiện | Đường dẫn Chrome tuỳ chỉnh |
|
||
| `API_KEY` | _(trống)_ | Nếu đặt, request phải có header `x-api-key` |
|
||
|
||
---
|
||
|
||
## API nhanh
|
||
|
||
### Auth
|
||
```
|
||
GET /api/auth/status Kiểm tra đăng nhập
|
||
POST /api/auth/login Mở browser đăng nhập Google
|
||
```
|
||
|
||
### Notebooks
|
||
```
|
||
GET /api/notebooks Danh sách notebooks
|
||
POST /api/notebooks Tạo notebook { "title": "..." }
|
||
DELETE /api/notebooks/:id Xoá notebook
|
||
```
|
||
|
||
### Sources
|
||
```
|
||
GET /api/notebooks/:id/sources Danh sách sources
|
||
POST /api/notebooks/:id/sources Thêm source
|
||
```
|
||
|
||
Body thêm source:
|
||
```json
|
||
{ "type": "url", "content": "https://...", "title": "Tuỳ chọn" }
|
||
{ "type": "text", "content": "Nội dung...", "title": "Tên tài liệu" }
|
||
{ "type": "file", "content": "/đường/dẫn/tuyệt/đối/file.pdf" }
|
||
```
|
||
|
||
Định dạng file hỗ trợ: `.pdf` `.txt` `.md` `.docx` `.doc` `.pptx` `.ppt` `.xlsx` `.xls` `.mp3` `.mp4` `.jpg` `.png`
|
||
|
||
### Chat
|
||
```
|
||
POST /api/notebooks/:id/chat Hỏi đồng bộ { "message": "..." }
|
||
GET /api/notebooks/:id/chat/history Lịch sử hội thoại
|
||
WS /api/notebooks/:id/chat/stream Chat streaming (WebSocket)
|
||
```
|
||
|
||
### Tiện ích
|
||
```
|
||
GET /health Trạng thái server + queue
|
||
GET /docs Swagger UI
|
||
```
|
||
|
||
---
|
||
|
||
## Ví dụ sử dụng
|
||
|
||
### curl
|
||
```bash
|
||
NB=<notebook-id>
|
||
|
||
# Tạo notebook
|
||
curl -X POST http://localhost:3456/api/notebooks \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"title": "Dự án Q3"}'
|
||
|
||
# Thêm URL
|
||
curl -X POST http://localhost:3456/api/notebooks/$NB/sources \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"type":"url","content":"https://example.com/bai-viet"}'
|
||
|
||
# Thêm file local
|
||
curl -X POST http://localhost:3456/api/notebooks/$NB/sources \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"type":"file","content":"/Users/me/Documents/report.pdf"}' \
|
||
--max-time 90
|
||
|
||
# Hỏi
|
||
curl -X POST http://localhost:3456/api/notebooks/$NB/chat \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"message":"Tóm tắt nội dung chính"}' --max-time 120
|
||
```
|
||
|
||
### Python
|
||
```python
|
||
import requests
|
||
|
||
BASE = "http://localhost:3456"
|
||
NB_ID = "<notebook-id>"
|
||
|
||
# Thêm file
|
||
requests.post(f"{BASE}/api/notebooks/{NB_ID}/sources",
|
||
json={"type": "file", "content": "/path/to/file.pdf"},
|
||
timeout=90)
|
||
|
||
# Hỏi
|
||
answer = requests.post(f"{BASE}/api/notebooks/{NB_ID}/chat",
|
||
json={"message": "Tóm tắt tài liệu"},
|
||
timeout=120).json()["answer"]
|
||
print(answer)
|
||
```
|
||
|
||
### WebSocket streaming
|
||
```javascript
|
||
const ws = new WebSocket('ws://localhost:3456/api/notebooks/<NB_ID>/chat/stream');
|
||
|
||
ws.onopen = () => ws.send(JSON.stringify({ message: 'Tóm tắt nội dung' }));
|
||
|
||
ws.onmessage = ({ data }) => {
|
||
const msg = JSON.parse(data);
|
||
if (msg.type === 'chunk') process.stdout.write(msg.data);
|
||
if (msg.type === 'done') console.log('\n[Xong]');
|
||
if (msg.type === 'error') console.error('[Lỗi]', msg.data);
|
||
};
|
||
```
|
||
|
||
---
|
||
|
||
## Cấu trúc dự án
|
||
|
||
```
|
||
notebooklm-api/
|
||
├── src/
|
||
│ ├── server.js Express app + debug routes
|
||
│ ├── browser.js Puppeteer BrowserManager (singleton)
|
||
│ ├── nlm.js Logic automation NotebookLM (core)
|
||
│ ├── queue.js AsyncQueue — tuần tự hoá thao tác browser
|
||
│ ├── selectors.js CSS selectors đã xác nhận trên DOM thực
|
||
│ ├── swagger.js OpenAPI spec
|
||
│ └── routes/
|
||
│ ├── auth.js /api/auth/*
|
||
│ ├── notebooks.js /api/notebooks/*
|
||
│ └── chat-ws.js WebSocket streaming
|
||
├── chrome-profile/ Session Chrome (KHÔNG xoá)
|
||
├── .env Biến môi trường
|
||
├── setup.sh Script cài đặt nhanh
|
||
└── API.md Tài liệu API đầy đủ
|
||
```
|
||
|
||
---
|
||
|
||
## Debug endpoints
|
||
|
||
Dùng khi selector bị hỏng sau khi Google cập nhật UI:
|
||
|
||
```
|
||
GET /debug/screenshot Chụp ảnh Chrome hiện tại (base64 PNG)
|
||
GET /debug/home Liệt kê buttons trên trang chủ
|
||
GET /debug/notebook-btns/:id Liệt kê buttons trên trang notebook
|
||
GET /debug/notebook-menu/:id Hover card + click "..." menu, trả về menu items
|
||
GET /debug/sources/:id Inspect DOM source panel
|
||
GET /debug/source-items/:id HTML đầy đủ của từng source item
|
||
GET /debug/add-source-dialog/:id Click "Thêm nguồn", snapshot dialog
|
||
GET /debug/add-url-flow/:id Trace từng bước flow thêm URL
|
||
GET /debug/add-file-flow/:id Trace từng bước flow upload file
|
||
GET /debug/chat/:id Liệt kê textarea/input trên trang notebook
|
||
GET /debug/page-state/:id Trạng thái overlay trước/sau click
|
||
```
|
||
|
||
---
|
||
|
||
## Lưu ý
|
||
|
||
- **1 thao tác tại 1 thời điểm** — queue tự xếp hàng, không cần lo concurrency
|
||
- **Upload file** có thể mất 30–60 giây — đặt `--max-time 90` khi dùng curl
|
||
- **Chat timeout** mặc định 90 giây — câu hỏi phức tạp có thể cần tăng lên
|
||
- **Chrome crash?** Xoá `chrome-profile/SingletonLock` rồi restart
|
||
- **Google có thể giới hạn** automation — nếu bị chặn, đợi vài phút rồi thử lại
|
||
|
||
---
|
||
|
||
## Scripts
|
||
|
||
```bash
|
||
npm start # Production
|
||
npm run dev # Development (auto-restart khi thay đổi file)
|
||
```
|