ハトネコエ Web がくしゅうちょう

プログラミングやサーバー・Web制作、チームマネジメントなど得た技術のまとめ

esa から Notion へ API を駆使して移行した話

esa から Notion へと死ぬほどがんばって移行したので、その記録を残しておきます。

esa にあった画像やコメントなども、API を駆使して移行しています。

1. 前置き

後述しますが、このやり方は完璧でない部分があります。
一部のデータが消えるという覚悟が必要です。

また、Notion は多機能で便利ですが、
esa に比べると検索機能はやや弱いです。

多機能ゆえ、TODOリストなども統合する都合でページ数が多くなり、
結果、求めるページが検索結果から見つけづらかったり、検索結果に出てこないことがあります。

書き心地や情報の探しやすさで言えば esa に軍配が上がると個人的には思います。
(あと、今回の移行で思ったけど esaAPI が親切。Notion API はベータ版だったってこともあるけど出来ること少なすぎてストレスフルだった)

移行・検証期間は長めに取ると良いでしょう。
Notion が内部的にはマークダウンじゃない影響で、他のドキュメントツールへの移行作業は難しそうに感じますし。

2. Notion のマークダウンインポートの罠

Notion には Import 機能があります。

f:id:nekonenene:20220314235002p:plain
Notion の Import 機能

esa には Markdown エクスポート機能があります。

f:id:nekonenene:20220314235126p:plain
esa のエクスポート機能

つまり、この2つを合わせれば、簡単にインポートできる!!!

・・・と思いますよね?

私もそう思っていました。
ところがそう上手くはいきません。

罠1. フォルダ単位でしかインポートできない

これは実際に Notion の Import 機能を使ってみると気付くことなのですが、
インポートするマークダウンファイルはフォルダ単位でしか選べません

1フォルダを選んで、再帰的にディレクトリを掘っていって取り込む、なんてことは出来ません。
エクスポートした esa のフォルダ構成は、元の階層通りになっているので、そのファイルすべてを取り込んでいくのは至難の業(わざ)です。

罠2. GitHub Flavored Markdown を解釈しない

esa は GFM こと GitHub Flavored Markdown にほぼ準拠で書けます。
なので、改行のために文末にスペースを2つ置く必要はありませんし、
URLをそのまま記載してもリンクになってくれます。

しかし、Notion の Import 機能では残念ながら GitHub Flavored Markdown として解釈しないので、
esa のときにあった改行は消えてしまうし、URL文字列はリンクじゃなくなってしまいます
コードブロックの言語設定も消えます。

罠3. テーブルの中の画像やリンクが消える

これは今回の移行作業後に気付いたのですが、
テーブルの中に画像が貼り付けてある場合、消えて、ただの空欄になります

Notion の Import 機能で、テーブルは Notion で言うところの「データベース」というものに変換されるのですが、
これへの変換が癖のある感じで、画像が消えたり文字へのリンクが消えたり残念なことになります……困る……。

罠4. Notion は見出し3までしかない

Notion は見出しが3までしかありません。
ですので、esa での ### , #### , ##### の見出しはインポート後、全て同じ大きさの見出しになります。

人によってはマークダウンで書く記事の見出しを ##### から書き始めるので、
そういう人の記事は移行後にやや残念な感じになります。
まあ、上3つの罠に比べれば些細(ささい)なことですね。

他には、箇条書きの内側に記されたコードブロックが正しくパースされないという細かなバグもあります。

3. HTML インポートを使おう

そんなこんなで、esa から Notion への移行は、想像ほど簡単におこなえません……。

罠1と罠2は致命的です。
(罠3も致命的ですが、これを回避するには Notion のインポート機能を使わずに API を介してページを作っていくしかなさそう)

これらの問題を解消するために esa-dumper-for-notion というものを書きました! ↓

READMEを読めばなんとなくわかると思いますが、
罠1と罠2の問題を解消するために、
1フォルダにすべての記事のHTMLファイルを書き出すという処理をおこなっています。

上部に esa の記事IDや作成者・作成時刻などを書きつつ、
下部にはコメント一覧を書き出してくれます。

これがおこなえたのは、
esaAPI が、記事やコメントの Markdown だけでなく、レンダリング時の HTML まで返してくれるからです。esaAPI 素晴らしいです!

HTMLファイルで書き出したあとにインポートすれば、
esa で改行されていた箇所やリンクがしっかりと再現されます。

f:id:nekonenene:20220315004350p:plain
Notion の Import 機能(HTMLでインポートする)

なお、5000以上ある記事を一度にインポートしようとしたら途中でエラーを吐いたので、
2回に分けてインポートしました。

4. notion-py をフル活用する

『Notion(非公開)APIで画像をアップロードする』API%E3%81%A7%E7%94%BB%E5%83%8F%E3%82%92%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%99%E3%82%8B)の記事を書いた neneka さんのフォークした notion-py を利用しました。

Notion API の公式ライブラリとしては notion-sdk-js があるのですが、
Notion API (2022/03/03 にようやくベータ版から正式版になった)では Notion への画像アップロードがおこなえません

esa にアップロードされていた画像を Notion にアップロードし直さないと、
esa の解約時に画像が消えてしまいます。

裏道的な手段で画像アップロードをおこなう notion-py があるおかげでギリギリなんとかなりました。

インポートした記事たちを加工する esa-to-notion-py がこちらです! ↓

このアプリケーションによって、

  • esa にアップロードされた画像を Notion に上げ直し
  • リンクURLを esa から Notion のものに変換
    (※移行後に気付いたのだけど、テーブル内にあるリンクURLを変換できていない)
  • 3. の手順で1フォルダにしてからインポートしたので、階層構造を再び作成する
    (※一度おこなうとやり直しが効かないので注意)

の3つをおこなうことができます。

記事数によりますが、時間はけっこうかかります
私はサーバーを建てて nohup で実行させました。

nohup python esa-image-to-notion 1234567890abcdef1234567890abcdef > esa-image-to-notion.log 2> error.log &

みたいな。

5. 今回の対応で移行できなかった点

今までに記載したことの繰り返しも含めて、移行できなかったポイントをまとめます。

  • テーブル内のアレコレ
    • テーブル内の画像が消えます
    • テーブル内の文字列に対するリンクがリンクでなくなる場合があります
    • 考慮不足により、テーブル内にある esa の記事URLを Notion の記事URLに書き換えることが esa-to-notion-py でおこなえません
    • 『罠3. テーブルの中の画像やリンクが消える』の項で記載しましたが、テーブルの移行はデータベースに変換されるぶん、つらみが多い。より普通のテーブルに近いシンプルテーブルに関しても縛りが多すぎるし……
  • esa にアップロードした画像以外のファイル
    • notion-py でアップロードできない関係で、画像以外のPDFやzipなどは移行できていません
  • コードブロックの言語設定

他にもなにかあったかもしれませんが、
単純に Markdown インポートをおこなうよりはだいぶいい感じになりました。

6. おわりに

めっっっちゃしんどかった!!!

事前調査では 2. で書いたように「マークダウンのインポートできるんだ、楽勝じゃ〜〜ん」って思っていたので、
そのぶん、上手く行かないところが次々と発覚していったときの絶望がヤバかったです。

Notion は世界中で使われてるから API もしっかりしてるでしょ〜、って思っていたら
驚くほど使いにくくて、Notion API を使って記事を書くのはそうとうしんどそうに感じました。

2022/03/03 に正式版になってから多少改善が入ったそうなので、自分が見たときよりは少しマシかな、と思っていま見てみましたが、やっぱり厳しそうです……。
Paragraph block にマークダウンテキストを渡したら解釈してくれれば少し楽なんだけど、Rich text object を書かなくちゃいけないのはつらい……。

Notion がファイル保管庫として使われるのを避けるために永遠に搭載されないかもだけど、
画像やファイルをアップロードするAPIエンドポイントも欲しいなあ……。
Notion API が今後良くなっていくことに期待したいです。