日が経過しています。情報の鮮度にご注意ください
はじめに
2021年にブログ自動化についての記事を書きましたが、当時はCraftの画像処理がうまくいかず、ロジックが複数のリポジトリに分散していて参考になりませんでした。その後、Craftから直接画像をアップロードできるか検証しましたが(結論は不可)、最近ようやく週末を使って腾讯云への画像転送問題を解決しました。さらにGithub PagesからVercelに移行したことで速度も大幅に向上したので、以下に記録します。
注:おそらく今後も「202x年の私のブログ自動化プロセス」のような記事を書くことになるでしょう。技術は進化し、時代は変化し、私は相変わらず弄り回していますから🤣
本文
全体の流れ

詳細説明
⓵ Craftドキュメント
特定のフォーマットで書かれたブログ記事を指します。このフォーマットとは、以下の条件を満たす必要があり、正しくリポジトリに同期されます:
-
ドキュメントの最初の要素はmeta情報を含むtable要素であること。
-
meta情報では、titleは記述不要(ドキュメントデータから直接取得)、headerImgとimgの著作権情報(unsplashからアップロードした場合)も記述不要。
-
Drawing要素はサポートされません(有効な画像拡張子のファイルを生成できないため)。存在する場合COSにアップロードされず、正常に表示されません(Craftのプライベートファイルタイプだからです)。
⓶ Craftプラグインリポジトリ(公開)
Craftに適用するプラグインで、Craftドキュメントの内容を取得し、処理後にリポジトリにアップロードします。Craftプラグインの詳細はこちら、私が作成したこのプライベートプラグインのアドレスはこちらです。
プラグインの役割は、Craftのドキュメント内容をMarkdown形式に変換し、Github REST APIを使用して固定のリポジトリ位置(craft_publish_ciリポジトリのcontent.mdファイル)に送信します。ファイルが既に存在する場合は内容が置き換えられます。リポジトリアドレスは公開されており、こちらから確認できます。
⓷ craft_publish_ciリポジトリ(公開)
このリポジトリは主にGithub Actionを使用して画像を処理します。プラグインからコンテンツを受信した後(つまりcontent.mdファイルが更新された後)、そのファイルの内容を読み取り、Markdownファイル内の画像(![で始まるブロック要素が画像と判定され、特別なheaderImgで始まるヘッダー画像)を取得し、Tencent Cloud COSに転送して保存します。統一性と利便性のため、画像を取得した後、Action内で一律にjpg形式に変換します。これにより、画像のアップロードが必要ない場合(テキストのみの修正)でも、ドキュメント内の画像アドレスを直接置換するロジックが容易になります。なぜなら、一部の画像はpngやjpgのような一般的な画像形式ではなく、拡張子がない場合もあるからです。以前は、画像を取得する際のレスポンスcontent-typeを使用して画像に拡張子を追加しようと試みましたが、tiff形式の画像の場合、content-typeがapplication/octce-stream(スペルミスでなければ)と返されることがあり、さらにこの方法ではドキュメント内のすべての画像を先に取得する必要があるため、BANされる恐れがありました。そのため、まずアップロードが必要な画像をすべてjpgに変換することにしました。その後、CDNアドレスを取得し、ドキュメント内の対応する画像アドレスをCDN画像アドレスに置き換えます。完了後、ファイルの内容を実際のブログリポジトリであるx_blog_srcに送信します。
⓸ x_blog_src リポジトリ(プライベート)
このリポジトリはpush更新を受信すると、Actionを実行し、HTMLファイルをビルドして公開ブログリポジトリx_blogに送信します。この理由について詳しくはこちらを参照してください。
⓹ x_blog リポジトリ(公開)
このリポジトリはVercelにその内容を読み取る権限を付与し、デプロイされます。カスタムドメインがバインドされているため、www.xheldon.comにアクセスすることで閲覧できます。Github Pagesを使用しない理由は、前者の方がよりプロフェッショナルであり、専用のグローバルCDNアクセラレーションがあるためです。一方、Github Pagesはドメイン解決が遅く、CDNアクセラレーションがありません。ドキュメントサイトとしては問題ありませんが、ブログとして最適化されていないのは適切ではないと感じます。
ブログにはNotionデータソースを非同期リクエストするページが存在します。例えば購読管理]ページで、このプロセスもVercelのserverlessを利用しており、サーバーサイドでNotionのdatabaseにリクエストを転送しています。このインターフェースは汎用的に設計されており、POSTでNotion databaseのヘッダーとdatabaseIdを送信できるようにしています。これにより、今後Notionへの非同期リクエストが必要な追加ページがあっても対応しやすくなっています。
人生の重要な選択に直面したとき、最善の方法を誰かが教えてくれて、貴重な時間を無駄にせずに済めばと、私はよく願っています。だからこそ、自分の経験を踏まえて頻繁にブログを書き、広大なインターネットのこの小さな片隅に、私にとって一度きりの人生経験を記録し、助けを求める人々の力になれればと思っています。