PDF to ImageBlocks ショートカットの作成 : hkob の雑記録 (348)

はじめに

hkob の雑記録の第348回目は、Notion の二つのアップデートです。本記事は2025年ユカスタマスの14日目(2023年ユカスタマスの745日目)の記事になります。

きっかけは学生のアドベントカレンダー

12月の Notion 座談会では、海外のアンバサダー、日本一般、日本学生のアドベントカレンダーを初回しています。今回もいろんな人の使い方が見られて面白かったのですが、その中でかぷちーのさんの記事が話題になりました。

その中で気になったのは以下の文章でした。

加えることがあるとすれば、レジュメがPDF形式しかない場合。

私はNotionで1枚ずつスライドを表示したい派なので、わざわざPDFダウンロード→ChatGPTでjpegに変換→zipにして保存→Notionに持ってくるとかいう非効率でしかない方法をとっています…。

以前も誰かの記事で同じ話があった気がしますね。座談会の中でも、先日の名刺でファイルアップロードを実装したばかりなので、すぐに作れそうですという話になりました。夜遅かったので、翌朝から実装に入りました。

実装

PDF の取得と定数設定

最初は共有シートから PDF を受け取るようにします。単にアプリとして起動した時には、クリップボードから PDF を取得します。また、いつものように NOTION_API_KEYdata_source_id を記録しておきます。

PDF の取得と定数設定

タイトル入力とページ作成

次にページタイトルを入力します。次に入力したテキストをタイトルとしたページを作成します。後でこのページに block を挿入するので、レスポンスから id (page_id) を取得しておきます。

タイトル入力とページ作成

ページを Notion で開く

ページが作成できたので、レスポンスから取得した url を使って、ページを Notion で開きます。URL scheme を notion に変更して URL を開きます。

ページを Notion で開く

PDF を分割して JPEG に変換

次に入力された PDF をページ分割してページごとに JPEG に変換していきます。PDF のページ分割が簡単にできるのがショートカットアプリの便利なところですね。

PDF を分割して JPEG に変換

分割されたページのテキストを取得

次に PDF ページからテキストを取得し、改行文字を \n という文字列に変換します。単体の RichText object の最大サイズが8000バイトなので、先頭の2000文字分だけ取り出しています。真面目にやるなら複数の RichText object の配列に変更するのですが、今回はサボって先頭の2000文字だけの抽出にしています。

分割されたページのテキストを取得

FileUpload object の作成

次にファイルをアップロードするための FileUpload object を作成します。指定された upload_url にファイルをアップロードします。その後、ここで取得した id をさまざまな FileObject としてブロックなどに接続します。

FileUpload object の作成

ファイルアップロード

ファイルアップロードは非常に単純でフォームで送信するだけです。

ファイルアップロード

追加する ColumnList block の json 作成

ここまで準備できれば、追加する ColumnList block の payload json を作成します。流石にこれは手書きできないので、NotionRubyMapping に作成してもらいます。

# ColumnListBlock を作成 (ImageBlock と ParagramBlock を並べたもの)
block = ColumnListBlock.new [
  ImageBlock.new("https://cdn.worldvectorlogo.com/logos/notion-logo-1.svg", caption: "Notion logo"),
  ParagraphBlock.new("abc")
]
=> NotionRubyMapping::ColumnListBlock-

# 適当なページを取得
page = Page.find "https://www.notion.so/abc-2c70ce2a652081599aaec1aabd14434f"
=> NotionRubyMapping::Page-2c70ce2a652081599aaec1aabd14434f

# このページに上のブロックを追加するスクリプトを作成
print page.append_block_children block, dry_run: true
#!/bin/sh
curl -X PATCH 'https://api.notion.com/v1/blocks/2c70ce2a652081599aaec1aabd14434f/children' \
  -H 'Notion-Version: 2025-09-03' \
  -H 'Authorization: Bearer '"$NOTION_API_KEY"'' \
  -H 'Content-Type: application/json' \
  --data '{"children":[{"type":"column_list","object":"block","column_list":{"children":[{"type":"column","object":"block","column":{"children":[{"type":"image","object":"block","image":{"type":"external","external":{"url":"https://cdn.worldvectorlogo.com/logos/notion-logo-1.svg"},"caption":[{"type":"text","text":{"content":"Notion logo","link":null},"plain_text":"Notion logo","href":null}]}}]}},{"type":"column","object":"block","column":{"children":[{"type":"paragraph","object":"block","paragraph":{"rich_text":[{"type":"text","text":{"content":"abc","link":null},"plain_text":"abc","href":null}],"color":"default"}}]}}]}}]}'=> nil

ここでは簡単のために external な画像ブロックにしましたが、今回はこの部分を file_upload に変更すればいいだけです。また、テキストの部分は先ほど取り出した先頭の 2000 文字を置いています。

追加する ColumnList block の json 作成

block の追加処理

最後にこの payload を使って、ブロックを追加します。URL の中に最初に作成した page_id が含まれるので、ここでもテキストを使って page_id の埋め込みをしています。

block の追加処理

動作確認

うまく設定できたので、動作確認をしてみました。様子を X にポストしたので、こちらをご覧ください。

実際に PC 版の画面では、横に2列で表示されています。無事に動作しているようです。

動作確認

おわりに

確かに学生に配布された PDF にコメント書きたければこういう形でページが作成されると便利そうだなと思いました。とりあえずこちらからショートカットを配布してみますので、皆さんでブロックの構成などをカスタマイズしてみてください。

www.icloud.com

hkob.notion.site