WP Manifestindependent plugin directory
manifest / ai / nimdai-cara-chat

Nimdai Cara Chat

WordPress plugin that embeds the Nimdai Cara AI chat widget on any WP site

by Nimdai · github.com/nimdai-ocl/nimdai-cara-chat · website

0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/nimdai-ocl/nimdai-cara-chat/archive/refs/heads/main.zip

Nimdai Cara Chat — WordPress Plugin

A WordPress plugin that embeds Cara, Nimdai's greeting + FAQ AI persona, as a chat widget on any WP site.

What it does

  • Renders a floating chat bubble (bottom-right by default) on every page
  • Opens to a 360×500 chat panel
  • Sends visitor messages to Nimdai's public /v1/widget/chat endpoint
  • Displays Cara's reply (or whichever persona you configure)
  • Persists chat history in the visitor's localStorage (per-browser)
  • Mobile-responsive — fills the viewport on phones
  • Admin page at Settings → Nimdai Cara Chat
  • Self-serve OAuth Connect — no manual credential paste (v1.1+)

What's new in 1.1

  • "Connect to Nimdai" button replaces the manual Business ID / widget token fields. One click opens a popup at https://api.nimdai.com/v1/oauth/authorize (or your configured Nimdai URL); after admin authenticates (if needed), the plugin exchanges the auth code for a hashed refresh token stored in wp_options. No long-lived secrets live in plaintext in the DB.
  • Disconnect button clears the connection state when you need to swap tenants or uninstall.
  • Front-end session cookies continue to work as before (the chat endpoint is still public on the dev/staging Nimdai deployment).

Files

nimdai-cara-chat/
├── nimdai-cara-chat.php        Main plugin file (header + bootstrap)
├── readme.txt                  WP-format readme
├── README.md                   This file
├── includes/
│   ├── class-nimdai-plugin.php Singleton bootstrap + option defaults
│   ├── class-nimdai-oauth.php OAuth orchestration (B10 / Task 11)
│   ├── class-nimdai-admin.php  Settings page (Settings → Nimdai Cara Chat)
│   ├── class-nimdai-widget.php Front-end asset enqueue + markup render
│   └── class-nimdai-api.php    HTTP client (wp_remote_post wrapper)
├── assets/
│   ├── css/cara-widget.css     Bubble + panel styles (vanilla CSS vars)
│   └── js/
│       ├── cara-widget.js     Vanilla JS chat client (no jQuery)
│       └── cara-oauth-popup.js OAuth popup orchestrator (B10 / Task 11)
└── templates/
    ├── admin-page.php          Admin settings form
    └── widget-html.php         Bubble + panel markup

Install

Option A — Manual upload

# From your WP root
cp -r nimdai-cara-chat /path/to/wp-content/plugins/
wp plugin activate nimdai-cara-chat --allow-root   # or via wp-admin

Option B — Zip upload

  1. Zip the nimdai-cara-chat/ directory.
  2. WP-Admin → Plugins → Add New → Upload Plugin → choose zip → Install → Activate.

Configure

  1. WP-Admin → Settings → Nimdai Cara Chat
  2. Click Connect to Nimdai. A popup opens at your Nimdai deployment's /v1/oauth/authorize endpoint. If you're not already logged into that Nimdai tenant, the popup shows a login form (browser-first fallback).
  3. After admin login, the popup redirects back to your site's wp-admin/admin-ajax.php?action=nimdai_cara_callback&code=… endpoint.
  4. WP exchanges the code for a refresh_token, hashes it with wp_hash_password(), and stores it under the nimdai_cara_refresh_token option.
  5. The admin page reloads with a green "Connected to Nimdai" banner showing the business_id and the granted scope.
  6. Optionally adjust:
    • API URLhttps://api.nimdai.com (production) or http://172.18.0.185:8080 (local Nimdai dev container)
    • Persona — Cara is the default; switch to Hugo/Seren/Kai/Otto if you want a different persona's voice.
    • Greeting — first message visitors see.
    • Theme color — bubble + accent.
    • Position — bottom-right / bottom-left / top-right / top-left.
    • Enabled — toggle the global bubble on/off.
  7. Click Verify connection — pings Nimdai /healthz and /v1/widget/config with your business_id to confirm the credentials resolve.
  8. Save. The bubble appears on every front-end page.

Callback URL limitation (dev build)

The plugin's OAuth callback URL is computed as:

https://<your-wp-site>/wp-admin/admin-ajax.php?action=nimdai_cara_callback

For this callback to be accepted by Nimdai, the oauth_clients.redirect_uris row for client_id="nimdai-cara-chat" must contain a prefix-matching entry. The seeded development OAuthClient only has https://example.com/wp-admin/admin-ajax.php?action=nimdai_cara_callback, which means:

  • Dev / local testing: set your WP site's host to example.com (e.g. wp-config.php define with WP_HOME/WP_SITEURL, or a local /etc/hosts mapping) so the callback resolves to the seeded URL.
  • Real customer installs: the customer's callback URL must be added to the Nimdai oauth_clients.redirect_uris row out-of-band (a Nimdai-side self-serve flow is planned but not part of this build). Until that lands, the plugin will work end-to-end on the dev stack but not on a production WP install without a one-time DB tweak.

The Nimdai prefix matcher uses scheme+host+path; query strings may vary. If https://jiao-tai.com/... is registered, then any WP site on jiao-tai.com works automatically.

How the chat call works

The plugin posts to <api-url>/v1/widget/chat with:

{
  "business_id": "<UUID>",
  "persona":     "cara",
  "message":     "<user text>",
  "conversation_id": "<server-returned id from prior turn, if any>"
}

Nimdai returns:

{
  "conversation_id": "<UUID>",
  "response":        "<Cara's reply>",
  "persona":         "cara",
  "tokens_in":       1834,
  "tokens_out":      135,
  "tool_calls":      []
}

The plugin stores conversation_id in localStorage so the conversation persists across page reloads in the same browser.

Notes on auth

  • POST /v1/widget/chat is currently in Nimdai's ADMIN_BYPASS_PATHS (no token check). When auth is enforced, the plugin will use the OAuth flow to mint a short-lived widget_jwt via POST /v1/oauth/session (which reads the stored refresh-token hash and returns an HttpOnly cookie valid for 30 minutes).
  • The plugin can fetch a short-lived JWT via GET /v1/widget/config?business_id=<UUID> — exposed via the "Verify connection" button.

Troubleshooting

Symptom Fix
Bubble doesn't appear Settings → Nimdai Cara Chat: confirm Enabled is checked and saved.
Connect popup shows error Confirm your Nimdai API URL is correct and reachable from the WP host. The popup must be allowed (disable popup blocker).
redirect_uri mismatch The seeded OAuthClient only allows https://example.com/... callbacks. See Callback URL limitation above.
Verify connection fails Confirm you're connected (green banner); API URL is reachable; Business ID exists.
Chat returns 500 The Business ID may not exist on the Nimdai side. Verify with the portal.
CORS error in browser console The Nimdai API must allow your site's origin via CORS_ORIGINS.
Panel doesn't open Check browser JS console for errors. The widget requires ES2017+ (fetch, Promise).

End-to-end test (verified 2026-08-23)

  • WordPress 6.x (Docker container wordpress:latest)

  • Plugin activated via WP-CLI

  • Business ID 6a0877e7-2c48-46cc-94ce-2abb2d62a952 (LowVerify tenant)

  • API URL http://172.18.0.185:8080

  • Visitor message: "What do you do?"

  • Cara response (truncated):

    Hi there! I'm Cara, an AI assistant here to help you with general questions and guide you to the right team member if needed. What I can help with:

    • Greetings and general inquiries
    • Basic information about our services and offerings
    • FAQs and light troubleshooting
    • Routing you to the right specialist when needed My team includes:
    • Hugo — for complex technical issues and detailed troubleshooting
    • Seren — for sales negotiations and plan comparisons
    • Kai — for documentation and training requests
    • Otto — for scheduling, logistics, and supply chain questions → What can I assist you with today?
  • HTTP status: 200

  • Tokens: in=1834, out=135

  • Confirms business_id and persona are passed correctly in the request body.

License

MIT.