# How to stop bot spam in your AI Chatbot

**URL:** https://community.elfsight.com/t/how-to-stop-bot-spam-in-your-ai-chatbot/142430
**Category:** Pro Tips
**Tags:** ai-chatbot
**Created:** [December 15, 2025, 7:37am UTC](https://community.elfsight.com/t/how-to-stop-bot-spam-in-your-ai-chatbot/142430 "2025-12-15T07:37:01Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![Max](https://sea2.discourse-cdn.com/flex020/user_avatar/community.elfsight.com/max/32/710_2.png) [@Max](https://community.elfsight.com/u/Max)
#### Post date: [December 15, 2025, 7:37am UTC](https://community.elfsight.com/t/how-to-stop-bot-spam-in-your-ai-chatbot/142430/1 "2025-12-15T07:37:01Z")

</div>

Tired of bots spamming your **[AI Chatbot](https://elfsight.com/ai-chatbot-widget/)** and wasting your message limit? While the widget doesn’t have a built-in feature for this, our devs came up with a simple and effective solution — adding a **Honeypot** to filter out bot submissions 🍯

## **How it works?**

* * *

The Honeypot solution adds an **invisible input field** that real users never see. Bots, however, tend to fill in every field they find.

If this hidden field is filled out, the message is automatically blocked and won’t be sent ✨

  

## **How to set it up ?**

* * *

> **Add the custom script**
>
> Go to the **Settings** tab in the widget editor, find the **Custom JS** section, and add the following script:
> 
> ```auto
> const CHAT_PORTAL_SELECTOR = ".es-portal-root[class*='eapps-ai-chatbot']";
> 
> const HONEYPOT_CLASS = 'es-honeypot';
> const HONEYPOT_NAME = 'message';
> 
> const waitForElement = (selector, interval = 250) => {
> return new Promise((resolve) => {
> const timer = setInterval(() => {
> const element =
> util.findElement(selector) ?? document.body.querySelector(selector);
> if (element) {
> clearInterval(timer);
> resolve(element);
> }
> }, interval);
> });
> };
> 
> const createHoneyPotField = (sourceField) => {
> const fieldClone = sourceField.cloneNode(true);
> 
> const input = fieldClone.querySelector('input');
> 
> const placeholder = fieldClone.querySelector(
> '[class*="TextControlBasePlaceholder-sc"]'
> );
> 
> if (!input) {
> return null;
> }
> 
> fieldClone.classList.add(HONEYPOT_CLASS);
> fieldClone.setAttribute('aria-hidden', 'true');
> 
> input.type = 'text';
> input.value = '';
> 
> input.name = HONEYPOT_NAME;
> input.id = HONEYPOT_NAME;
> input.placeholder = HONEYPOT_NAME;
> 
> input.tabIndex = -1;
> input.autocomplete = 'off';
> input.setAttribute('aria-hidden', 'true');
> 
> if (placeholder) {
> placeholder.textContent = 'Message';
> }
> 
> return fieldClone;
> };
> 
> const insertHoneyPot = (form) => {
> const submitButton = form.querySelector('[type="submit"]');
> 
> const sourceField = form.querySelector('.es-form-field-shortText');
> 
> if (!submitButton || !sourceField) {
> return;
> }
> 
> const existingHoneyPot = form.querySelector(`.${HONEYPOT_CLASS}`);
> 
> if (existingHoneyPot) {
> return;
> }
> 
> const honeyPotField = createHoneyPotField(sourceField);
> 
> if (!honeyPotField) {
> return;
> }
> 
> form.insertBefore(honeyPotField, submitButton);
> };
> 
> const handleFormSubmit = (e) => {
> const form = e.target;
> 
> if (!(form instanceof HTMLFormElement)) {
> return;
> }
> 
> const honeyPotInput = form.querySelector(`.${HONEYPOT_CLASS} input`);
> 
> if (honeyPotInput?.value?.trim()) {
> e.preventDefault();
> e.stopPropagation();
> 
> console.warn('Spam blocked by honeypot');
> }
> };
> 
> const patchedForms = new WeakSet();
> 
> const observePortal = (portal) => {
> const observer = new MutationObserver(() => {
> const form = portal.querySelector('form');
> 
> if (!form || patchedForms.has(form)) {
> return;
> }
> 
> insertHoneyPot(form);
> 
> form.addEventListener('submit', handleFormSubmit, true);
> 
> patchedForms.add(form);
> });
> 
> observer.observe(portal, {
> childList: true,
> subtree: true,
> });
> };
> 
> const initHoneyPot = async () => {
> const portal = await waitForElement(CHAT_PORTAL_SELECTOR);
> 
> observePortal(portal);
> };
> 
> initHoneyPot();
> 
> ```
> 
> ![image](https://us1.discourse-cdn.com/flex020/uploads/elfsight/original/3X/1/5/1585e991c7b9208e14eaaf979152ee77ec4bfebd.png)
> 
> > **Note:** Custom JS only works on the **live site after the widget is installed** —it won’t run inside the widget editor or preview.

  

> **Add the CSS code**
>
> Then, open the **Custom CSS** section, paste the code below and publish changes:
> 
> ```auto
> .es-honeypot {
> position: absolute !important;
> left: -9999px !important;
> top: 0 !important;
> width: 1px !important;
> height: 1px !important;
> padding: 0 !important;
> margin: 0 !important;
> border: 0 !important;
> overflow: hidden !important;
> opacity: 0 !important;
> pointer-events: none !important;
> }
> 
> ```
> 
> ![image](https://us1.discourse-cdn.com/flex020/uploads/elfsight/original/3X/e/0/e0276dba29b763f99d82f377f04598604f91737b.png)

  

That’s it! Your AI Chatbot is now protected from bot spam and unnecessary message usage.

> Guys, was this solution helpful for you? We’d love to hear your thoughts — feel free to share them in the comments 🙂

---

<div class="post-metadata">

### Author: ![Petar\_Dietrich](https://sea2.discourse-cdn.com/flex020/user_avatar/community.elfsight.com/petar_dietrich/32/92003_2.png) [@Petar\_Dietrich](https://community.elfsight.com/u/Petar_Dietrich)
#### Post date: [May 6, 2026, 2:26pm UTC](https://community.elfsight.com/t/how-to-stop-bot-spam-in-your-ai-chatbot/142430/2 "2026-05-06T14:26:03Z")

</div>

Howdy!

For an important topic such as this one, what are Elfsight’s plans to incorporate the above into the AI chatbot’s native “defense mechanism” to prevent bots from consuming message tokens and endangering the affected website and/or business? Shouldn’t this topic be classified as “Security and Safety” and acted upon? Adding a “Honeypot” (ON/OFF) toggle to the configurator would be ideal (see below for example).

Please note that, recently, many of our message tokens were used up but never received any incoming notifications (i.e., emails) telling us what or who used our message tokens. I suspect the rapid usage was caused by a bot and/or Elfsight developers/team members testing changes made to the configurator or internal chatbot code.

Thank you!

* * *

 ![screenshot-prevent-spam-example](https://us1.discourse-cdn.com/flex020/uploads/elfsight/original/3X/e/1/e176bc4ac312c00a20e3242dec6a53bff9f6a313.jpeg)

---

<div class="post-metadata">

### Author: ![Max](https://sea2.discourse-cdn.com/flex020/user_avatar/community.elfsight.com/max/32/710_2.png) [@Max](https://community.elfsight.com/u/Max)
#### Post date: [May 6, 2026, 3:45pm UTC](https://community.elfsight.com/t/how-to-stop-bot-spam-in-your-ai-chatbot/142430/3 "2026-05-06T15:45:42Z")

</div>

Hi there, @Petar_Dietrich 👋

I completely understand your concern about the lack of a spam protection mechanism, and I’m really sorry it’s not supported yet.

At the moment, this feature isn’t on our roadmap, but we have received a request for a [CAPTCHA option](https://community.elfsight.com/t/add-captcha/107765). Hopefully, our developers will be able to consider this improvement soon. We’ll keep you updated in the Wishlist thread if there are any changes 🙂

Regarding the messages used, our devs and the Support Team don’t test new features on customers’ widgets since they use their own widgets for testing.

We can use some of the messages from your limit, but only when a user reports an issue with the chatbot’s response or needs a custom behavior setup and the number of messages we can use isn’t high (usually, just a few messages).

Additionally, I’d like to note that such tests or setups are performed through the configurator (except for the script testing, which should be live), so the messages used will be deducted from the test message limit, not from the overall message limit given on your plan.

Looking into your case, I don’t see any recent requests from you on the forum or in our support folder that would require the dev team to use your messages.

To confirm this, here’s a quick breakdown of messages used for the last 2 weeks:

> **May 5-6**
>
> Only 15 messages were used, all coming from your website, meaning they were sent by you, your team, or your clients:

  

> **April 28 - May 4**
>
> No conversations during this period.

  

> **April 24-27**
>
> **12** messages were used. Most conversations came from your website, with the exception of one message sent by us to test the script for opening the email service in a new tab:

  

In total, **27** messages were used over the **last two weeks** , with **26 sent from your website**. The messages appear to be live and not generated by bots.

I hope this clears things up.

If you’ve noticed a spike in message usage during a different period, please let me know, and I’ll be happy to check things.

---

<div class="post-metadata">

### Author: ![Petar\_Dietrich](https://sea2.discourse-cdn.com/flex020/user_avatar/community.elfsight.com/petar_dietrich/32/92003_2.png) [@Petar\_Dietrich](https://community.elfsight.com/u/Petar_Dietrich)
#### Post date: [May 6, 2026, 4:26pm UTC](https://community.elfsight.com/t/how-to-stop-bot-spam-in-your-ai-chatbot/142430/4 "2026-05-06T16:26:43Z")

</div>

Hi @Max,

As always, thank you for your quick and thorough support!

Well, there must be something going on. Bots, most likely. However, since our team burned through our test messages early on, I can only infer that any testing performed by Eflsight using our configurator indeed deducted tokens from our live messages. Not a biggie, but I would like to recommend Elfsight implement a method by which any form of testing conducted by Elfsight team members via a customer’s configurator should never deduct any type of message tokens.

Last, can you kindly delete the company information you posted (i.e., stats) and send them to me via DM? By the way, those stats are great. Customers should have access to them. Make them part of an **AI Chatbot Debug Log** available to the customer.

Thank you, amigo!

---

<div class="post-metadata">

### Author: ![Petar\_Dietrich](https://sea2.discourse-cdn.com/flex020/user_avatar/community.elfsight.com/petar_dietrich/32/92003_2.png) [@Petar\_Dietrich](https://community.elfsight.com/u/Petar_Dietrich)
#### Post date: [May 6, 2026, 4:47pm UTC](https://community.elfsight.com/t/how-to-stop-bot-spam-in-your-ai-chatbot/142430/5 "2026-05-06T16:47:36Z")

</div>

Also: (almost forgot)

Can you re-check your above JS and CSS codes and provide an alternate solution? I entered the above JS code into our configurator and the validator rejected it since we’re already using `waitForElement`.

**Details:**

 ![screenshot-js-for-spam-rejected](https://us1.discourse-cdn.com/flex020/uploads/elfsight/original/3X/3/4/34fdb485a2f4dd104fef3b9e118c4fccb129ab60.jpeg)

---

<div class="post-metadata">

### Author: ![Petar\_Dietrich](https://sea2.discourse-cdn.com/flex020/user_avatar/community.elfsight.com/petar_dietrich/32/92003_2.png) [@Petar\_Dietrich](https://community.elfsight.com/u/Petar_Dietrich)
#### Post date: [May 6, 2026, 5:21pm UTC](https://community.elfsight.com/t/how-to-stop-bot-spam-in-your-ai-chatbot/142430/6 "2026-05-06T17:21:14Z")

</div>

**Update:**

In addition to the above, it appears your JS code has an additional issue/error. See below for details and fix.

* * *

The error is happening because you have defined the `waitForElement` function **twice** in the same script scope.

In JavaScript, you cannot declare a `const` with the same name more than once. Since you’ve combined several different features (Form Validation, Button Animations, and the Honeypot) into one file, the second declaration of `waitForElement` is crashing the script.

**How to Fix It**

You only need **one** version of that function. Here is the streamlined fix:

1. **Delete** the definition of `waitForElement` from the **bottom** of your script (around line 457).
2. Ensure there is one global version at the top of your script.
3. **Crucial Logic Fix:** In your Honeypot section, your `handlePreSubmit` function is still trying to read `.value` from a `div` (the container), which will return `undefined` and allow spam through.

**The Corrected “Prevent Spam” Section**

Replace the bottom section of your code (from `/* Prevent Spam via Honeypot */` downwards) with this version. I have removed the duplicate function and fixed the selector logic:

```auto
/* Prevent Spam via Honeypot */

// Note: waitForElement is already declared at the top of the script, 
// so we do not re-declare it here.

const CHAT_PORTAL_SELECTOR = ".es-portal-root[class*='eapps-ai-chatbot']";
const HONEYPOT_CONTAINER_CLASS = "es-field"; 
const HONEYPOT_NAME_VAL = "message_internal";

const insertHoneyPot = (form) => {
  const submitButton = form.querySelector('[type="submit"]');
  const template = form.querySelector('.es-form-field-shortText');
  
  if (!template || !submitButton) return;

  const fieldClone = template.cloneNode(true);
  const input = fieldClone.querySelector('input');
  const placeHolder = fieldClone.querySelector('[class*="TextControlBasePlaceholder-sc"]');
  
  input.type = "text";
  input.value = "";
  input.id = HONEYPOT_NAME_VAL;
  input.name = HONEYPOT_NAME_VAL;
  input.placeholder = HONEYPOT_NAME_VAL;
  input.autocomplete = "off";
  input.tabIndex = -1; // Hide from keyboard users

  if (placeHolder) {
    placeHolder.textContent = "Message";
  }
  
  // Apply class and hide it from human view
  fieldClone.classList.add(HONEYPOT_CONTAINER_CLASS);
  fieldClone.style.position = "absolute";
  fieldClone.style.opacity = "0";
  fieldClone.style.height = "0";
  fieldClone.style.zIndex = "-1";

  form.insertBefore(fieldClone, submitButton);
};

const handleHoneyPotSubmit = (e) => {
  const form = e.target.closest('form');
  // Target the actual INPUT inside our honeypot container
  const honeyInput = form.querySelector(`.${HONEYPOT_CONTAINER_CLASS} input`);
  
  if (honeyInput && honeyInput.value.trim() !== "") {
    console.warn("Spam detected.");
    e.preventDefault();
    e.stopPropagation();
  }
};

const portalObserve = (portal) => {
  const observer = new MutationObserver(() => {
    const chat = portal.querySelector(".es-window-container");
    if (!chat) return;

    const form = chat.querySelector("form");
    const existingHoneypot = form?.querySelector(`.${HONEYPOT_CONTAINER_CLASS}`);
    
    if (form && !existingHoneypot) {
      insertHoneyPot(form);
      const submitButton = form.querySelector('[type="submit"]');
      if (submitButton) {
        submitButton.addEventListener("click", handleHoneyPotSubmit);
      }
    }
  });

  observer.observe(portal, { childList: true, subtree: true });
};

const initHoneyPot = async () => {
  try {
    const portal = await waitForElement(CHAT_PORTAL_SELECTOR);
    portalObserve(portal);
  } catch (err) {
    // Silently fail if portal doesn't load
  }
};

initHoneyPot();

```

**Why this works:**

- **No Redeclaration:** By removing the `const waitForElement` line from the bottom, the script will use the version already defined at the top of your file.
- **Correct Selector:** Instead of `honeyPot.value` (which was looking at a `div`), it now uses `form.querySelector('.es-field input').value`.
- **Better Hiding:** Added `tabIndex = -1` so real users don’t accidentally tab into the “invisible” field while filling out the form.

---

<div class="post-metadata">

### Author: ![Max](https://sea2.discourse-cdn.com/flex020/user_avatar/community.elfsight.com/max/32/710_2.png) [@Max](https://community.elfsight.com/u/Max)
#### Post date: [May 6, 2026, 7:15pm UTC](https://community.elfsight.com/t/how-to-stop-bot-spam-in-your-ai-chatbot/142430/7 "2026-05-06T19:15:15Z")

</div>

Sure, I’ve removed the info with the message stats from the post!

Regarding your suggestion to exclude messages from our team when helping with the widget setup: the thing is, all messages (including test messages) are not free for us and require additional resources and costs.

At the same time, we understand that precise widget configuration is crucial for accurate bot responses. That’s why we’ve added 100 free messages for testing, which are intended for both your own work and for cases when you reach out to us for help.

Anyway, we greatly appreciate your feedback, and we’ve passed it along to the development team

As for the Honeypot script, the solution provided in the post is correct. We add scripts to the Pro Tips category assuming that no other scripts are already in the widget.

If other scripts are already in use (like in your case), adjustments will need to be made depending on the specific situation. Since it’s impossible to account for all possible scenarios, we publish the default version of the script.

If you’re using other scripts and want to add one more, just let us know, and we’ll be happy to assist 🙂

---

<div class="post-metadata">

### Author: ![Petar\_Dietrich](https://sea2.discourse-cdn.com/flex020/user_avatar/community.elfsight.com/petar_dietrich/32/92003_2.png) [@Petar\_Dietrich](https://community.elfsight.com/u/Petar_Dietrich)
#### Post date: [May 6, 2026, 7:27pm UTC](https://community.elfsight.com/t/how-to-stop-bot-spam-in-your-ai-chatbot/142430/8 "2026-05-06T19:27:05Z")

</div>

Thank you, Max.

Did you catch these details (see above as well)? It appears your original JS code needs to be reviewed and corrected.

> **Crucial Logic Fix:** In your Honeypot section, your `handlePreSubmit` function is still trying to read `.value` from a `div` (the container), which will return `undefined` and allow spam through.

and

> - **Better Hiding:** Added `tabIndex = -1` so real users don’t accidentally tab into the “invisible” field while filling out the form.

Cheers!

---

<div class="post-metadata">

### Author: ![Max](https://sea2.discourse-cdn.com/flex020/user_avatar/community.elfsight.com/max/32/710_2.png) [@Max](https://community.elfsight.com/u/Max)
#### Post date: [May 7, 2026, 1:20pm UTC](https://community.elfsight.com/t/how-to-stop-bot-spam-in-your-ai-chatbot/142430/9 "2026-05-07T13:20:19Z")

</div>

My bad, sorry for missing this!

Our devs reviewed this solution and you’re absolutely right! We’ve adjsuted both the script and CSS code in the post and now it should be working fine 🙂

A huge thank you for your help!

---

<div class="post-metadata">

### Author: ![Petar\_Dietrich](https://sea2.discourse-cdn.com/flex020/user_avatar/community.elfsight.com/petar_dietrich/32/92003_2.png) [@Petar\_Dietrich](https://community.elfsight.com/u/Petar_Dietrich)
#### Post date: [May 7, 2026, 5:11pm UTC](https://community.elfsight.com/t/how-to-stop-bot-spam-in-your-ai-chatbot/142430/10 "2026-05-07T17:11:05Z")

</div>

Awesome! You’re welcome. Here to help too! 👍
