WordPress & WooCommerce
Overview
Habla ships a first-party WordPress & WooCommerce plugin that drops the streaming chat widget on every public page, syncs the site's content as a knowledge source, and (when WooCommerce is active) deeply integrates with the store — product cards, coupon application, order lookup, lead mirroring, and abandoned-cart re-engagement.
The plugin lives in the Habla monorepo at
wp-plugin/pitchbar/ (technical slug pitchbar)
and ships as a versioned zip you can install from
Plugins → Add New → Upload Plugin in any WordPress
6.4+ install on PHP 7.4+. The customer-visible plugin name in
WordPress admin is Habla (Settings → Habla).
The plugin is optional. For widget-only deployment on any HTML site (including WordPress), use the manual embed snippet documented in Embed the widget. Manual embed loads the chat widget but is not a full substitute for this plugin's WordPress content sync, WooCommerce integration, order lookup, coupon apply, or lead mirroring.
/api/v1/wp/* and the plugin's /wp-json/pitchbar/v1/*.What this plugin does
- Widget embed — one asynchronous
<script>tag injected intowp_footeron every public page, scoped to the post types you opt into. RTL-aware. Hidden onwp-admin,wp-login, AJAX, REST, XML-RPC, and cron requests. - Content sync — bulk + delta ingest of posts, pages, custom post types, and WooCommerce products into a Habla knowledge source. Resumable on shared hosting with a 30s exec cap.
- Page-builder rendering — Elementor, Divi, Beaver Builder, Oxygen, and Bricks pages are rendered via each builder's native API so their visible HTML actually reaches the RAG store (instead of empty
post_content). - Shopper context — a logged-in WooCommerce customer's
wp_user_id+email_hash(never plaintext) are signed and forwarded to the chat session so the agent knows who's talking. - Order lookup — the
lookup_ordertool calls back into/wp-json/pitchbar/v1/orders/lookupover HMAC-signed POST so the agent can answer "where's my order?" without exposing customer data. - Coupon emission & apply — the agent renders
<coupon/>cards in chat; the Apply button stages the code in a transient and applies it on the visitor's next cart load. - Lead mirroring — every Habla lead is pushed back into WordPress as a WC customer (or WP subscriber when Woo is absent) with conversation correlation in user meta.
- Abandoned-cart trigger — a tiny front-end script mirrors WC cart events into
localStorage; the widget proactively engages when the cart sits idle past the configured threshold.
Compatibility matrix
| Component | Tested range |
|---|---|
| WordPress | 6.4 → 6.6 |
| PHP | 7.4 → 8.4 |
| WooCommerce | 8.0 → 9.x (optional — plugin core works without WC) |
| Multisite | Supported (per-site activation; each site connects to its own Habla workspace) |
| Page builders | Elementor (Free + Pro), Divi, Beaver Builder, Oxygen, Bricks |
| Theme | Theme-agnostic. Widget renders in a Shadow DOM isolated from theme CSS. |
| RTL locales | Yes (Arabic, Hebrew, Persian, Urdu, etc.). Widget mirrors via data-page-dir. |
Distribute the plugin
How tenants obtain the zip depends on how the platform is operated. The app does not expose a built-in zip download to every workspace member by default.
Platform super_admin build (operator only)
Platform super_admin users can produce an install-ready
.zip from inside the Habla admin without ssh access.
Open /admin/integrations/wordpress:
- Click Build latest. The server runs
php artisan pitchbar:build-wp-pluginagainst the bundledwp-plugin/pitchbar/source tree and writes a versioned archive tostorage/app/private/wp-plugin-builds/pitchbar-{version}.zip. - Click Download on the resulting row. The archive is streamed back with the correct
Content-Disposition; it contains a top-levelpitchbar/directory (technical slug unchanged). - The archive excludes dev-only files (
.DS_Store,node_modules/,tests/,.git*) so what your tenants upload is exactly what WordPress should install.
Workspace owners, admins, editors, and viewers cannot access this
build/download surface — it is gated to super_admin only.
Tenant-facing download link
Workspace owners and admins who open
Integrations see a
Download plugin button when a platform
super_admin has configured
wordpress_plugin_download_url in
Plugin distribution.
That is the normal Habla SaaS customer path.
When that URL is blank, the integrations card tells customers the plugin is currently unavailable and to contact their workspace administrator — no download anchor is rendered.
Operator distribution (self-host)
Self-hosted operators can also build the zip inside the platform admin or from the CLI — see Plugin distribution.
Permissions at a glance
- Plugin zip build/download — platform
super_adminonly (/admin/integrations/wordpress). - Integrations page + optional download link — workspace owner or admin (
/app/integrations). - API tokens — workspace owner or admin; scope
wp:integration. Editors and viewers are blocked. - WordPress plugin settings —
manage_optionsin WP admin (Settings → Habla).
Security model at a glance
The plugin and the Habla server authenticate each other with two distinct credentials, in opposite directions:
- Plugin → Habla: bearer API token. Created in
/settings/api-tokens, scopewp:integration. Habla stores only the SHA-256 hash of the plaintext. The plugin keeps the plaintext inwp_options(treat aswp-config.php-level secret). - Habla → Plugin: HMAC-SHA256 signature using the per-token
shopper_signing_secret. The plugin receives this secret in the handshake response and stores it locally. Habla uses it to sign every callback (order lookup, coupon apply, lead push) so the WordPress REST endpoints can verify the caller is Habla without ever holding the bearer plaintext. - Replay protection: both directions enforce a 5-minute timestamp window on the HMAC signature.
See REST API reference for the exact signature scheme and verification code path.
Current release
Plugin version 2.0.6. Notable since v1.x:
2.0.x patch series
- 2.0.6 — Customer-facing rebrand to Habla. WordPress admin menu and settings screen now read Settings → Habla. Technical identifiers are unchanged: plugin slug
pitchbar, REST namespace/wp-json/pitchbar/v1/*, option keys, and HMAC headers (X-Pitchbar-Signature, etc.). - 2.0.5 — Simplified Chinese (zh_CN) + standalone bundled documentation. Buyer-requested zh_CN language pack ships both
pitchbar-zh_CN.po(editable) andpitchbar-zh_CN.mo(compiled, what WP loads).pitchbar/documentation.htmlnow ships inside the install with the full Mintlify-style reference — open in any browser, no internet required.php artisan pitchbar:build-wp-plugincompiles every.poto.moautomatically before zipping, so future language packs ship correctly without GNUmsgfmton the build host. - 2.0.4 — Admin column width fix. On the WooCommerce Products list (and other crowded list tables) the “Pitchbar” column was rendering one letter per line because WP's auto-width algorithm starved it of pixels. Forced to 110px via an
admin_headstyle block. - 2.0.3 — “Indexed” admin badges + empty-body fallback. Posts, Pages, and Products lists now render a green “Indexed” pill, yellow “Out of date” pill, or gray “Not indexed” pill per row based on the sync timestamp + content hash the plugin stamps on every push. Featured-image-only / builder-stub posts whose
the_contentcollapses to empty are synthesised fromtitle + excerpt + taxonomy termsclient-side so they always have indexable text. - 2.0.2 — Empty-body posts + every product type. Pre-fix a post-sync batch died with
posts.N.content_html field is requiredthe first time any post had an empty body. Pre-fix the product syncer filtered to[simple, variable, grouped, external]which silently dropped subscriptions, bundles, memberships, bookings, and custom types. Both fixed; a fallbackWP_Querycovers hosts whosewc_get_productshook chain hides everything. - 2.0.1 — Diagnostic Test connection. The generic “Connection failed” message is gone. The plugin now surfaces HTTP status, the URL it tried, the transport-level cURL / DNS code on network failure, and the first 800 chars of the upstream response body. A “Show details” toggle reveals the full diagnostic block. HTTP-status-aware hints (401 → reissue token, 403 → missing scope, 404 → not deployed, 5xx → server log).
2.0.0 — major release
- Page-builder content actually reaches the RAG store (was empty for Elementor/Bricks/Oxygen).
- WooCommerce load-order race fixed — the plugin's WC-dependent hooks now defer to
woocommerce_loadedinstead of trustingclass_exists('WooCommerce')atplugins_loadedpriority 10. - Sync is resumable across multiple WP-Cron ticks — large catalogs no longer hit the 30s exec cap.
- Coupon enumeration switched from
wc_get_coupons()(not public API) to theshop_couponCPT directly. abandoned_cartrule kind exposed in the agent Behavior triggers admin.- RTL mirroring + admin background-sync notice.
See application changelog for the full release history.