mirror of
https://github.com/astonysh/OpenClaw-DeepReeder.git
synced 2026-08-14 00:57:54 +00:00
feat: integrate notebooklm-py for Audio Overview and Notebook artifact generation
This commit is contained in:
@@ -107,6 +107,36 @@ result = run("""
|
||||
|
||||
---
|
||||
|
||||
## 📓 NotebookLM & Audio Integration
|
||||
|
||||
DeepReader now seamlessly integrates with **Google NotebookLM**.
|
||||
|
||||
If your message includes keywords like `notebooklm`, `audio`, or `podcast`, DeepReader will automatically:
|
||||
1. Parse the requested URLs into Markdown.
|
||||
2. Create a new Notebook in your Google NotebookLM account.
|
||||
3. Upload the pristine Markdown content as a source.
|
||||
4. **(Optional)** Generate an engaging Audio Overview (podcast format) and download it directly to your agent's memory folder.
|
||||
|
||||
**Supported NotebookLM Artifacts Generation:**
|
||||
Along with Audio Overviews, this integration can easily be extended to automatically generate and save:
|
||||
- **🎙️ Audio Overview** (Podcast)
|
||||
- **🎥 Video Overview**
|
||||
- **🧠 Mind Map**
|
||||
- **📄 Reports**
|
||||
- **📇 Flashcards**
|
||||
- **❓ Quiz**
|
||||
- **📊 Infographic**
|
||||
- **🖥️ Slide Deck**
|
||||
- **📈 Data Table**
|
||||
|
||||
> **⚠️ Note: Authentication Required**
|
||||
> Before using the NotebookLM integration, you must authenticate in your terminal (this only needs to be done once):
|
||||
> ```bash
|
||||
> notebooklm login
|
||||
> ```
|
||||
|
||||
---
|
||||
|
||||
## 📄 Output Format
|
||||
|
||||
Every piece of content is saved as a `.md` file with structured YAML frontmatter:
|
||||
@@ -201,6 +231,7 @@ DeepReader uses sensible defaults out of the box. Configuration can be customize
|
||||
- **[x-tweet-fetcher](https://github.com/ythx-101/x-tweet-fetcher)** — Inspiration for the FxTwitter integration approach
|
||||
- **[Trafilatura](https://trafilatura.readthedocs.io/)** — Robust web content extraction
|
||||
- **[youtube-transcript-api](https://github.com/jdepoix/youtube-transcript-api)** — YouTube transcript fetching
|
||||
- **[notebooklm-py](https://github.com/teng-lin/notebooklm-py)** — Google NotebookLM integration for audio generation
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -74,6 +74,40 @@ result = run("شاهد هذا: https://youtube.com/watch?v=dQw4w9WgXcQ")
|
||||
|
||||
---
|
||||
|
||||
## 📓 تكامل NotebookLM والصوت
|
||||
|
||||
DeepReader يندمج الآن بكل سلاسة مع **Google NotebookLM**.
|
||||
|
||||
إذا كانت رسالتك تحتوي على كلمات مفتاحية مثل `notebooklm` أو `audio` أو `podcast`، سيقوم DeepReader تلقائياً بـ:
|
||||
1. تحليل الروابط المطلوبة إلى Markdown.
|
||||
2. إنشاء دفتر ملاحظات جديد في حساب Google NotebookLM الخاص بك.
|
||||
3. رفع محتوى Markdown كمصدر البيانات.
|
||||
4. **(اختياري)** إنشاء ملخص صوتي (بتنسيق بودكاست) ممتع وتنزيله مباشرةً في مجلد الذاكرة الخاص بوكيلك.
|
||||
|
||||
**إنشاء عناصر NotebookLM المدعومة:**
|
||||
بالإضافة إلى الملخصات الصوتية، يمكن توسيع هذا التكامل بسهولة لإنشاء وحفظ ما يلي تلقائيًا:
|
||||
- **🎙️ Audio Overview** (بودكاست صوتي)
|
||||
- **🎥 Video Overview** (ملخص فيديو)
|
||||
- **🧠 Mind Map** (خريطة ذهنية)
|
||||
- **📄 Reports** (تقارير)
|
||||
- **📇 Flashcards** (بطاقات تعليمية)
|
||||
- **❓ Quiz** (اختبار)
|
||||
- **📊 Infographic** (إنفوجرافيك)
|
||||
- **🖥️ Slide Deck** (مجموعة شرائح العرض)
|
||||
- **📈 Data Table** (جدول بيانات)
|
||||
|
||||
> **⚠️ ملاحظة: يتطلب تسجيل الدخول**
|
||||
> قبل استخدام تكامل NotebookLM، يجب المصادقة في جهازك الطرفي (محطة الأوامر) لمرة واحدة فقط:
|
||||
> <div dir="ltr">
|
||||
>
|
||||
> ```bash
|
||||
> notebooklm login
|
||||
> ```
|
||||
>
|
||||
> </div>
|
||||
|
||||
---
|
||||
|
||||
## 🙏 شكر وتقدير
|
||||
|
||||
- **[FxTwitter](https://github.com/FxEmbed/FxEmbed)** · **[x-tweet-fetcher](https://github.com/ythx-101/x-tweet-fetcher)** · **[Trafilatura](https://trafilatura.readthedocs.io/)** · **[youtube-transcript-api](https://github.com/jdepoix/youtube-transcript-api)**
|
||||
|
||||
@@ -107,6 +107,36 @@ result = run("""
|
||||
|
||||
---
|
||||
|
||||
## 📓 Integración de NotebookLM & Audio
|
||||
|
||||
DeepReader ahora se integra perfectamente con **Google NotebookLM**.
|
||||
|
||||
Si tu mensaje incluye palabras clave como `notebooklm`, `audio` o `podcast`, DeepReader automáticamente:
|
||||
1. Analizará las URLs solicitadas en Markdown.
|
||||
2. Creará un nuevo Cuaderno (Notebook) en tu cuenta de Google NotebookLM.
|
||||
3. Subirá el contenido Markdown impecable como fuente.
|
||||
4. **(Opcional)** Generará un Audio Overview (formato podcast) atractivo y lo descargará directamente en la carpeta de memoria de tu agente.
|
||||
|
||||
**Generación de Artefactos de NotebookLM Soportados:**
|
||||
Junto con los Resúmenes de Audio, esta integración se puede extender fácilmente para generar y guardar automáticamente:
|
||||
- **🎙️ Audio Overview** (Podcast)
|
||||
- **🎥 Video Overview** (Resumen en Vídeo)
|
||||
- **🧠 Mind Map** (Mapa Mental)
|
||||
- **📄 Reports** (Informes)
|
||||
- **📇 Flashcards** (Tarjetas de Estudio)
|
||||
- **❓ Quiz** (Cuestionario)
|
||||
- **📊 Infographic** (Infografía)
|
||||
- **🖥️ Slide Deck** (Presentación)
|
||||
- **📈 Data Table** (Tabla de Datos)
|
||||
|
||||
> **⚠️ Nota: Autenticación Requerida**
|
||||
> Antes de usar la integración con NotebookLM, debes autenticarte en tu terminal (esto solo se requiere una vez):
|
||||
> ```bash
|
||||
> notebooklm login
|
||||
> ```
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Arquitectura
|
||||
|
||||
```
|
||||
|
||||
@@ -107,6 +107,36 @@ result = run("""
|
||||
|
||||
---
|
||||
|
||||
## 📓 Intégration NotebookLM & Audio
|
||||
|
||||
DeepReader s'intègre désormais parfaitement à **Google NotebookLM**.
|
||||
|
||||
Si votre message inclut des mots-clés tels que `notebooklm`, `audio` ou `podcast`, DeepReader va automatiquement :
|
||||
1. Analyser les URL demandées en Markdown.
|
||||
2. Créer un nouveau carnet (Notebook) dans votre compte Google NotebookLM.
|
||||
3. Télécharger le contenu Markdown propre comme source.
|
||||
4. **(Facultatif)** Générer un Audio Overview (format podcast) captivant et le télécharger directement dans le dossier mémoire de votre agent.
|
||||
|
||||
**Génération d'Artefacts NotebookLM Supportés :**
|
||||
Outre les résumés audio, cette intégration peut être facilement étendue pour générer et sauvegarder automatiquement :
|
||||
- **🎙️ Audio Overview** (Podcast)
|
||||
- **🎥 Video Overview** (Résumé vidéo)
|
||||
- **🧠 Mind Map** (Carte mentale)
|
||||
- **📄 Reports** (Rapports)
|
||||
- **📇 Flashcards** (Cartes mémoire)
|
||||
- **❓ Quiz** (Questionnaire)
|
||||
- **📊 Infographic** (Infographie)
|
||||
- **🖥️ Slide Deck** (Présentation)
|
||||
- **📈 Data Table** (Tableau de données)
|
||||
|
||||
> **⚠️ Remarque : Authentification requise**
|
||||
> Avant d'utiliser l'intégration NotebookLM, vous devez vous authentifier dans votre terminal (à faire une seule fois) :
|
||||
> ```bash
|
||||
> notebooklm login
|
||||
> ```
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Architecture
|
||||
|
||||
```
|
||||
|
||||
@@ -61,6 +61,36 @@ result = run("興味深い記事: https://example.com/blog/ai-agents-2026")
|
||||
|
||||
---
|
||||
|
||||
## 📓 NotebookLM & オーディオ統合
|
||||
|
||||
DeepReaderは**Google NotebookLM**とシームレスに統合されるようになりました。
|
||||
|
||||
メッセージに `notebooklm`、`audio`、または `podcast` などのキーワードが含まれている場合、DeepReaderは自動的に以下を実行します:
|
||||
1. リクエストされたURLをMarkdownにパースします。
|
||||
2. Google NotebookLMアカウントに新しいノートブックを作成します。
|
||||
3. 綺麗なMarkdownコンテンツをソースとしてアップロードします。
|
||||
4. **(オプション)** 魅力的なオーディオ概要(ポッドキャスト形式)を生成し、エージェントのメモリフォルダに直接ダウンロードします。
|
||||
|
||||
**サポートされているNotebookLM成果物の生成:**
|
||||
オーディオ概要に加えて、この統合を簡単に拡張して、以下を自動的に生成および保存できます:
|
||||
- **🎙️ Audio Overview**(オーディオポッドキャスト)
|
||||
- **🎥 Video Overview**(ビデオ概要)
|
||||
- **🧠 Mind Map**(マインドマップ)
|
||||
- **📄 Reports**(レポート)
|
||||
- **📇 Flashcards**(フラッシュカード)
|
||||
- **❓ Quiz**(クイズ)
|
||||
- **📊 Infographic**(インフォグラフィック)
|
||||
- **🖥️ Slide Deck**(スライドデッキ)
|
||||
- **📈 Data Table**(データテーブル)
|
||||
|
||||
> **⚠️ 注意:認証が必要**
|
||||
> NotebookLM連携を使用する前に、ターミナルで認証を行う必要があります(これは一度だけ行う必要があります):
|
||||
> ```bash
|
||||
> notebooklm login
|
||||
> ```
|
||||
|
||||
---
|
||||
|
||||
## 💡 なぜDeepReader?
|
||||
|
||||
| 機能 | DeepReader | 手動スクレイピング | ブラウザツール |
|
||||
|
||||
@@ -107,6 +107,36 @@ result = run("""
|
||||
|
||||
---
|
||||
|
||||
## 📓 NotebookLM & 오디오 통합
|
||||
|
||||
이제 DeepReader는 **Google NotebookLM**과 완벽하게 통합됩니다.
|
||||
|
||||
메시지에 `notebooklm`, `audio` 또는 `podcast`와 같은 키워드가 포함 된 경우 DeepReader는 자동으로 다음을 수행합니다:
|
||||
1. 요청된 URL을 Markdown으로 파싱합니다.
|
||||
2. Google NotebookLM 계정에 새 노트를 만듭니다.
|
||||
3. 깔끔한 Markdown 콘텐츠를 소스로 업로드합니다.
|
||||
4. **(선택 사항)** 매력적인 오디오 개요(팟캐스트 형식)를 생성하고 에이전트의 메모리 폴더에 직접 다운로드합니다.
|
||||
|
||||
**지원되는 NotebookLM 아티팩트 생성:**
|
||||
오디오 개요와 함께 이 통합을 쉽게 확장하여 다음을 자동으로 생성하고 저장할 수 있습니다:
|
||||
- **🎙️ Audio Overview** (오디오 팟캐스트)
|
||||
- **🎥 Video Overview** (비디오 개요)
|
||||
- **🧠 Mind Map** (마인드맵)
|
||||
- **📄 Reports** (보고서)
|
||||
- **📇 Flashcards** (플래시카드)
|
||||
- **❓ Quiz** (퀴즈)
|
||||
- **📊 Infographic** (인포그래픽)
|
||||
- **🖥️ Slide Deck** (슬라이드 덱)
|
||||
- **📈 Data Table** (데이터 테이블)
|
||||
|
||||
> **⚠️ 참고: 인증 필요**
|
||||
> NotebookLM 통합을 사용하기 전에 터미널에서 인증해야 합니다(이 작업은 한 번만 수행하면 됩니다):
|
||||
> ```bash
|
||||
> notebooklm login
|
||||
> ```
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 아키텍처
|
||||
|
||||
```
|
||||
|
||||
@@ -107,6 +107,36 @@ result = run("""
|
||||
|
||||
---
|
||||
|
||||
## 📓 NotebookLM & 音频播客集成
|
||||
|
||||
DeepReader 现在无缝集成 **Google NotebookLM**。
|
||||
|
||||
如果你的消息包含如 `notebooklm`、`audio` 或 `podcast` 等关键词,DeepReader将自动:
|
||||
1. 将请求的 URL 解析成 Markdown。
|
||||
2. 在您的 Google NotebookLM 账号下创建一个新的 Notebook。
|
||||
3. 将干净的 Markdown 内容作为数据源(Source)上传。
|
||||
4. **(可选)** 生成生动的 Audio Overview (播客格式的音频概述) 并直接下载到智能体的记忆文件夹中。
|
||||
|
||||
**支持生成的 NotebookLM 制品包含:**
|
||||
除了音频播客,该集成很容易扩展为自动生成和保存以下内容的导出:
|
||||
- **🎙️ Audio Overview** (音频播客)
|
||||
- **🎥 Video Overview** (视频概述)
|
||||
- **🧠 Mind Map** (思维导图)
|
||||
- **📄 Reports** (报告)
|
||||
- **📇 Flashcards** (抽认卡)
|
||||
- **❓ Quiz** (测验)
|
||||
- **📊 Infographic** (信息图)
|
||||
- **🖥️ Slide Deck** (幻灯片)
|
||||
- **📈 Data Table** (数据表)
|
||||
|
||||
> **⚠️ 注意: 需要进行身份验证(登录)**
|
||||
> 在使用 NotebookLM 集成功能之前,您必须先在终端中完成身份验证(仅需操作一次):
|
||||
> ```bash
|
||||
> notebooklm login
|
||||
> ```
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 架构
|
||||
|
||||
```
|
||||
|
||||
@@ -125,6 +125,31 @@ def run(text: str, **kwargs: Any) -> str:
|
||||
f" Saved to: `{filepath}`\n"
|
||||
f" Content: {len(parse_result.content)} characters"
|
||||
)
|
||||
|
||||
# --- NotebookLM Integration ---
|
||||
text_lower = text.lower()
|
||||
use_notebooklm = "notebooklm" in text_lower or "audio" in text_lower or "podcast" in text_lower
|
||||
generate_audio = "audio" in text_lower or "podcast" in text_lower
|
||||
|
||||
if use_notebooklm:
|
||||
logger.info("NotebookLM integration triggered for %s", filepath)
|
||||
from .integrations.notebooklm import NotebookLMIntegration
|
||||
nl_integration = NotebookLMIntegration()
|
||||
|
||||
nl_result = nl_integration.run_sync(
|
||||
filepath=filepath,
|
||||
title=parse_result.title or "DeepReader Document",
|
||||
generate_audio=generate_audio
|
||||
)
|
||||
|
||||
if "error" in nl_result:
|
||||
errors.append(f"❌ NotebookLM upload failed: {nl_result['error']}")
|
||||
else:
|
||||
nb_id = nl_result.get("notebook_id")
|
||||
success_msg += f"\n 📓 Notebook ID: {nb_id}"
|
||||
if generate_audio and "audio_path" in nl_result:
|
||||
success_msg += f"\n 🎙️ Audio Output: `{nl_result['audio_path']}`"
|
||||
|
||||
results.append(success_msg)
|
||||
logger.info("Successfully saved %s", filepath)
|
||||
except OSError as exc:
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
from .notebooklm import NotebookLMIntegration
|
||||
|
||||
__all__ = ["NotebookLMIntegration"]
|
||||
@@ -0,0 +1,97 @@
|
||||
"""
|
||||
DeepReader Skill - NotebookLM Integration
|
||||
=========================================
|
||||
Pushes parsed Markdown content directly into Google NotebookLM and optionally generates Audio Overviews.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
# Provide a fallback if not installed, though it's in dependencies
|
||||
try:
|
||||
from notebooklm import NotebookLMClient
|
||||
__HAS_NOTEBOOKLM__ = True
|
||||
except ImportError:
|
||||
__HAS_NOTEBOOKLM__ = False
|
||||
|
||||
logger = logging.getLogger("deepreader.notebooklm")
|
||||
|
||||
|
||||
class NotebookLMIntegration:
|
||||
"""Manages integration with Google NotebookLM for DeepReader content.
|
||||
|
||||
This requires a pre-authenticated session handled via `notebooklm login`.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
if not __HAS_NOTEBOOKLM__:
|
||||
logger.warning("notebooklm-py is not installed. NotebookLM integration will be disabled.")
|
||||
|
||||
async def upload_and_generate_audio(
|
||||
self,
|
||||
filepath: str | Path,
|
||||
title: str,
|
||||
generate_audio: bool = False,
|
||||
audio_instructions: str | None = None
|
||||
) -> dict[str, str | None]:
|
||||
"""
|
||||
Create a new notebook, upload the given markdown file, and optionally generate an audio overview.
|
||||
|
||||
Args:
|
||||
filepath: Path to the local markdown file saved by StorageManager.
|
||||
title: The title for the new notebook.
|
||||
generate_audio: If True, request an audio overview.
|
||||
audio_instructions: Optional instructions for the audio overview.
|
||||
|
||||
Returns:
|
||||
A dict containing the notebook ID and optionally the path to the downloaded audio.
|
||||
"""
|
||||
if not __HAS_NOTEBOOKLM__:
|
||||
return {"error": "notebooklm-py not installed"}
|
||||
|
||||
filepath = Path(filepath)
|
||||
if not filepath.exists():
|
||||
return {"error": f"File not found: {filepath}"}
|
||||
|
||||
try:
|
||||
# Authenticates via ~/.book_client_session created by `notebooklm login`
|
||||
async with await NotebookLMClient.from_storage() as client:
|
||||
logger.info("Creating NotebookLM instance titled: %s", title)
|
||||
nb = await client.notebooks.create(title)
|
||||
|
||||
logger.info("Uploading %s to NotebookLM", filepath.name)
|
||||
# Ensure the file gets added and fully processed before proceeding
|
||||
await client.sources.add_file(nb.id, str(filepath), wait=True)
|
||||
|
||||
result = {
|
||||
"notebook_id": nb.id,
|
||||
"title": title,
|
||||
}
|
||||
|
||||
if generate_audio:
|
||||
logger.info("Generating Audio Overview... (This may take a few minutes)")
|
||||
instructions = audio_instructions or "Create an engaging, easy to follow podcast overview of this content."
|
||||
status = await client.artifacts.generate_audio(nb.id, instructions=instructions)
|
||||
|
||||
# Wait for completion - this takes minutes for full audio.
|
||||
await client.artifacts.wait_for_completion(nb.id, status.task_id)
|
||||
|
||||
# Download the generated mp3/mp4 to the same dir
|
||||
audio_filepath = filepath.with_suffix(".mp3")
|
||||
await client.artifacts.download_audio(nb.id, str(audio_filepath))
|
||||
logger.info("Audio Overview saved to %s", audio_filepath)
|
||||
|
||||
result["audio_path"] = str(audio_filepath)
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.exception("Failed to upload/generate NotebookLM content")
|
||||
return {"error": str(e)}
|
||||
|
||||
def run_sync(self, filepath: str | Path, title: str, generate_audio: bool = False) -> dict[str, str | None]:
|
||||
"""Synchronous wrapper for integration."""
|
||||
return asyncio.run(self.upload_and_generate_audio(filepath, title, generate_audio))
|
||||
@@ -48,6 +48,7 @@ dependencies = [
|
||||
"pydantic-settings>=2.1.0",
|
||||
"tldextract>=5.1.0",
|
||||
"beautifulsoup4>=4.12.0",
|
||||
"notebooklm-py>=0.3.0",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
|
||||
Reference in New Issue
Block a user