NGワードで送信させないフォームのカスタマイズ

この記事は、a-blog cms Advent Calendar 2023 の17日目の記事となります。メールフォーム内にNGワードが入力された場合、送信できないカスタマイズを考えてみました。

この記事は、a-blog cms Advent Calendar 2023 の17日目の記事となります。

営業メール多過ぎ問題

最近、お問い合わせフォームから「業務提携したい」「コーディングできます」などと書いた営業メールが多数届きます。

正直なところ架空のサイトだけしか載せていないようなポートフォリオを載せたコピペメールを送りつけられても、仕事を依頼しようという気にはなりませんし、撲滅できないまでも少しは通知を減らしたい。そこでメールフォーム内に書かれてある特定のキーワードが入力された場合、送信できない仕組みを考えてみました。

Javascriptのみを使う方法

とりあえず「提携」「パートナー」「稼働時間」の3つのキーワードを使って試してみましょう。以下のフォームにいずれかのキーワードを入力してください。


id="inquiry" のテキストボックスの内容をリアルタイムでチェックして、NGワードが含まれていれば、送信ボタンを押せなくなる(disabled)にします。

わざわざソースコードをチェックして、NGワードを回避する文章に直す人には効果はありませんが、「営業メールお断り」という文章を読んだ上で、チャレンジを続ける人のメールは読んでもいいかなという気もします。返事しないとは思いますけど。

ソースはこんな感じに。


<textarea id="inquiry" name="inquiry" rows="3"></textarea>
<button type="submit" id="btnConfirm">内容の確認画面へ</button>
<div id="spamMessage"></div>

<script>
  var inquiry = document.getElementById("inquiry");
  var regex = /提携|パートナー|稼働時間/;
  function checkKeywords() {
    if (regex.test(inquiry.value)) {
      document.getElementById("btnConfirm").disabled = true;
      document.getElementById("spamMessage").innerHTML = '<p class="error-text acms-margin-top-medium"><i class="icon-attention"></i>フォームからの営業メールはお断りいたします。</p>';
    } else {
      document.getElementById("btnConfirm").disabled = false;
      document.getElementById("spamMessage").innerHTML = '';
    }
  }
  inquiry.addEventListener("input", checkKeywords);
</script>

送信ボタンを押させないという比較的にシンプルで穏当な対策ですし、実装も簡単です。

Javascriptとフォームのバリデーターの併用

次はフォームのバリデーター機能を使ってみましょう。今回はJavascriptではない方のバリデーターを使います。

複数の文字列をバリデートの対象にするには、正規表現を使います。a-blog cmsには、もともと正規表現のバリデート機能もあるので、そのまま利用しようとしたのですが、テキストエリアで改行が入ると上手く動作しません(上手く動作する正規表現があれば教えてください。すぐに記事を直します)。

そこでJavascriptを仕様して、 まずは id="inquiry" のテキストボックスの中身をチェックして改行を取り除いて、inquiry_checkという入れ物を作り、その中身をCMSでチェックすることにしました。

以下、当サイトのフォームで実装済みです。ダミーではないので、むやみに送信しないでお試しください。

実装済みのフォームはこちら

<!-- 本来のテキストボックス -->
<textarea id="inquiry" name="inquiry" >{inquiry}</textarea>
<input type="hidden" name="field[]" value="inquiry" />

<!-- チェック用の追加記述 -->
<input type="hidden" id="inquiry_check" name="inquiry_check" value="{inquiry_check}"></input>
<input type="hidden" name="field[]" value="inquiry_check" />
<input type="hidden" name="inquiry_check:v#regex" value="^(?!.*提携|.*パートナー|.*稼働時間|).*$" id="inquiry_check-v-regex" />

<!-- BEGIN inquiry_check:validator#regex -->
<p class="error-text large"><i class="icon-attention"></i>お問い合わせフォームからの営業メールはお断りいたします。送信されても絶対に返信しません。</p>
<!-- END inquiry_check:validator#regex -->

<!-- inquiryの中身をリアルタイムで inquiry_checkに -->
<script>
	var inquiry = document.getElementById("inquiry");
	function removeNewline(text) {
		return text.replace(/\r?\n/g, '');
	}
	function reflectInput() {
		var inquiryWithoutNewline = removeNewline(inquiry.value);
		document.getElementById("inquiry_check").value = inquiryWithoutNewline;
	}
	inquiry.addEventListener("input", reflectInput);
</script>

NGワードを含んだまま送信するとこのようにエラーが出ます。


NGワードを含んだまま送信した際のエラー表示

先ほどのJavascriptだけの実装に比べると、やや手間が掛かりますが、送信ボタンを押すまでエラーの文言がわからないというメリットがあります(NGワードは見れてしまう)。

もちろんJavascriptでバリデートすれば、もっとスマートなのですが、あえて使わないのは「単なる嫌がらせ」です。

おまけ:文字数を制限する方法

また以前に住所欄に長々と宣伝文を入力してくる人がいたので、80文字を超える場合に以下のようなエラーを出すようにしています。

<input type="text" id="address" name="address" value="{address}">
<input type="hidden" name="field[]" value="address" />
<input type="hidden" name="address:v#maxLength" value="80" />
<!-- BEGIN address:validator#maxLength -->
<p class="error-text"><i class="icon-attention"></i>住所が長すぎます。住所に宣伝を入れるようなマナーの悪い会社からの営業メールは固くお断りしております。</p>
<!-- END address:validator#maxLength -->

フォームオプションを見直そう

NGワードを多く設定しすぎると、本来受けるべき問い合わせをブロックすることになりかねないため、それほど汎用性が高いとは思えませんが、a-blog cmsのフォームオプションは結構豊富なので、いろいろと工夫したフォームを作れますので、一度目を通すことをおすすめします。


多機能なCMSなので、使ったことがない機能も多いわけですが、Advent Calendarの時期にはいろいろ情報集めがはかどるので助かりますね。

それでは皆さま、よいお年を!



グローバル変数

global varsvalues
%{BID}2
%{UID}
%{CID}44
%{EID}839
%{RID}
%{RVID}
%{UTID}
%{CMID}
%{TBID}
%{KEYWORD}
%{TAG}
%{FIELD}
%{DATE}
%{START}1000-01-01 00:00:00
%{END}9999-12-31 23:59:59
%{PAGE}1
%{ORDER}
%{QUERY}
%{QOL}?
%{ADMIN}
%{IS_ADMIN}0
%{ADMIN_PATH}
%{ADMIN_PATH_MID}
%{MID}
%{MODULE_ID}
%{MODULE_NAME}
%{STYLEGUIDE_PAGE}acms-admin
%{GETTEXT_TYPE}user
%{BCD}blog
%{UCD}
%{CCD}ablogcms
%{ECD}advent-calendar-2023.html
%{BLOG_NAME}ブログ
%{USER_NAME}
%{CATEGORY_NAME}a-blog cms
%{ENTRY_TITLE}NGワードで送信させないフォームのカスタマイズ
%{RULE_NAME}
%{CONFIG_SET_NAME}共通の設定
%{THEME_SET_NAME}ブログテーマ
%{EDITOR_SET_NAME}編集の基本設定
%{RCID}44
%{PCID}
%{RCCD}ablogcms
%{PCCD}
%{ROOT_CATEGORY_NAME}a-blog cms
%{PARENT_CATEGORY_NAME}
%{RBID}1
%{PBID}1
%{RBCD}
%{PBCD}
%{ROOT_BLOG_NAME}フォルトゥナ
%{PARENT_BLOG_NAME}フォルトゥナ
%{ALIAD_ID}
%{ALIAS_ID}
%{ALIAS_DOMAIN}
%{ALIAS_CODE}
%{ALIAS_NAME}
%{CHARSET}UTF-8
%{META_KEYWORDS}
%{META_DESCRIPTION}
%{NOW_DATE}2024-09-16
%{NOW_TIME}05:37:43
%{BLOG_THEME_COLOR}#559655
%{BLOG_THEME_CONTRAST_COLOR}#ffffff
%{VERSION}3.1.22
%{SNAME}sid
%{SID}
%{SESSION_USER_ID}
%{SESSION_BLOG_ID}
%{MAX_PUBLISHES}15
%{ROOT_TPL}/themes/blog@base/_entry.html
%{ROOT_TPL_NAME}_entry
%{ROOT_DIR}/
%{DOCUMENT_ROOT}/
%{THEMES_DIR}/themes/
%{JS_DIR}/js/
%{JS_LIB_DIR}/js/library/
%{JS_LIB_JQUERY_DIR}/js/library/jquery/
%{JS_LIB_JQUERY_DIR_VERSION}3.6.1
%{LOGIN_SEGMENT}login
%{ADMIN_RESET_PASSWORD_SEGMENT}admin-reset-password
%{ADMIN_RESET_PASSWORD_AUTH_SEGMENT}admin-reset-password-auth
%{ADMIN_TFA_RECOVERY_SEGMENT}admin-tfa-recovery
%{SIGNIN_SEGMENT}signin
%{SIGNUP_SEGMENT}signup
%{RESET_PASSWORD_SEGMENT}reset-password
%{RESET_PASSWORD_AUTH_SEGMENT}reset-password-auth
%{TFA_RECOVERY_SEGMENT}tfa-recovery
%{PROFILE_UPDATE_SEGMENT}mypage/update-profile
%{PASSWORD_UPDATE_SEGMENT}mypage/update-password
%{EMAIL_UPDATE_SEGMENT}mypage/update-email
%{TFA_UPDATE_SEGMENT}mypage/update-tfa
%{WITHDRAWAL_SEGMENT}mypage/withdrawal
%{SYSTEM_THEMES_DIR}/themes/system/
%{CURRENT_THEMES_DIR}/themes/blog@base/
%{ARCHIVES_DIR}/archives/
%{MEDIA_ARCHIVES_DIR}/media/
%{MEDIA_STORAGE_DIR}storage/
%{BID_ARCHIVES_DIR}/archives/002/
%{YM_ARCHIVES_DIR}/archives/002/202409/
%{ARCHIVES_DIR_TEMP}/archives/temp/
%{ARCHIVES_CACHE_SERVER}
%{HTTP_THEMES_DIR}https://www.color-fortuna.com/themes/
%{HTTP_CURRENT_THEMES_DIR}https://www.color-fortuna.com/themes/blog@base/
%{HTTP_ARCHIVES_DIR}https://www.color-fortuna.com/archives/
%{HTTP_MEDIA_ARCHIVES_DIR}https://www.color-fortuna.com/media/
%{HTTP_ARCHIVES_DIR_TEMP}https://www.color-fortuna.com/archives/temp/
%{HTTP_BID_ARCHIVES_DIR}https://www.color-fortuna.com/archives/002/
%{HTTP_YM_ARCHIVES_DIR}https://www.color-fortuna.com/archives/002/202409/
%{HTTP_REQUEST_URL}https://www.color-fortuna.com/blog/ablogcms/advent-calendar-2023.html
%{IMAGES_DIR}/themes/system/images/
%{SCRIPT_ROOT}/
%{REWRITE_OFFSET}/
%{HTTP_ROOT}https://www.color-fortuna.com/
%{DOMAIN}www.color-fortuna.com
%{DOMAIN_ROOT}www.color-fortuna.com
%{HTTP_HOST}www.color-fortuna.com
%{BASE_URL}http://www.color-fortuna.com/blog/
%{ADMIN_BASE_URL}https://www.color-fortuna.com/
%{BLOG_URL}https://www.color-fortuna.com/blog/
%{ROOT_BLOG_URL}https://www.color-fortuna.com/
%{PARENT_BLOG_URL}https://www.color-fortuna.com/
%{CATEGORY_URL}https://www.color-fortuna.com/blog/ablogcms/
%{ROOT_CATEGORY_URL}https://www.color-fortuna.com/blog/ablogcms/
%{PARENT_CATEGORY_URL}https://www.color-fortuna.com/blog/
%{CANONICAL_URL}https://www.color-fortuna.com/blog/ablogcms/advent-calendar-2023.html
%{ENTRY_URL}https://www.color-fortuna.com/blog/ablogcms/advent-calendar-2023.html
%{PERMALINK}https://www.color-fortuna.com/blog/ablogcms/advent-calendar-2023.html
%{INHERLINK}https://www.color-fortuna.com/blog/ablogcms/advent-calendar-2023.html
%{CURRENT_URL}https://www.color-fortuna.com/blog/ablogcms/advent-calendar-2023.html
%{HOME_URL}https://www.color-fortuna.com/
%{BASE_ACMS_PATH}blog/
%{ACMS_PATH_BASE}blog/
%{SCRIPT_DIR}/home/kyunitan/color-fortuna.com/public_html/
%{CURRENT_ROOT}/blog/ablogcms/advent-calendar-2023.html
%{REQUEST_PATH}/blog/ablogcms/advent-calendar-2023.html
%{REQUEST_DIRNAME}/blog/ablogcms
%{MODULE}
%{VALID_ID_REGEX}@^[a-zA-Z0-9_-]+$@
%{REGEX_VALID_ID}@^[a-zA-Z0-9_-]+$@
%{REGEX_VALID_PASSWD}@^[!-~]+$@
%{CATEGORY_EXISTS}1
%{CATEGORY_LEVEL}1
%{VIEW}entry
%{UA}CCBot/2.0 (https://commoncrawl.org/faq/)
%{CH_UA}
%{CH_UA_MOBILE}0
%{CH_UA_PLATFORM}
%{UA_GROUP}PC
%{REMOTE_ADDR}44.220.247.152
%{MAINTENANCE_MODE}
%{PROTOCOL}https
%{BLOG_CODE}blog
%{USER_CODE}
%{CATEGORY_CODE}ablogcms
%{ENTRY_CODE}advent-calendar-2023.html
%{BLOG_ID}2
%{USER_ID}
%{CATEGORY_ID}44
%{ENTRY_ID}839
%{SUID}
%{SBID}
%{SESSION_USER_AUTH}
%{SESSION_USER_NAME}
%{SESSION_USER_CODE}
%{SESSION_USER_MAIL}
%{SEARCH_ENGINE_KEYWORD}
%{MAIL_MAGAZINE_FROM}info@example.com
%{MAIL_TRACKBACK_FROM}
%{MAIL_COMMENT_FROM}info@example.com
%{MAIL_REMIND_FROM}
%{MAIL_SUBSCRIBE_FROM}info@example.com
%{MAIL_SUBSCRIBE_ADMIN_FROM}info@example.com
%{PHP_FILE_MAX_SIZE}30M
%{PHP_POST_MAX_SIZE}30M
%{MEDIA_LIBRARY}on
%{IS_DEVELOPMENT}off
%{IS_TRIAL}off
%{TRIAL_COUNT_DOWN}0
%{IS_SUBSCRIPTION}off
%{SUBSCRIPTION_PLAN}
%{UNLICENSED_REASON}
%{SUBSCRIPTION_PAYMENT}
%{ACTIVATION_ENDPOINT}https://mypage.a-blogcms.jp/api/activation
%{GOOGLE_API_KEY}
%{PREVIEW_DEFAULT_DEVICE}iPhone 6/7/8
%{PREVIEW_HAS_HISTORY_DEVICE}
%{APPROVAL_PREVIEW_DEFAULT_DEVICE}iPhone 6/7/8
%{APPROVAL_PREVIEW_HAS_HISTORY_DEVICE}
%{TIMEMACHINE_PREVIEW_DEFAULT_DEVICE}PC
%{TIMEMACHINE_PREVIEW_HAS_HISTORY_DEVICE}
%{d}16
%{D}Mon
%{j}16
%{l}Monday
%{N}1
%{S}th
%{w}1
%{z}259
%{W}38
%{F}September
%{m}09
%{M}Sep
%{n}9
%{t}30
%{L}1
%{o}2024
%{Y}2024
%{y}24
%{a}am
%{A}AM
%{B}901
%{g}5
%{G}5
%{h}05
%{H}05
%{i}37
%{s}43
%{u}000000
%{e}Asia/Tokyo
%{I}0
%{O}+0900
%{P}+09:00
%{T}JST
%{Z}32400
%{c}2024-09-16T05:37:43+09:00
%{r}Mon, 16 Sep 2024 05:37:43 +0900
%{U}1726432663

モジュール処理時間

moduleidentifierrun timesql
Entry_Body0.0291712
Entry_ListentryList0.015795
Category_ListcategoryList0.007710
Ogp0.0066711
NavigationglobalNavi0.004971
NavigationglobalNavi0.004781
Blog_FieldtopBlog0.004274
TopicpathtopicPath0.004095
TopicpathtopicPath0.004025
Blog_FieldtopBlog0.003323
Blog_FieldtopBlog0.003073
Blog_FieldtopBlog0.003043
Blog_FieldtopBlog0.002973
Entry_Field0.002662
Blog_FieldtopBLog0.002591
Touch_Unlogin0.002140
Topicpathtopicpath0.001993
Entry_Field0.00181
Entry_Field0.00181
Blog_FieldtopBLog0.001592
Form2_Unit0.001340
Form2_Unit0.001240
Form0.001011
Form2_Unit0.000821
Js0.000310
Field_Search0.000240
Admin_Entry_Add0.000220
Form2_Unit0.000210
Touch_Benchmark0.000160
Touch_SessionWithContribution0.000150
Touch_SessionWithAdministration0.000140
Touch_NotApprovalEditVersion0.000130
Touch_Version0.000130
Tag_Filter0.000120
Touch_Admin0.000120
Touch_Form20.000120
Touch_NotEditInplace0.000120
Touch_NotPreview0.000120
Touch_EditDirect0.000110
Touch_NotEditDirect0.000110
Touch_NotEntry0.000110
Touch_Entry0.00010
Touch_Approval9.0E-50
Touch_ApprovalEditVersion9.0E-50
Touch_Edit9.0E-50
Touch_GeolocationEntryFunction9.0E-50
Touch_MailMagazineEnable9.0E-50
Touch_NotApprovalORsessionWithApprovalAdministrator9.0E-50
Touch_NotEdit9.0E-50
Touch_NotTag9.0E-50
Touch_NotsessionWithApprovalAdministrator9.0E-50
Touch_RelatedEntryFunction9.0E-50
Touch_SessionWithCompilation9.0E-50
Touch_SubCategoryFunction9.0E-50
Touch_Category8.0E-50
Touch_Debug8.0E-50
Touch_EditInplace8.0E-50
Touch_HigherLicense8.0E-50
Touch_Index8.0E-50
Touch_Keyword8.0E-50
Touch_Login8.0E-50
Touch_NotAdmin8.0E-50
Touch_NotCategory8.0E-50
Touch_NotPreview8.0E-50
Touch_NotTimemachineMode8.0E-50
Touch_RelatedEntryFunction8.0E-50
Touch_Tag8.0E-50
Touch_Top8.0E-50
Touch_sessionWithApprovalAdministrator8.0E-50
Touch_Entry7.0E-50
Touch_NotPreview7.0E-50
Touch_NotPreview7.0E-50
Touch_SessionWithAdministration7.0E-50
Touch_SessionWithContribution7.0E-50
Touch_sessionWithApprovalAdministrator7.0E-50
Touch_Admin6.0E-50
Touch_GeolocationEntryFunction6.0E-50
Touch_NotApprovalORsessionWithApprovalAdministrator6.0E-50
Touch_NotEdit6.0E-50
Touch_NotPreview6.0E-50
Touch_NotPreview6.0E-50
Touch_NotPreview6.0E-50
Touch_NotPreview6.0E-50
Touch_SessionWithAdministration6.0E-50
Touch_SessionWithAdministration6.0E-50
Touch_SessionWithAdministration6.0E-50
Touch_SessionWithAdministration6.0E-50
Touch_SessionWithContribution6.0E-50
Touch_SessionWithContribution6.0E-50
Touch_SessionWithContribution6.0E-50
Touch_SessionWithContribution6.0E-50
Touch_SessionWithContribution6.0E-50
Touch_SubCategoryFunction6.0E-50
Touch_Version6.0E-50
Touch_Admin5.0E-50
Touch_Edit5.0E-50
Touch_EditInplace5.0E-50
Touch_Entry5.0E-50
Touch_Entry5.0E-50
Touch_Entry5.0E-50
Touch_Entry5.0E-50
Touch_Entry5.0E-50
Touch_Entry5.0E-50
Touch_NotAdmin5.0E-50
Touch_NotEdit5.0E-50
Touch_NotEdit5.0E-50
Touch_NotEntry5.0E-50
Touch_NotEntry5.0E-50
Touch_SessionWithContribution5.0E-50
Touch_SessionWithContribution5.0E-50
Touch_Tag5.0E-50
Touch_Unlogin5.0E-50
Touch_Unlogin5.0E-50
MODULE TOTAL TIME0.1203578
BOOT TOTAL TIME0.15811
BUILD TOTAL TIME0.16526
REWRITE PATH TOTAL TIME0.01036
PROCCESS TIME0.560382

テンプレート

template
themes/base/include/head/meta.html
themes/base/include/head/robots.html
themes/base/include/head/link.html
themes/base/include/head/js.html
themes/base/include/head/structured-data.html
themes/base/include/body-start.html
themes/base/include/header.html
themes/base/include/header/dynamicGlobalNavi.html
themes/system/admin/module/setting.html
themes/blog@base/include/header/page-title.html
themes/base/include/header/topicpath.html
themes/system/admin/action.html
themes/system/include/check-seo.html
themes/base/include/footer.html
themes/base/include/body-end.html
themes/base/include/module/tag/filter.html
themes/base/include/module/entry/bodyNoDate.html
themes/system/admin/entry/revision-info.html
themes/system/admin/entry/title.html
themes/system/include/unit.html
themes/base/include/unit/tag-select.html
themes/system/include/gmaps-error.html
themes/base/include/unit/custom.html
themes/base/include/unit/extend.html
themes/base/include/module/entry/continue.html
themes/base/include/form/unit.html
themes/base/include/form/input.html
themes/base/include/form/confirm.html
themes/system/admin/entry/edit.html
themes/system/admin/entry/style.html
themes/system/admin/entry/geo.html
themes/system/admin/map/_google-map-picker.html
themes/system/admin/map/_open-street-map-picker.html
themes/system/admin/entry/related.html
themes/system/admin/entry/related-table.html
themes/base/admin/entry/field.html
themes/base/admin/entry/ogp.html
themes/base/admin/entry/pickup.html
themes/base/admin/entry/seo.html
themes/system/admin/entry/unit.html
themes/base/admin/entry/unit/extend.html
themes/base/admin/entry/field_foot.html
themes/system/admin/entry/revision.html
themes/system/admin/entry/js.html
themes/system/admin/entry/add.html
themes/system/admin/form2/edit.html
themes/system/admin/form2/unit.html
themes/system/admin/entry/action.html
themes/base/include/module/entry/list.html
themes/base/include/module/category/list.html

メモリー

keyvalue
memory_limit200M
memory_get_usage3.56 MB
memory_get_peak_usage5.28 MB

Query Count

query count
119