敬語を判定する簡単なBotを作成しました!
概要
こんな感じで簡単な敬語を感知して返信するBotです。
「河童様」は反応、様は付くけど無礼な言葉とされる「貴様」には無反応なことを例に
誤検知を防ぐよう設計しています。
コマンド「@Breako」を入力すると設定されたNGワードを確認できます。
作った理由
Twitterのつぶやきは基本ため口ですが、そこまで親しくない人からリプライが飛んできた場合は敬語になりませんか?
親しくなりたいけどついよそよそしくなってしまいがちです。
なのでDiscord内でサーバー側から敬語を禁止したらたくさん友達ができるんじゃないかという魂胆で作成しました。
密かに人見知りや繊細な人にも枷を外してインターネットを楽しめる世の中にしたいという野望があります。
参考にした記事
使用した技術
- Glitch
- discord.js
v11.6.412.3.1 - Google Apps Script
コード
基本、「誰でも作れる!Discord Bot(基礎編)」の記事の順序に従って作成しました。
constng=require('./ng.json')constok=require('./ok.json')
["です","ます","ました","でした",...
["かます","ますます","さます","覚ます","冷ます",...
管理しやすいようNGワード、除外ワードを配列でjsonファイルに保存して呼び出しています。
// 禁止ワード設定varng_reg=ng.map((v)=>{returnnewRegExp(v,'g')})varok_reg=ok.map((v)=>{returnnewRegExp(v,'g')})varok_under=ok.map((v)=>{returnv.replace(ng_reg[0],' __'+ng[0]+'__ ').replace(ng_reg[1],' __'+ng[1]+'__ ').replace(ng_reg[2],' __'+ng[2]+'__ ').replace(ng_reg[3],' __'+ng[3]+'__ ').replace(ng_reg[4],' __'+ng[4]+'__ ').replace(ng_reg[5],' __'+ng[5]+'__ ')...})varok_under_reg=ok_under.map((v)=>{returnnewRegExp(v,'g')})
NG、除外ワードの配列を正規表現化しています。
ok_underは除外ワードをDiscord用に下線で装飾するようreplaceで置換されたワードを上書きするために下線で置き換えしています。
(例: 覚ます → 覚 _ます_)
// 禁止ワード判定// 禁止ワードがあればカウントプラス、OKワードがあればマイナスvarmatch_count=0;ng_reg.forEach((v)=>{match_count=match_count+(message.content.match(v)||[]).length;});ok.forEach((v)=>{match_count=match_count-(message.content.match(v)||[]).length;});if(match_count>=1){lettext=message.content.replace(ng_reg[0],' __'+ng[0]+'__ ').replace(ng_reg[1],' __'+ng[1]+'__ ').replace(ng_reg[2],' __'+ng[2]+'__ ').replace(ng_reg[3],' __'+ng[3]+'__ ')....replace(ok_under_reg[0],ok[0]).replace(ok_under_reg[1],ok[1]).replace(ok_under_reg[2],ok[2])...letBreako='敬語が含まれているよ!: '+textsendReply(message,Breako);return;}});
NGワード数をmatchでカウントして、除外ワードでマイナスしています。1以上ならば敬語が含まれていると感知して返信をする仕組みです。
「天狗様、目を覚ます。」であれば
「様」、「ます」で+2、「冷ます」で-1で合計1になり敬語が含まれている判定になっています。
そして前半の.replace(ng_reg, ' __' + ng + '__ ')
で「天狗_様_ 、目を覚 _ます_ 。」となり
後半の.replace(ok_under_reg,ok)
で「覚_ます_」を「覚ます」置き換えて「天狗_様_ 、目を覚ます 。」となります。
constng_list=ng.join(', ')client.on('message',message=>{if(message.author.id==client.user.id||message.author.bot){return;}if(message.isMemberMentioned(client.user)){sendReply(message,"禁止された敬語: "+ng_list);return;}
@Breakoの部分です。NGワードの配列を文字列化して返信します。
振り返り
replaceを複数条件で置き換えするためにメソッドチェーンを利用したんですがかなり長いコードになってしまいました。
他によい方法が見つからずこのような形になっています。メンテナンスもしづらいのでよい方法があったら是非教えていただきたいです。
さいごに
NGワード、除外ワードについてはかなり杜撰なのでご意見あればTwitterなどにお願いします!