Chatwoot Client Portal by ICT Shift

Description

Chatwoot Client Portal by ICT Shift turns your WordPress site into a Chatwoot-backed support portal.

Built by ICT Shift.

Give clients a familiar, branded support area inside WordPress while your team continues working in Chatwoot.

Ideal for businesses that want to:

  • Let logged-in users view and reply to support tickets without leaving your website
  • Offer contact-style intake pages for non-logged-in visitors
  • Keep omnichannel conversations centralized in Chatwoot inboxes (email, livechat, WhatsApp, and more)
  • Sync useful customer context from WordPress and commerce plugins into Chatwoot contact records

For help with Chatwoot setup, self-hosting, or hosting guidance, you can contact ICT Shift at https://www.ictshift.com/.
Plugin support is also available in the WordPress.org support forum.

Features:

  • Ticket list and detail shortcodes
  • Dedicated new-ticket shortcode/form
  • Reply support with optional attachments
  • Ticket status display and update flow
  • Floating livechat widget + embedded chat modes
  • Logged-in user livechat identity (setUser) with optional identity validation (identifier_hash)
  • Contact sync to Chatwoot from WordPress profile, WooCommerce, and FluentCart (best effort)
  • Multi-inbox filtering support
  • Webhook-based synchronization support
  • Translation-ready text domain

Shortcodes:

  • [ictss_support_tickets] – ticket list view (+ New Ticket button)
  • [ictss_support_ticket] – ticket conversation detail view (?ictss_ticket_id=)
  • [ictss_support_new_ticket] – dedicated new ticket form
  • [ictss_support_live_chat_full]
  • [ictss_support_live_chat_box]

Ticket list shortcode

[ictss_support_tickets]

Shows the ticket list only and includes the “+ New Ticket” header button.

Optional ticket list attributes:

  • new_ticket_url – override the “+ New Ticket” button URL
  • ticket_detail_url – override ticket detail page URL

Example:

[ictss_support_tickets new_ticket_url="https://example.com/new-ticket" ticket_detail_url="https://example.com/ticket-details"]

Ticket detail shortcode

[ictss_support_ticket]

Shows a selected ticket conversation using ?ictss_ticket_id= and includes a “Back to My Tickets” button.

Optional ticket detail attributes:

  • tickets_url – override the back-to-list button URL
  • show_unassigned_assignee="yes|no" (default no) – when yes, always show Assigned as Unassigned if no agent is set

New ticket shortcode

[ictss_support_new_ticket]

Optional new ticket attributes:

  • show_attachments="yes|no" (default yes)
  • show_priority="yes|no" (default no)
  • inbox_id – override the Chatwoot inbox used for ticket creation
  • mail_to – override mail transport recipient(s) for this page only
  • require_login="yes|no" (default yes) – set to no for public/contact intake pages
  • tickets_url – override the “Back to My Tickets” button URL after successful submit
  • debug_console="yes|no" (default no) – for admins, logs submit diagnostics to browser console (helpful for mail transport troubleshooting)

Examples:

  • Support intake: [ictss_support_new_ticket show_attachments="yes" show_priority="yes"]
  • Contact intake (public form): [ictss_support_new_ticket show_attachments="no" show_priority="no" require_login="no"]

When require_login="no", the form is available to non-logged-in visitors. Enable hCaptcha in plugin settings for public intake protection.

Recommended page setup:

  • My Tickets page: [ictss_support_tickets] and [ictss_support_ticket] (can be the same page)
  • New Ticket page: [ictss_support_new_ticket] (can also be a separate page)

Optional URL overrides:

  • Ticket list: new_ticket_url, ticket_detail_url
  • Ticket detail: tickets_url (back to list button)
  • New ticket: tickets_url (back to list button after successful submit)

After submit, users are informed that a new ticket can take a few minutes to appear in the ticket list.

Theme compatibility notes:

  • Supported compatibility targets: Astra, Divi, BeTheme, and default WordPress themes.
  • BeTheme compatibility includes field/button normalization for the new-ticket form (including public contact intake pages).
  • Divi compatibility includes suppression of inherited hover pseudo-icons on ICTSS buttons in WooCommerce-themed contexts.

External Services

This plugin relies on external services for support portal functionality and optional anti-bot verification.

Chatwoot

This plugin connects to a Chatwoot instance to provide support ticket, livechat, contact sync, and webhook functionality. The Chatwoot base URL is configured by the site owner in plugin settings and can point to either a self-hosted Chatwoot server or the Chatwoot cloud service.

  • What it is: Chatwoot is an open-source customer support platform. This plugin uses the Chatwoot REST API to sync contacts, create tickets, post replies, and receive webhook events.
  • Data sent: contact identity and profile data (name, email, phone, optional custom attributes), conversation and ticket metadata, message content, and optional file attachments.
  • When data is sent: when loading the livechat widget/embed, creating support tickets, replying to tickets, syncing contacts, loading debug/API diagnostics, and processing webhook events.
  • Browser storage: when the livechat widget or embed is enabled, Chatwoot and optional identity/session-reset flows may use browser cookies and local/session storage to maintain chat session state.
  • Service URL: Determined by the Base URL configured in plugin settings (e.g. https://app.chatwoot.com/ for Chatwoot cloud, or a custom domain for self-hosted deployments).

If using Chatwoot cloud (app.chatwoot.com):

  • Terms of service: https://www.chatwoot.com/terms-of-service
  • Privacy policy: https://www.chatwoot.com/privacy-policy

If using a self-hosted Chatwoot instance:

  • The data controller is the operator of that server. The site owner is responsible for ensuring appropriate terms and privacy policies are in place for their own Chatwoot deployment. Chatwoot’s privacy policy and terms of service do not automatically apply to self-hosted instances.
  • Chatwoot is open-source (MIT licensed): https://github.com/chatwoot/chatwoot

hCaptcha (optional)

This plugin optionally integrates hCaptcha for anti-spam/bot protection on public ticket and contact intake forms.

  • What it is: hCaptcha is a third-party CAPTCHA service. It is only loaded when hCaptcha is explicitly enabled in plugin settings.
  • Data sent: a challenge response token and visitor IP address (remoteip) for server-side verification, and the hCaptcha widget JavaScript for browser-side challenge rendering.
  • When data is sent: only when hCaptcha is enabled in plugin settings AND a visitor submits a public form that requires CAPTCHA verification.
  • Service URL: https://www.hcaptcha.com/
  • Terms of service: https://www.hcaptcha.com/terms.html
  • Privacy policy: https://www.hcaptcha.com/privacy.html

Site owners are responsible for obtaining any consent required in their jurisdiction before enabling external-service features.

Screenshots

  • Chat widget conversation inside WordPress
  • Chat widget embedded inside WordPress page
  • Settings – General tab
  • Settings – Submit Ticket tab
  • Settings – Ticket Details tab
  • Settings – Ticket List tab
  • Submit new ticket form
  • Ticket detail email HTML rendering
  • Ticket detail livechat conversation
  • Ticket detail multiple downloads
  • Ticket detail multiple uploads
  • Ticket list view

Installation

  1. Upload the plugin folder to /wp-content/plugins/.
  2. Activate the plugin through the Plugins screen in WordPress.
  3. Go to Settings > Chatwoot Client Portal by ICT Shift.
  4. Configure settings by tab:
    • General: Base URL, Account ID, API Token, Website Token, widget/embed toggles, livechat identity options, contact sync, revenue currency prefix options.
    • Cron Sync: Scheduled contact refresh enable/interval/scope, sync status overview, manual batch/full runs, emergency stop, manual contact sync test, Chatwoot attribute key reference.
    • Ticket list: Inbox IDs, Tickets List Page URL, New Ticket Page URL.
    • Ticket details: Ticket Detail Page URL, refresh interval, reply transport, attachment fallback options.
    • Submit ticket: New Ticket Transport, New Ticket Inbox ID, mail recipient/routing, hCaptcha and Public Inbox Identifier.
    • Webhooks: Webhook token and webhook URL.
    • Debug: embedded troubleshooting panel (WP_DEBUG-aware).
  5. Save changes on each tab after editing.
  6. Add shortcodes to your portal pages.

FAQ

Does this plugin require Chatwoot?

Yes. A working Chatwoot instance is required.

Which channels are supported?

Ticket list/detail relies on configured Chatwoot inbox data, including email and other supported inbox channels. Livechat identity settings apply only to website widget/embed flows.

How do I prevent livechat impersonation?

Enable identity validation in your Chatwoot website inbox and in plugin settings, then use the same shared secret.

Can I sync WooCommerce and FluentCart fields?

Yes. Enable contact sync in plugin settings. The plugin syncs core profile fields and selected commerce attributes when available, including total revenue fields:
ictss_total_revenue_woo
ictss_total_revenue_fluentcart
You can also configure revenue display prefix in Settings > Chatwoot Client Portal by ICT Shift > General using Show Currency Prefix for Revenue and Revenue Currency Prefix (for example: EUR, $, USD).

How can I still expose extra customer context in Chatwoot contact records?

The plugin stores fallback context in Chatwoot contact additional attributes during contact sync (for example: FluentCRM URL, latest WooCommerce/FluentCart order summaries, and latest FluentBoards tracked time when available).

How can I show synced values in Chatwoot’s Attributes tab?

Create Contact Attributes in Chatwoot settings with keys: ictss_wp_user_url, ictss_fluentcrm_url, ictss_wc_last_order_summary, ictss_fc_last_order_summary, ictss_fluentcart_order_url, ictss_fb_last_time, ictss_fb_last_task (Text type is fine). The plugin will mirror values to custom_attributes when data exists.

If WooCommerce / FluentCRM / FluentBoards is not installed, sync still works; those specific values are simply skipped.

Can I test contact sync on production without WP_DEBUG?

Yes. In Settings -> Chatwoot Client Portal by ICT Shift -> Cron Sync, use the Manual Sync Now form (enter a WordPress user email). The same tab shows latest sync status (including scheduler health and progress), supports Run Cron Batch Now with skip breakdown, Sync All Now (All Batches) for catch-up, and Emergency Stop Cron for lock/abort recovery.

Can I control how scheduled sync selects users?

Yes. In Cron Sync, choose scope as all users, commerce users (WooCommerce or FluentCart), WooCommerce-only, or FluentCart-only. You can also set interval (hourly, twice daily, daily). Scheduled sync runs in batches and auto-continues in the background with short-delay follow-up batches until the active cycle is complete.

How are local phone numbers normalized for Chatwoot?

Phone sync is strict E.164. The plugin first tries country/profile hints from WordPress/commerce data. The Default Phone Country Code setting is fallback-only and is used only if no hint resolves a country. If country still cannot be resolved, local phone updates are skipped to avoid wrong-country values.

How do I choose the correct FluentCRM contact URL route?

In Settings -> Chatwoot Client Portal by ICT Shift -> General, set FluentCRM Contact Route to subscribers or contacts.

How to verify: open a contact in FluentCRM and inspect the browser URL hash after #/.
Examples:
#/subscribers/38/ -> choose subscribers
#/contacts/38 -> choose contacts

How are company/city/country synced to Chatwoot contact details?

The plugin mirrors these values to Chatwoot additional_attributes for compatibility with Chatwoot contact sync behavior:
– company -> additional_attributes.company_name
– city -> additional_attributes.city
– country (ISO code when available) -> additional_attributes.country

WooCommerce and FluentCart billing fields are used as source values when present.

What happens when require_login=”no” is used on the new ticket shortcode?

The form is available for non-logged-in visitors and is suitable for contact-style intake pages. In this mode, the “Back to My Tickets” success button is not shown for non-logged-in users.

What happens on uninstall?

By default, uninstall removes plugin options, plugin transients, local conversation cache posts (ictss_conversation), and chatwoot_contact_id user meta mappings.

If you need to preserve data, define ICTSS_PRESERVE_DATA as true before uninstall.

Reviews

There are no reviews for this plugin.

Contributors & Developers

“Chatwoot Client Portal by ICT Shift” is open source software. The following people have contributed to this plugin.

Contributors

Changelog

2.0.12

  • Removed duplicate screenshot files from plugin package assets to reduce plugin ZIP size.
  • Kept WordPress.org listing screenshots in the repository root /assets directory.

2.0.11

  • Updated plugin page documentation for clearer setup and usage guidance.
  • Fixed screenshot visibility in the WordPress.org plugin listing.
  • Improved readme text formatting and encoding for cleaner display in the plugin directory.

2.0.10

  • Hardened new-ticket mail attachment handling by attaching uploaded files in-memory during send flow, avoiding temporary file writes while preserving attachment names.
  • Excluded local docs/page-export artifacts from release packaging output to keep submission ZIPs clean and deterministic.

2.0.9

  • Refactored shortcode/admin/webhook/API diagnostics logging to remove file-wide error_log suppressions and keep only narrow, WP_DEBUG-gated log helpers.
  • Completed shortcode request/upload hardening pass by fixing stale helper usage and keeping nonce-gated upload normalization paths explicit.
  • Reduced suppression surface in settings/debug flows and narrowed SQL suppression scope where PHPCS allows line-level scoping.
  • Reworked runtime contact/conversation lookup paths to avoid slow meta_query usage in hot flows by using bounded paged scans and deterministic conversation indexing.
  • Standardized request filtering to explicit sanitizing filters across runtime handlers (no unsafe raw filter usage) while preserving strict validation and context-aware output escaping.
  • Added strict reviewer-facing development directives for WordPress-native methods first, sanitize/validate/escape lifecycle, nonce/capability fail-closed enforcement, and mandatory pre-submission pattern scans.

2.0.8

  • Strengthened WordPress.org submission hardening for nonce verification and request sanitization reviews by aligning guarded superglobal reads with explicit checker-safe validation/sanitization paths.
  • Added security-sniff coverage to local PHPCS ruleset (WordPress.Security.NonceVerification and WordPress.Security.ValidatedSanitizedInput) so recurring review points fail locally before release.
  • Improved release preflight pattern checks for settings slug/title detection to avoid brittle formatting dependencies during release validation.

2.0.7

  • Hardened shortcode/admin/AJAX request handling by removing raw input filter patterns and enforcing immediate sanitization plus strict scalar validation for POST/GET reads.
  • Refined nonce and permission guard flows across form submits and AJAX endpoints to keep security checks explicit and non-bypassable.
  • Applied submission-readiness cleanup for WordPress.org review consistency across request, upload, and output handling paths.

2.0.6

  • Restored shortcode hardening updates and fixed ticket-list first-load filtering by normalizing invalid/empty status query values to all.
  • Prevented a regression where opening the ticket list with an empty ictss_status query parameter could show “No tickets found” while searches still returned tickets.

2.0.5

  • Hotfix: restored ticket-list shortcode request handling to the previous stable path to resolve a production regression where valid users could see “No tickets found.”
  • Kept webhook authentication/security hardening introduced in 2.0.4 unchanged.

2.0.4

  • Added progressive webhook authentication modes: token-only (default), token-or-signature transition mode, and signature-required strict mode.
  • Added optional Chatwoot signature verification support with timestamp freshness checks and delivery replay protection.
  • Hardened webhook diagnostics by redacting sensitive payload fields and trimming stored debug payload data.

2.0.3

  • Hardened nonce, capability, and request sanitization checks across ticket forms, admin actions, webhook tools, and livechat identity AJAX handlers.
  • Tightened upload request handling so file arrays are only processed through verified nonce-gated paths.
  • Refreshed submission-readiness validation and packaging after WordPress.org review fixes.

2.0.2

  • Removed legacy Chatwoot sidebar integration from plugin settings and runtime bootstrap.
  • Cleaned documentation to remove deprecated sidebar-token and sidebar-endpoint instructions.
  • Kept contact-context sync guidance focused on Chatwoot contact attributes/additional attributes.

2.0.1

  • Clarified External Services section to correctly distinguish self-hosted Chatwoot deployments from Chatwoot cloud. Self-hosted instances are now documented separately, noting that the data controller is the server operator and that chatwoot.com terms/privacy do not automatically apply.

2.0.0

  • Added contributor username to readme.txt Contributors header.
  • Added External Services section to readme.txt documenting Chatwoot and hCaptcha integrations (data sent, terms, privacy links).
  • Added .distignore entry to exclude design PSD assets from distribution archive.
  • Removed DONOTCACHEPAGE global define, replacing with targeted nocache_headers() calls scoped to debug-mode form renders only.
  • Refactored all GET parameter reads to use filter_input(INPUT_GET) via private helpers, removing direct $_GET superglobal access.
  • Wrapped all inline script content in (new Function(wp_json_encode(…)))() boundary for safe dynamic JS injection.
  • Removed JSON_UNESCAPED_UNICODE and JSON_UNESCAPED_SLASHES flags from JSON-encoded inline script output.
  • Renamed livechat embed shortcodes from ict_shift_support_live_chat_* to ictss_support_live_chat_* for prefix consistency.
  • Ensured all $_FILES access is routed through the allowlisted get_uploaded_files_from_field() helper.

1.9.9

  • Added stronger release preflight checks for WordPress.org submission readiness (external-services docs and packaging exclusions).
  • Hardened attachment upload handling by accepting only real uploaded temp files in multipart upload paths.
  • Improved settings/admin compliance messaging and nonce handling for ticket status updates.
  • Fixed frontend asset loading reliability for ICTSS shortcodes to prevent missing styling in builder/theme render paths.
  • Removed explicit textdomain loading call to align with current WordPress.org plugin directory guidance.

1.9.8

  • Improved ticket-list performance by reducing unnecessary enrichment calls and adding enrichment caching.
  • Hardened release/package validation flow and resolved remaining plugin-check findings for submission readiness.
  • Added compatibility hardening for BeTheme and Divi, including button/form UI normalization.
  • Added public intake behavior refinement for require_login="no" and asset cache-busting for CSS/JS updates.

1.9.7

  • Added livechat identity controls (auto-identify, optional identity validation hash, auth-session reset)
  • Added WordPress/WooCommerce/FluentCart contact sync service
  • Added debug status panel and manual one-time contact sync action
  • Fixed settings tab save behavior so tab saves no longer clear other-tab values