---
title: Notion Electronリバースエンジニアリング:クリップボード-REA
url: https://rea.tools/ja/showcase/notion/
---

[ホーム](https://rea.tools/ja/) / [展示会のご案内](https://rea.tools/ja/showcase/) /Notion

ケーススタディ·Electron

# どのようにNotionコピー テキストとHTML。

NotionのページAPIから、プリロードとメインプロセスを介してElectronのクリップボードライターにクリップボード呼び出しをトレースします。

Notionデスクトップ7.6.1·JavaScript\*REA

Notionのデスクトップパッケージ内のブリッジ

1. 01\*ページに直面するAPI

   `clipboard.write(data)`

   プリロードは呼び出し可能なメソッドを公開します。
2. 02\*プリロードラッパー

   `ipcRenderer.invoke`

   Wrapperはチャンネルと引数を送信します。
3. 03\*メインプロセスハンドラー

   `ipcMain.handle`

   受信者は、どのページが送信されたかを確認します。
4. 04\*システムクリップボード

   `clipboard.write(data)`

   Electronは、指定されたテキストとHTMLを書き込みます。

一つのチャネルは、二つの側面を結合します: `notion:clipboard:write`

パッケージ化されたコードは、プリロードプロセスとメインプロセスで同じチャネルを使用します。 ラッパーを解決すると、これらの名前の背後にあるElectron呼び出しが明らかになります。

## コピー操作はどこに行きますか？

ページには、次のようなメソッドが表示されます `clipboard.write`. プリロードでの実装はラッパーです。 有用な質問は、そのラッパーが何を送信し、どのコードがそれを受信するかです。

あなたのコーディングエージェント

REAを使用して、NotionがテキストとHTMLをシステムクリップボードにコピーする方法を追跡します。 各ステップでコードを表示します。

コーディングエージェントが使用できるNotionのローカルアプリケーションパッケージを使用した例のプロンプト。

### REAは、読み取りを開始する場所を検索します

REAを使用してタブプリロードを分析すると、ページに公開されているAPIとIPC要求を送信する呼び出しが検索されます。 どちらの調査結果も、縮小されたバンドルのソース範囲が付属しています:

REA調査結果→二つの場所を開く

公開されたページAPI

```
api_key: "__electronApi"
api_status: "dynamic"
source: preload.js:1:22764–22828
```

レンダラIPCコール

```
operation: "invoke"
channel_expression: "e"
source: preload.js:1:6486–6522
```

新鮮なから選択されたフィールド `analyze_javascript_application` Notionのタブプリロードの結果、REA4.1.0で記録されました。 ポジションは、元のバンドルのラインとゼロベースの列を使用します。

エージェントはこれらの場所を開き、組み立てられたAPIでclipboardメンバーを見つけて、次のように `invokerInMain`. そのコールサイトの供給 `notion:clipboard:write`. この名前は、エージェントにメインバンドルで探すための正確な何かを与えます。 以下の4つの抜粋は、それが接続するルートを示しています。

### コードの4つの短い部分

パッケージ化されたJavaScriptから簡略化され、可読な変数名が付いています。 無関係なメンバーは省略されます。

1. #### ページに公開されているAPIから開始します

   tab_browser_view/preload.js-APIメンバー

   ```
   const clipboardApi = {
     write: invokerInMain("notion:clipboard:write")
   };

   // Included in the API exposed through contextBridge:
   // window.__electronApi.clipboard
   ```

   このメンバーは、チャネル名を指定します。 の実装 `invokerInMain` リクエストがページのプロセスからどのように離れるかを示します。
2. #### プリロードのラッパーを解決する

   tab_browser_view/preload.js\*IPCヘルパー

   ```
   function invokerInMain(channel) {
     return (...args) => invokeInMainAndReturnResult(channel, ...args);
   }

   function invokeInMainAndReturnResult(channel, ...args) {
     return ipcRenderer.invoke(channel, ...args);
   }
   ```

   返された関数は、Electronの要求と応答IPCを介して引数を転送します。 私たちは今、探すことができます `notion:clipboard:write` メインプロセス側。
3. #### 受信機の登録方法を確認する

   メイン/index.js \*ハンドラーヘルパー

   ```
   const handleRequestFromRenderer = {
     addListener(channel, handler) {
       ipcMain.handle(channel, handler);
     }
   };
   ```

   メインプロセスは別のラッパーを使用します。 その `addListener` メソッドを登録します。 `ipcMain.handle` そのチャンネルの受信機。
4. #### 書き込みとその送信者チェックを見つけます

   メイン/index.js \*クリップボード受信機

   ```
   handleRequestFromRenderer.addListener(
     "notion:clipboard:write",
     (event, data) =>
       isNotionWebContents(event.sender)
         ? clipboard.write(data)
         : undefined
   );
   ```

   これが目的地です。 送信者を確認した後、ハンドラーは提供されたデータをElectronのクリップボードAPIに渡します。 チャネルと2つの解決されたラッパーは、公開されたメソッドをこの呼び出しに接続します。

## コピーされたブロックはどのようにその構造を保持しますか？

Notionのwebエディタは、テキストとHTMLを介して送信します `electronApi.clipboard.write`. ブロックデータをローカルに保持し、コピーされたHTMLにIDを入れて接続します。

保存されたブロックデータへのHTMLリンク

システムのクリップボードに送信されます

```
text: "Project notes"
html: "<p>Project notes</p>"
    + "<!-- notionvc: <copy-id> -->"
```

Notionによってローカルに保存されます

```
id: <copy-id>
mimeTypes:
  text/_notion-blocks-v3-production
    → structured block data
```

1. HTML IDを読み取る
2. 同じローカルIDを検索する
3. Notionブロックデータの復元

例示的なテキストとID。 記録されたモジュールテストでは、Idが一致するとブロックデータが復元されます。

貼り付け時に、NotionはHTML IDを探し、保存されたコピーと照合します。 一致するIdは、ブロックデータを復元します。

2026年7月13日にキャッシュされたwebアセットから記録されたクリップボード形式。

## より多くの例とソース

別の例：Markdownテーブル

NotionはMarkdownをブロックデータに解析します。 この例では、テーブルがヘッダー行とデータ行になる方法を示します。

NotionのMarkdownパーサーを介したテーブル

マークダウン入力

```
| A | B |
| - | - |
| 1 | 2 |
```

構造化パーサー出力\*抜粋

```
table · headerRow: true
  table_row
    cells: ["A"], ["B"]
  table_row
    cells: ["1"], ["2"]
```

抽出されたMarkdownパーサーからの出力を記録しました。 テーブルは行とセルになります。


別のパス：オフラインSQLite接続

Notionのレンダラリクエスト `getSqliteMeta` IPCを介して。 メインプロセスはメッセージチャネルを作成し、1つのポートをレンダラーに、もう1つのポートをSQLiteユーティリティプロセスに提供します。 後続のステートメントのバッチと結果は、そのポート上を移動します。

このハンドオフに続いて、データベース作業がどこで実行されるか、および最初のIPC要求のみをトレースすると後の会話が失敗する理由を説明します。


出典と抜粋の読み方

クリップボードブリッジはNotionデスクトップ7.6.1から来ています `app.asar`：タブのプリロードと `main/index.js`. 抜粋は、縮小された変数名を展開し、無関係なコードを省略します。sender-checkヘルパーは、その基礎となるもので表示されます `isNotionWebContents` 呼び出します。

仮想クリップボードとMarkdownの例は、モジュールを含む2026年7月13日にキャッシュされたwebアセットからのものです `747001`, `58169`, `736810` と `422457`. これらのアセットには独自のバージョンがあります。 保存されたプローブは、抽出されたモジュールと小さなハーネスを実行しました。

ここに示されているREAの結果は、公開されたREA4.1.0パッケージで記録された、保存されたタブプリロードの集中分析です。 これは、APIを検索し、操作を呼び出します。 クリップボードメンバーと一致する受信機は、パッケージ内のラッパー実装を読み取ることによって接続されます。

Markdownの例では、パーサーモジュールを使用しています `422457`. 保存されたモジュールのテストでは、ページフィルタとチャットフィルタの両方がこのテーブルを保持することが示されています。 Paste/import、structured Markdown、AI/chatパーサーには、別々のエントリポイントと中間形式があります。

- [JavaScriptアプリケーションガイド](https://rea.tools/guides/javascript/)小さなElectronアプリケーションのエクスポート機能に従ってください。
- [DX-Ball再構成](https://rea.tools/ja/showcase/dx-ball/)チェックされたC関数へのネイティブの指示に従ってください。

[独自のアプリを分析する](https://rea.tools/get-started/)
