Files
audio-voice-converter/docs/result/002_result_planning.md
T
vahidaskari 7bc34c79ed Refactor Google Meet Transcripts Extension for Local Use
- Removed all cloud-related functionalities, including login prompts and token handling.
- Disabled Laxis cloud features, ensuring no data is sent to external servers.
- Updated manifest to reflect the new local-only functionality.
- Added a new Python server to handle transcripts locally, including WebSocket support.
- Implemented storage management for transcripts, including deduplication and file writing.
- Created a smoke test for the WebSocket server to simulate transcript updates.
- Updated README with setup instructions and usage details for the new local server.
2026-06-12 00:31:32 +03:30

6.8 KiB

Result — 002 Planning

اکشن مرتبط: action/002_action_planning.md تاریخ اجرا: 2026-06-09


هدف این جلسه

خواندن پروژه، فهمیدن ساختار، و پیاده‌سازی گام اول MVP: اتصال افزونه‌ی Chrome به یک سرور پایتون بیرون مرورگر از طریق WebSocket.


تصمیم‌های کلیدی که گرفته شد

معماری — چرا extension به‌عنوان WS client؟

افزونه نمی‌تواند خودش سرور باشد (MV3 سرویس‌ورکر TCP port نمی‌تواند باز کند). پس افزونه client است و پایتون server — افزونه به ws://127.0.0.1:8765 وصل می‌شود.

همچنین WS باید از service worker باز شود، نه content script؛ چون content script تابع CSP صفحه‌ی گوگل میت است و connect-src اتصال را بلاک می‌کند.

نقطه‌ی hook در کد افزونه

setSpeaker() در storage.js — هر پاراگراف caption نهایی از این تابع رد می‌شود. یک chrome.runtime.sendMessage کوچک به آن اضافه شد که background را خبر می‌کند.

venv برای پایتون

تصمیم گرفته شد پایتون داخل .venv اجرا شود تا سیستم کثیف نشود.


چه چیزی ساخته شد

فایل نوع کار
bridge/server.py جدید WebSocket server پایتون روی 127.0.0.1:8765
bridge/requirements.txt جدید فقط websockets>=12.0
bridge/.gitignore جدید .venv/ و transcripts/ از git خارج
bridge/README.md جدید راهنمای اجرا با venv
bridge/_smoke_test.py جدید کلاینت تستی بدون Chrome
bridge/.venv/ جدید محیط ایزوله پایتون
google-meet-transcripts-extension/bridge.js جدید WS client داخل service worker
login.js ویرایش اضافه شدن importScripts("bridge.js")
storage.js ویرایش setSpeaker حالا TRANSCRIPT_UPDATE می‌فرستد
manifest.json ویرایش ws://127.0.0.1:8765/* به host_permissions اضافه شد

تست انجام شده

سرور پایتون با _smoke_test.py end-to-end تست شد:

  • PING → PONG
  • سه TRANSCRIPT_UPDATE → سه ACK
  • فایل transcripts/meeting-abc123.txt با متن فارسی درست ذخیره شد

تست با Chrome واقعی هنوز انجام نشده (نیاز به Reload افزونه و یک جلسه‌ی Meet).


وضعیت چک‌لیست اصلی (از action)

  • حذف کدهای laxis — انجام شد (اجرای ۲۰۲۶-۰۶-۱۰، پایین را ببین)
  • لوگوی اختصاصی — انجام شد (لوگوی جدید جایگزین شد)
  • گرفتن caption از افزونه — گام ۱ (اتصال) انجام شد
  • سرویس MCP روی پورت — انجام شد (روی همان server.py)
  • تست میدانی با Chrome واقعی — باقی‌مانده (نیاز به مرورگر و یک جلسه‌ی Meet)

اجرای دوم — پاک‌سازی laxis + MCP + لوگو (۲۰۲۶-۰۶-۱۰)

پاک‌سازی laxis (هیچ داده‌ای دیگر بیرون نمی‌رود)

  • analytics.js: کاملاً خالی شد (از قبل کامنت‌شده و مرده بود؛ در manifest هم لود نمی‌شد).
  • login.js (service worker): بازنویسی شد — حذف tabs.onRemoved (که transcript را آپلود می‌کرد)، حذف onMessageExternal (دریافت توکن) و getTopics. فقط import ها + نگه‌داشتن وضعیت لوکال ماند.
  • runtime.js (content script): حذف فراخوانی addRemindLogin() و کل listener دریافت توکن/fetch.
  • meetingInfo.js: checkToken و renewToken با return; در ابتدا خنثی شدند؛ آپلود پایان جلسه (Export2App + باز کردن domainUrl/transcript) حذف شد.
  • transcript.js: Export2App بلافاصله reject می‌کند (آپلود ابری قطع)، getTopics خنثی شد، addRemindLogin خالی شد، منوی دانلود از حالت پیش‌فرضِ «app/cloud» به دانلود محلی txt تغییر کرد.
  • panel/main.js: لینک لوگو → domainUrl/login در هر سه جا حذف شد؛ متن‌های برند «Laxis…» حذف شدند.
  • manifest.json: update_url فروشگاه حذف شد (که افزونه با ID لاکسیس آپدیت نشود)؛ name/description به نسخه‌ی محلی و بدون cloud تغییر کرد.

MCP روی server.py

سرور حالا در یک پراسس هم WebSocket (برای افزونه) و هم MCP stdio (برای Claude) را اجرا می‌کند و حافظه‌ی sessions را share می‌کنند. ابزارها: list_sessions، get_transcript، get_latest_transcript و resource با الگوی transcript://{session_id}. کانفیگ Claude Desktop در bridge/README.md.

درس‌آموخته‌ها

  • stdout برای MCP رزرو است: همه‌ی print ها به stderr منتقل شدند، وگرنه استریم JSON-RPC خراب می‌شود. برای تست دستیِ WebSocket باید از python server.py --ws-only استفاده کرد.
  • کد افزونه minified است: برای فایل‌های فشرده (meetingInfo.js) به‌جای حذفِ بدنه‌ها، با return; در ابتدای تابع خنثی‌سازی شد (کم‌ریسک‌تر). کدِ مرده باقی می‌ماند ولی هرگز اجرا نمی‌شود.
  • یک رشته‌ی غیرفعال باقی‌ست: متنِ «Autosave to Laxis cloud…» در displayGoogleMeetQuota (transcript.js) داخل کدِ مرده مانده — هرگز نمایش داده نمی‌شود چون فراخوان‌هایش خنثی‌اند.

تأیید (validation)

  • syntax همه‌ی فایل‌های JS با node --check پاس شد.
  • منطق server.py با AST + یک smoke test واقعیِ WebSocket (PONG/ACK + ذخیره‌ی صحیح فارسی) تأیید شد.
  • ابزار/resource های MCP با mcp SDK ساخته و اجرا شدند (get_latest_transcript متن را درست برگرداند).

باقی‌مانده برای تو

تست میدانی: venv را بساز/فعال کن، python server.py --ws-only را اجرا کن، افزونه را در chrome://extensions Reload کن، در یک Meet واقعی caption را روشن کن و خروجی را در bridge/transcripts/ ببین. بعد کانفیگ MCP را به Claude Desktop اضافه کن.