diff --git a/README.md b/README.md index 5f27e6a..ab3d24e 100644 --- a/README.md +++ b/README.md @@ -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 --- diff --git a/README_ar.md b/README_ar.md index 02bfebb..2df3534 100644 --- a/README_ar.md +++ b/README_ar.md @@ -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، يجب المصادقة في جهازك الطرفي (محطة الأوامر) لمرة واحدة فقط: +>
+> +> ```bash +> notebooklm login +> ``` +> +>
+ +--- + ## 🙏 شكر وتقدير - **[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)** diff --git a/README_es.md b/README_es.md index 05e5f91..ed15230 100644 --- a/README_es.md +++ b/README_es.md @@ -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 ``` diff --git a/README_fr.md b/README_fr.md index 05df488..76c6ea1 100644 --- a/README_fr.md +++ b/README_fr.md @@ -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 ``` diff --git a/README_ja.md b/README_ja.md index c9375e9..af89f7a 100644 --- a/README_ja.md +++ b/README_ja.md @@ -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 | 手動スクレイピング | ブラウザツール | diff --git a/README_ko.md b/README_ko.md index 3e16978..f42b247 100644 --- a/README_ko.md +++ b/README_ko.md @@ -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 +> ``` + +--- + ## 🏗️ 아키텍처 ``` diff --git a/README_zh.md b/README_zh.md index d02a9b9..5c382e3 100644 --- a/README_zh.md +++ b/README_zh.md @@ -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 +> ``` + +--- + ## 🏗️ 架构 ``` diff --git a/deepreader_skill/__init__.py b/deepreader_skill/__init__.py index dc5a6e4..f0b55fc 100644 --- a/deepreader_skill/__init__.py +++ b/deepreader_skill/__init__.py @@ -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: diff --git a/deepreader_skill/integrations/__init__.py b/deepreader_skill/integrations/__init__.py new file mode 100644 index 0000000..8173afd --- /dev/null +++ b/deepreader_skill/integrations/__init__.py @@ -0,0 +1,3 @@ +from .notebooklm import NotebookLMIntegration + +__all__ = ["NotebookLMIntegration"] diff --git a/deepreader_skill/integrations/notebooklm.py b/deepreader_skill/integrations/notebooklm.py new file mode 100644 index 0000000..5ce73b3 --- /dev/null +++ b/deepreader_skill/integrations/notebooklm.py @@ -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)) diff --git a/pyproject.toml b/pyproject.toml index 499c2f5..efca372 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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]