post / 2025.04.19

TypechoコメントをWalineにインポート

TypechoコメントをWalineにインポート

この記事は最終更新日:2025-04-19。記載内容が現在有効でない可能性がありますのでご注意ください。

数日前、ブログの記事をTypechoからHugoに移行しましたが、Front Matterのパラメータ設定や画像リンクの再設定だけでかなりの手間がかかりました。
ブログの価値は、まず記事そのものにあり、次にコメントです。コメントはブログがインターネットと現実世界に与えた影響を証明し、人と人との交流を記録しています。私的な言い方をすれば、世界中からのコメントは大切な思い出であり、「私」を構成する一部です。
したがって、元のサイトのコメントを新しいサイトの対応する記事の下にコピーすることは非常に重要です。

Walineの設定

WordpressやTypechoなどの動的ブログと比べて、静的ブログは外部のコメントシステムに依存するしかありません。選択肢は多く、それぞれに長所と短所があります。この記事を参考にし、各コメントシステムの公式サイトを調べた後、最終的にWalineを選びました。
Walineの中国語ドキュメントは内容が充実しており、LeanCloudデータベースとVercelサーバーを設定すれば、コメント管理画面https://<あなたのサーバードメイン>/ui/にアクセスできます。初回登録で管理者になり、ここでコメントやユーザーを管理できます。

Typechoコメントのエクスポート

Typechoは古く、ユーザーが少なく、HexoやWordpressのような活発なコミュニティがありません。インターネット上の資料も少ないです。
筆者が見つけたのは、怡红院落氏が書いたTypechoコメントをValineにエクスポートするプラグインExport2Valine(Walineのドキュメントにも記載されています)だけでした。
しかし、最後の更新は3年前で、テストしたところ最初のコメントしかインポートできませんでした。エクスポートされたjsonlファイルを見ると、コメントデータは完全にエクスポートされていることが明らかです。

まず、このプラグインをTypechoにインストールします(プラグインフォルダ名を"Export2Valine"に変更する必要があります!)。

この記事を参考に、このプラグインは長年メンテナンスされていないため、いくつかの変更が必要です。
プラグインフォルダ内のAction.phpを開き、42行目から以下のコードに変更します(親コメントを追跡するため):


$arr = array(
  "objectId" => $comment["coid"],
  "QQAvatar" => "",
  "comment" => $comment["text"],
  "insertedAt" => array(
    "__type" => "Date",
    "iso" => $time
  ),
  "createdAt" => $time,
  "updatedAt" => $time,
  "ip" => $comment["ip"],
  "link" => $comment["url"],
  "mail" => $comment["mail"],
  "nick" => $comment["author"],
  "ua" => $comment["agent"],
  "url" => "/{$slug}.html"
);

if($comment["parent"]) {
  $arr["pid"] = $comment["parent"];
  $arr["rid"] = $this->getRootId($comment["coid"]);
}

他の部分は変更不要です。
次に、Typechoの管理画面-コントロールパネル-コメントエクスポートで、ダウンロードしたjsonlファイルを開き、先頭の#filetype:JSON-streaming {"type":"Class","class":"Comment"}\n\nを削除します。
保存してファイルを閉じ、ファイル拡張子を.jsonに変更します。

json形式の修正

エクスポートされたjsonlファイル内の中国語はエスケープされ、1行で表示されるため、見づらい状態です。
編集可能でインポートしやすいjson形式に変換するため、まずエディタの検索と置換機能を使用し、}\n{を以下のように置換します:

},
{

Xcodeの置換では、改行文字は左側の虫眼鏡アイコンをクリックして挿入できます。

これで、1行に1つのコメントオブジェクトが表示されます。

同様に、各コメントオブジェクト内のフィールド構造を分離するため、","を以下のように置換します:

",
    "

これで、各コメントオブジェクト内に複数のデータが含まれていることがわかります。例えば:

{"objectId":"3",

    "QQAvatar":"",

    "comment":"\u6d4b\u8bd5\u4e00\u4e0b",

    "insertedAt":{"__type":"Date",

    "iso":"2023-06-27T09:37:07.000Z"},"createdAt":"2023-06-27T09:37:07.000Z",

    "updatedAt":"2023-06-27T09:37:07.000Z",

    "ip":"223.104.150.16",

    "link":**null**,"mail":"2868301418@qq.com",

    "nick":"2868301418",

    "ua":"Mozilla\/5.0 (Linux; Android 13; V2171A Build\/TP1A.220624.014; wv) AppleWebKit\/537.36 (KHTML, like Gecko) Version\/4.0 Chrome\/109.0.5414.86 MQQBrowser\/6.2 TBS\/046605 Mobile Safari\/537.36 V1_AND_SQ_8.9.63_4190_HDBM_T QQ\/8.9.63.11380 NetType\/4G WebP\/0.3.0 Ap",

    "url":"\/\u4ea4\u53cb\u6807\u51c6-\u548c\u5e73\u5171\u5904\u4e94\u9879\u539f\u5219.html"},

  {"objectId":"4",

    "QQAvatar":"",

    "comment":"\u600e\u4e48ip\u4e0d\u5bf9",

    "insertedAt":{"__type":"Date",

    "iso":"2023-06-27T09:38:15.000Z"},"createdAt":"2023-06-27T09:38:15.000Z",

    "updatedAt":"2023-06-27T09:38:15.000Z",

    "ip":"223.104.150.16",

    "link":**null**,"mail":"2868301418@qq.com",

    "nick":"2868301418",

    "ua":"Mozilla\/5.0 (Linux; Android 13; V2171A Build\/TP1A.220624.014; wv) AppleWebKit\/537.36 (KHTML, like Gecko) Version\/4.0 Chrome\/109.0.5414.86 MQQBrowser\/6.2 TBS\/046605 Mobile Safari\/537.36 V1_AND_SQ_8.9.63_4190_HDBM_T QQ\/8.9.63.11380 NetType\/4G WebP\/0.3.0 Ap",

    "url":"\/\u4ea4\u53cb\u6807\u51c6-\u548c\u5e73\u5171\u5904\u4e94\u9879\u539f\u5219.html"},

共通フィールドの説明

  1. objectId: コメントの一意の識別子(例: “4"や"5”)
  2. QQAvatar: QQアバターのリンク(現在は空文字列)
  3. comment: コメント内容(Unicodeエスケープ文字を含む、例: \u600e\u4e48は「どうやって」を意味)
  4. insertedAt/createdAt/updatedAt: タイムスタンプ(ISO 8601形式)
  5. ip: コメント者のIPアドレス
  6. link: コメント者が提供したリンク(nullの場合あり)
  7. mail: コメント者のメールアドレス
  8. nick: コメント者のニックネーム
  9. ua: ユーザーエージェント(ブラウザ/デバイス情報を表示)
  10. url: コメントされたページのパス

特殊フィールド

  1. pid: 親コメントID
  2. rid: ルートコメントID

"link"の値がnullの場合、"link"と"mail"の間に改行がありません。jsonは改行に敏感ではないため、無視できます。
この時点で、ファイルの先頭と末尾を[ ]で囲み、ファイルを保存します。

コメント属性の修正

この時点でLeanCloudに直接インポートできますが、まだ修正可能な内容があります。

Export2Valineはコメントに関連する記事のurlを\/slugに設定しています。例えば"url": "\/Summary-of-the-First-Semester-of-Junior-Year.html"で、\/は/のエスケープです。

新しいブログの記事とコメントを関連付けるため、urlを新しいブログの記事リンクに手動で変更する必要があります。

筆者のブログを例にすると、Hugoが生成するウェブサイトのルートディレクトリにはzh-cn,zh-tw,en,jaの4つのフォルダ(多言語対応を有効にしている)があり、中国語サイトの記事は/zh-cn/post/記事カテゴリ/にあります。
筆者はローカルのブログソースファイルで記事をカテゴリごとに異なるフォルダに分類しています。例えば/content/post/Thoughts/最近書いた詩.mdはウェブページの相対アドレスzh-cn/post/thoughts/最近書いた詩として生成されます。

新しいブログの記事がルートディレクトリにあり、名前が変更されていない場合は、urlを変更する必要はありません。
すべての記事が/post/にある場合は、検索と置換を使用して

"url":"\/

を

"url":"\/post\/

に置換できます。

筆者は一時的に

"url":"\/zh-cn\/post\/

に置換しました。

同様に、友達リンクやつぶやきなどの独立ページのコメントも、新しいブログの対応するページの相対アドレスに変更する必要があります。 例えば友達リンクページ

"url":"\/links.html

を

"url":"\/zh-cn\/friend\/

に置換します。

postや独立ページで大規模に適用できる検索と置換を先に適用しないと、インポート後に一括置換が困難になります。

検索と置換を使用する際は、できるだけ多くの共通部分を含め、「最大公約数」を見つけて誤った変更を避けてください。
エスケープ\/に注意!!!

LeanCloudへのインポート

LeanCloudのコントロールパネル-データストレージ-インポート/エクスポートで、修正したjsonファイルを選択し、ClassにCommentと入力してインポートします。

注意、もし以前にブログのWalineでテストコメントを投稿したことがある場合、またはCommentのインポートを試みたことがある場合、Walineは最初にComment Classを作成するため、再度インポートしてもデータが正常にインポートされません(LeanCloudは成功を報告しますが、新しいデータはインポートされません)。

コントロールパネル-構造化データでCommentを選択し、このClassを削除してから再度インポートを試みる必要があります。LeanCloudのページはすぐに更新されない場合があるため、Ctrl+F5でキャッシュをリフレッシュすると表示されます。

インポートが成功したら、各コメントのurlを個別に設定します。
例えば筆者のpostは"url":"\/zh-cn\/post\/記事カテゴリ\/に分類する必要があり、この時点でLeanCloudの一括操作と条件付きフィルタリング機能を活用します。

後書き

コメントの整理にはそれほど時間がかかりませんでした。120件のコメントのほとんどは筆者がつぶやきページで自分自身に語りかけたもので、urlを一括修正できました。他人からのコメントはわずか十数件で、数記事に分散していたため、postでフィルタリングして修正するのは簡単でした。これは良いことなのか悪いことなのか(笑)

独り言であれ、他人からのメッセージであれ、一つ一つが筆者にとって特別な意味を持ち、時間を置いて振り返ると新たな気付きがあります。
最初に述べたように、これは筆者の成長の軌跡であり、この世に存在する証であり、「私」の一部です。

そして、親愛なる読者であるあなたは、私に価値を与えてくれる存在です。

時間があれば、ぜひコメントをください~筆者は本当に長く喜びます(善意のコメントであれば)。

著者: 孤筝

タイトル: TypechoコメントをWalineにインポート

公開日: 2025-04-19

更新日: 2025-04-19

ライセンス: CC BY-NC-SA 4.0

いつまた一杯の酒を飲み、細かい論文を議論するのか。

検索