Skip to content
NovaSpark Docs v1.0.0
Live Demo Support

Build

Connect a chatbot

Point a NovaKit Form at your chatbot, and let the Mascot react while it answers.

A chat box on your site is three things: a NovaKit Form the visitor types into, something that answers, and, if you like, a Mascot that shows what is going on. NovaKit does not include an AI service. This page shows how to connect the one you use.

1. Build the form #

  1. Add NovaKit FormSet Powered By to Custom Action.
  2. Turn on Stay on PageThis is what stops the reload: the form sends in the background and answers in place.
  3. Set HandleUse chatbot, as the examples here do. It tells your code which form this is.
  4. Add the fieldA Form: Textarea named chatbot. Turn on Required, so an empty message is refused. Under Behaviour, turn on Grow With Text and Enter Sends, and Start Compact if it should open out when clicked. See A prompt box.
  5. Add the buttonA Form: Submit. For an icon-only button, choose an Icon and leave Text empty.

That already works with nothing connected: pressing the button clears the field and shows the Sent Message. It is how a demo can behave without paying for an AI service. If the Mascot answers instead, set Style → Message → Show to None and give its Form Sent row a Say line.

Quick prompts

Buttons that put a ready-made prompt in the field, like the Write and Code chips under a chat box. On each button’s Link:

  1. Choose the tagPress the dynamic tags icon and choose NovaKit Trigger Link.
  2. Set the actionAction: Fill Form Field.
  3. Say where and whatField: chatbot, the field’s Name. Text: the prompt, such as “Write a welcome email for my new customers”. Put several, one per line.
  4. Pick an orderOrder: Random (the default) never repeats the same prompt twice in a row; In Order goes through the list one press at a time.
  5. Send it, or notLeave Send Right Away off to let the visitor edit it first, or turn it on to send it at once.

The button can sit anywhere on the page. It fills the nearest field with that name, puts the cursor at the end, and opens a Start Compact field. A Mascot reacts as if the visitor had typed. Each prompt is one line. Field also takes a CSS selector, such as #chat textarea.

A “surprise me” button. With a real AI behind the form, one prompt with Send Right Away on, such as “Surprise me with something interesting to learn today”, gets a different answer every time. Without one, as on a demo, list several prompts and let the button pick.

A Mascot added to the page hears the form by itself. These are its default Trigger rows, so a new one needs nothing. For one you added earlier, add them above its Default row, and add a Thinking expression with Effect set to Thinking Dots.

ShowWhenHold For
HappyForm Sent3
SadForm Failed3
BoredForm Invalid2
ThinkingForm Sending0

Keep Form Sent above Form Sending, because the top row wins. Add a Say line to any row for a speech bubble. Minimum Sending Time on the form keeps a very fast answer from flashing past before the mascot has looked busy.

3. Connect your chatbot #

Choose by how your chatbot is reached:

Your chatbot isSend ToHow it connects
An AI API with a secret keyEmptyA PHP filter, so the key stays on your server
A webhook: n8n, Make, your own serviceIts URLIt answers with JSON
A hosted chat widgetEmptyA script passes the message on

An AI API, through PHP

The right choice for anything with an API key. A key in a page’s JavaScript can be read by every visitor. Add this to your child theme, and change the request to match your provider:

novaspark-child/functions.php
add_filter( 'nk_form_custom_result', function ( $result, array $values, string $handle ) {
    if ( 'chatbot' !== $handle ) {
        return $result;
    }

    $response = wp_remote_post( 'https://api.example.com/chat', [
        'timeout' => 30,
        'headers' => [
            'Authorization' => 'Bearer ' . MY_CHAT_KEY, // Define it in wp-config.php.
            'Content-Type'  => 'application/json',
        ],
        'body'    => wp_json_encode( [ 'message' => $values['chatbot'] ?? '' ] ),
    ] );

    if ( is_wp_error( $response ) ) {
        return $response; // The visitor sees your Failed Message, never this error's text.
    }

    $body = json_decode( wp_remote_retrieve_body( $response ), true );

    return [
        'reply'   => $body['reply'] ?? '',
        'message' => '', // Empty: no notice under the form, as the reply shows elsewhere.
    ];
}, 10, 3 );

What you return becomes the event’s data. message is special: text replaces the Sent Message for this answer, and empty shows no notice at all. Then put the reply on the page. This shows it in the mascot’s bubble:

your-script.js
document.addEventListener( 'nk-form:success', ( event ) => {
    if ( 'chatbot' !== event.detail?.handle ) {
        return;
    }

    document.dispatchEvent( new CustomEvent( 'nk:mascot', { detail: {
        say: event.detail.data.reply,
        hold: 8,
    } } ) );
} );

Add a rate limit before you go live. This form is public, and every message spends your API credit. Count requests per visitor in your filter, and return a WP_Error past your limit.

A webhook

Put its URL in Send To. The browser posts the fields straight to it, and it answers with JSON such as { "reply": "Hello!" }, which arrives as the same event.detail.data, so the script above works unchanged. Two things to check:

Cross-origin accessIt must send an Access-Control-Allow-Origin header for your site. Without one, the browser hides the answer and the form reports a failure.
No secretsThe URL is visible in the page, so anyone can post to it. Limit requests on the webhook’s side.

A script, or a hosted chat widget

nk-form:submit fires first and can be cancelled. Cancel it, do your own work, and report when you are done. The form and the mascot carry on as if they had sent it themselves. This is also the route for word-by-word replies:

your-script.js
const form = document.querySelector( '[data-nk-custom-form="chatbot"] form' );

form.addEventListener( 'nk-form:submit', async ( event ) => {
    event.preventDefault();

    const report = ( name, data ) => form.dispatchEvent(
        new CustomEvent( name, { bubbles: true, detail: { handle: 'chatbot', data } } )
    );

    try {
        const reply = await myChat.send( event.detail.fields.get( 'chatbot' ) );

        report( 'nk-form:success', { reply, message: '' } );
    } catch ( error ) {
        report( 'nk-form:error', {} );
    }
} );

myChat stands for your provider’s script. Intercom’s, for example, is Intercom( 'showNewMessage', text ). Always report one of the two events, or the form stays busy.

Events #

All bubble, so one listener on document hears every form. handle is the form’s Handle setting.

EventWhendetail
nk-form:submitBefore sending. Cancel it to send it yourselfhandle, fields (FormData)
nk-form:successIt was senthandle, data
nk-form:errorIt could not be senthandle, status, data
nk-form:doneLast, after either result. The form accepts another messagehandle

A WP_Error’s message never reaches the browser, because it may name a key or a server. If you want the browser to have something, put an array in its data: new WP_Error( 'limit', 'Too many', [ 'message' => 'Please wait a minute.' ] ).

Good to know

Page cachingA cached page can hold an expired security token. The form gets a fresh one and tries again by itself, so visitors never see this.
Text onlyValues are cleaned as plain text, which removes line breaks from a textarea. The bubble and the notice show plain text too, so a reply cannot inject markup.
Waiting for the whole replyThe PHP and webhook routes deliver the reply when it is complete. For word-by-word replies, use the script route and call say as the text grows.
Esc