WEBシステムにコメント機能を実装するにあたって、安価にモデレーション機能が求められたのでそれを実装した時の備忘です。
前置き
- モデレーションってなんぞや?って人向けの解説
ブログやSNS、インターネット上の記事に投稿された読者によるコメントに対し、管理者が内容をチェックしたり、別の読者が評価付けをしたりすること。また、その仕組み。不適切な投稿を除外するはたらきがある。モデレーション機能。
goo辞書より
要はやばいコメント投稿をされないように制限する機能です。
- 実装の種類
実装には大きく分けて2種類が考えられます。
1.AI/機械学習系のサービスを用いる
2.コメント送信前にブラックリストによる判断を実施する
3.コメントが投稿されたら、一旦保留し、人の目で確認する。
今回はコストがかからない2の方式で実装していきます。
ライブラリ等は利用せずに、VaniraJSで実装します。
やること
formを実装したhtmlを用意して簡易的なコメント描画ページを用意
JSにて該当イベント時にブラックリストを参照して、判定を実施する
ポイント
通常であれば、送信された内容は永続化する為に、DB等に保存する形式になります。(過去ログ等を残す為
今回は簡易的な実装記事の為、その部分は記載しません。
- ディレクトリ構造
Root
├index.html
└taboo.json
今回はBootStrapで簡単な装飾を実施しています。
コード
- index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"/>
</head>
<body>
<div class="container mt-5">
<h2>モデレーション_サンプル</h2>
<form id="commentForm">
<div class="form-group">
<label>ユーザー名</label>
<input type="text" class="form-control" id="nameInput" />
</div>
<div class="form-group">
<label>コメント</label>
<textarea class="form-control" id="commentInput"></textarea>
</div>
<div class="form-group">
<div id="errorMessage" class="text-danger"></div>
</div>
<div class="d-grid gap-2">
<button type="button" class="btn btn-primary w-auto" id="submitButton" >
送信
</button>
</div>
</form>
<hr />
<h2>コメントの表示領域</h2>
<div id="comments"></div>
</div>
<script>
let taboo = [];
document
.getElementById("submitButton")
.addEventListener("click", function () {
const name = document.getElementById("nameInput").value;
const comment = document.getElementById("commentInput").value;
if (isValid(comment)) {
let html = `
<div class="border p-2 mb-2">
<strong>${name}</strong>
<small class="text-muted">閲覧済み投稿</small>
<p>${comment}</p>
</div>
`;
document.getElementById("comments").innerHTML += html;
document.getElementById("commentInput").value = "";
document.getElementById("errorMessage").textContent = "";
} else {
document.getElementById("errorMessage").textContent =
"NGワードが含まれています。";
}
});
async function loadtaboo() {
try {
const response = await fetch("./taboo.json");
const data = await response.json();
taboo = data.taboo.map((pattern) => new RegExp(pattern, "i"));
} catch (error) {
console.error("Error loading ./taboo.json:", error);
}
}
(async () => {
await loadtaboo();
})();
function isValid(str) {
return !taboo.some((pattern) => pattern.test(str));
}
</script>
</body>
</html>
このコードでは、下記のブラックリスト(taboo.json)の内容を判定して、コメントの投稿を阻止しています。
もし、taboo.jsonの内容に更新があった場合に、クライアントサイドでもブラウザの更新処理が必要になります。
- taboo.json
{
"taboo": [".*殺.*","許せない"]
}
上記では完全一致の場合には"hoge"の形式で指定して、部分一致の場合には".*hoge.*" で記載しています。
その為、「殺してやる!」、「許せない」などが投稿されない様に、阻止することができます。
動作イメージ
まとめ
私は掲示板やコメント欄等を利用したことがないので使い古された実装かもしれませんが、書いていくに当り結構勉強になりました。
上記ナレッジがどなたかのお役に立てば幸いです。