あなたの記事で、いちばんコピーされているのは、どの文でしょうか。
読者がどこをコピーしているのかは、ふだんはまったく見えません。
それを見えるようにするプラグイン、「Rapls Copy Notice」を作って、WordPress.orgで無料で公開しました。
読者が本文をコピーすると、コピーされた文をログに残して、管理者にメールで知らせます。コピーそのものは止めません。
コピーは、止めても止まらない
本文のコピーに困ったとき、最初に思いつくのは「止める」ことです。
右クリックを禁止する。文字を選べなくする。そういうプラグインは、今もたくさんあります。
でも、止まりません。
ページのソースを開けば文は読めます。スクリーンショットも撮れます。本気で持っていきたい人は、どの方法でも持っていきます。
困るのは、普通の読者のほうです。引用したい人、メモを取りたい人、読み上げや翻訳の機能を使う人。止める仕組みは、そういう人の手を止めてしまいます。
止めずに、何がコピーされたかを知らせる。
Rapls Copy Noticeは、その考え方で作っています。
同じ目的のプラグインには、もう一つ前例があります。
コピーの報告は、ログインしていない誰からでも届きます。中身は、すべて訪問者のブラウザーが作ったものです。それを管理画面にそのまま表示したことで、蓄積型のXSS(クロスサイトスクリプティング)を抱えたプラグインがありました。
このジャンルのプラグインは、訪問者が送ってくる値をどう扱うかで、そのまま穴になります。
何をするプラグインか
読者が投稿の本文から20文字以上をコピーすると、コピーされた文と投稿をログに残し、サイトの管理者にメールで知らせます。メールは既定で1時間に1回のまとめで、コピーのたびにすぐ1通、にも切り替えられます。
届くメールは、こんな形です。

「>」で始まる行が、コピーされた文です。その下に日時、投稿、URL、文字数、短くしたIPアドレス、ブラウザー、どこから来たかが並びます。
メールのほかに、管理画面の「ツール」→「Rapls Copy Notice」のログでも一覧できます。下の画面のように、投稿で絞り込めます。

ほかにも、いくつかの機能があります。
同じ段落からのコピーをまとめて見る機能。どの段落がよく持っていかれているかが分かります。ダッシュボードには、直近7日間のコピー数と、よくコピーされた投稿の上位3件が出ます。サイトヘルスには、メールが送れているか、毎時の処理が止まっていないかを見る検査が6つ入ります。
読者向けには、コピーしたあとに「引用するときはリンクをお願いします」といった短いメッセージを出す機能と、コピーした文の後ろに投稿のタイトルとURLを付ける機能があります。どちらも既定ではオフです。
以前 Check Copy Contents を使っていた方へ
同じ用途のプラグインに、日本製の「Check Copy Contents」(CCC)がありました。WordPress.orgでの配布は2019年4月25日に止まっていて、更新はもう来ません。Rapls Copy Noticeは、CCCのコードを引き継いだものではなく、一から書いた別のプラグインですが、同じ使い方ができるようにしています。
移るのに、手間はほとんどかかりません。CCCの設定がデータベースに残っていれば、Rapls Copy Noticeを最初に有効化したときに、通知の送信先、最小文字数、自分で決めていた件名を引き継ぎます。引き継いだ値も、通常の保存と同じ検査を通してから使います。
引き継いだら、CCCを停止してください。両方が有効なままだと、1回のコピーでメールが2通届きます。両方が有効なあいだは、管理画面に案内が出ます。
CCCに残っている過去のコピーの記録は、移しません。新しい記録は、有効化したときから始まります。
入れるときの手順は、CCCを使っていたかどうかに関係なく同じです。
まず、「プラグイン」→「新規追加」で「Rapls Copy Notice」を検索して、インストールして有効化します。この時点で記録が始まります。
次に、「ツール」→「Rapls Copy Notice」の通知のタブで送信先を確かめて、テストメールのボタンを押します。CCCから移った場合は、ここでCCCを停止します。
動作を確かめるなら、ログアウトした状態(プライベートウィンドウ)で投稿を開き、本文から20文字以上コピーしてみてください。ログに1行増えていれば動いています。管理者と編集者のコピーは、既定では数えません。
動作要件は、WordPress 6.3以上、PHP 8.2以上です。PHP 8.2より古い環境では、管理画面に必要なバージョンと現在のバージョンを書いた通知が出るだけで、サイトが止まることはありません。
管理画面の表示は英語です。日本語の訳はtranslate.wordpress.orgで配信される予定で、それまでは無料版マニュアルとプラグインのページで、項目を日本語で説明しています。
作り直すときに決めたこと
前半の話を、作りの側から振り返ります。同じ目的のプラグインの前例を見て、最初から決めていたことが3つあります。
一つ目は、訪問者から来た値を、何ひとつ信用しないことです。
コピーされた文、ブラウザーの情報、参照元、IPアドレス。どれも、管理画面に出すたびに、出す場所(HTMLの本文、属性、URL)に合わせてエスケープします。保存のときに消毒したことは当てにしません。メールは常にテキストだけで送り、件名にはサイト名と自分で決めた文言と件数しか入れません。投稿のタイトルも、訪問者が送ったものも入れません。コピーされた文に改行が入っていれば、1行ずつ「>」を付けるので、文がほかの項目のふりをすることもできません。
二つ目は、ページキャッシュと喧嘩しないことです。
コピーの報告を受け取る口(REST APIの /wp-json/rapls-copy-notice/v1/log)は、ログインしていない人にも開いていて、nonceを使っていません。nonceは時間がたつと切れるので、キャッシュされたページに埋め込むと、古いページから報告が届かなくなるからです。
その代わりに、回数の上限で守ります。既定では、1つのIPアドレスから1分に10件、サイト全体で1時間に500件まで。公開中で監視対象の投稿への報告しか受け付けず、文は500文字で切ります。受け口は状態コードだけを返して、送られた値は返しません。
三つ目は、訪問者のデータを持ちすぎないことです。
IPアドレスは、既定で短くしてから保存します(IPv4なら最後の区切りを0に)。Cookieは使いません。記録は90日で自動で消えます。プラグイン自身は、外部のサービスに何も送りません。
段落をまとめて見るための「指紋」は、段落の文から読者のブラウザーで計算したハッシュで、段落の文そのものは保存しません。ブラウザーがこの計算をHTTPSのページでしか許さないので、指紋はHTTPSのサイトだけで記録されます。
短い余談を一つ。
コメント欄やお問い合わせフォームのような入力欄からのコピーは、記録しないようにしました。そこにあるのは、たいてい読者が自分で書いている文だからです。自分の書いた文をコピーしただけで記録されるのは、筋が違います。
Pro版のこと
無料版は、体験版ではありません。
ここまでに書いた機能は、すべて無料版に入っていて、期限も件数の制限もありません。
そのうえで、チームで共有したい人や、数字で傾向を見たい人のために、別売りのPro版(アドオン)を用意しました。
直近7・30・90日のコピー数を前の期間と重ねて見る統計。Slack、Chatwork、Discord、自分のWebhookへの通知。投稿やカテゴリー、文字数で通知先を振り分けるルールと、1つの投稿のコピーが急に増えたときの急増アラート。何度もコピーされた段落を、自分の検索APIのキーでWeb検索して、転載かもしれないページを一覧にする機能(既定でオフ、承認した段落だけを検索)。それに、CSVの書き出しです。
価格は、1サイト1,980円、5サイト4,980円(いずれも税込)の買い切りです。14日間の返金保証があります。詳しくはPro版の販売ページをご覧ください。
最初の問いに戻ります。
あなたの記事で、いちばんコピーされているのは、どの文でしょうか。
入れて、テストメールを1通送れば、あとは記録がたまっていきます。何日かたってログを開くと、読者が持ち帰っている文が並んでいるはずです。
参考:通知メールの見本とフック
まとめのメールは、次の形のテキストで届きます(件名のサイト名は見本です)。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 件名: [サンプルブログ] Copy notification (2 copies) Content-Type: text/plain; charset=UTF-8 --------------------------------------------------- It appears that the following text was copied. --------------------------------------------------- > ドリップの前に、ペーパーフィルターをお湯でさっと湿らせておきます。 Date: 2026年10月9日 3:14 PM Post: ハンドドリップの基本 URL: https://example.com/hand-drip/ Length: 33 characters IP: 203.0.113.0 Browser: Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X) ... Referrer: www.google.com --------------------------------------------------- |
特定の投稿のコピーだけをメールから外したいときは、フィルターで外せます。$row のうち、post_id などの一部以外は訪問者から来た値なので、出力するときは必ずエスケープしてください。
| 1 2 3 4 5 | add_filter( 'rapls_cn_email_rows', function ( $rows, $context ) { return array_filter( $rows, function ( $row ) { return 42 !== (int) $row['post_id']; } ); }, 10, 2 ); |
Googleアナリティクスなどでコピーを数えたいときは、ページで発生する rapls-cn:copy イベントを受けてください。detail には投稿IDと選択の文字数だけが入り、コピーされた文は入りません。
| 1 2 3 4 5 | document.addEventListener( 'rapls-cn:copy', function ( e ) { // e.detail.postId : 投稿 ID // e.detail.length : 選択の文字数 console.log( e.detail.postId, e.detail.length ); } ); |


コメント