# Better Messages - WordPress Private Messaging Plugin > Documentation for Better Messages, a real-time private messaging plugin for WordPress with WebSocket support, video/audio calls, AI chatbots, and mobile apps. ## Additional Documentation - [Hooks & Functions Full Content](/llms-hooks-full.txt) — PHP and JavaScript hooks, filters, and functions - [REST API Full Content](/llms-rest-api-full.txt) — All REST API endpoints ## Voice Messages Add-on for WordPress Chat Voice Messages is an addon for Better Messages that allows users to send recorded voice messages in conversations. ## How it works When installed, a microphone button appears in the message input area. Users can press and hold (or click to toggle) to record a voice message, then send it like any other message. Recorded voice messages are stored on your website hosting in efficient MP3 format and do not consume much storage space. AI-powered transcription via Better Messages Cloud AI or OpenAI can automatically generate text transcripts of voice messages. ## Key capabilities - Record and send voice messages directly in conversations - Microphone button in the message input area - Efficient MP3 format storage on your server - Configurable maximum recording duration - Auto-deletion of voice messages after a specified number of days - Role-based restrictions for sending voice messages - AI-powered transcription via [Better Messages Cloud AI](/docs/websocket/cloud-ai/) or OpenAI - Playback controls for received voice messages - Works in all conversation types (private, group, chat rooms) ## How to install Install the Voice Messages addon through the WordPress plugins screen or upload the addon files to your `/wp-content/plugins/` directory. Activate the addon through the **Plugins** screen. ## Settings Configure the addon at **WP Admin → Better Messages → Settings → Voice Messages**. ### Max Recording Duration Set the maximum recording duration in seconds. During recording, a timer displays the current and maximum time. The timer turns red when 10 seconds or less remain, and recording automatically stops when the limit is reached. ### Auto-Delete Automatically delete voice messages after a specified number of days. Set to `0` to disable auto-deletion. Two deletion modes are available: - Complete — fully deletes the message from the conversation - Replace — removes the audio file but keeps the message with a "Voice message expired" indicator ### Role Restrictions Restrict which user roles can send voice messages. Selected roles will not see the microphone button in the message input area. ### Voice Transcription Enable AI-powered transcription to automatically generate text transcripts of voice messages. Two providers are available: - **Better Messages Transcription AI** — Included with the WebSocket license at no additional cost. No third-party API keys required. Supports 99+ languages with automatic detection. See [Better Messages Cloud AI](/docs/websocket/cloud-ai/) for details. - **OpenAI Transcription API** — Requires an OpenAI API key configured in **Integrations** → **OpenAI**. Supports model and prompt selection. ## Troubleshooting ### Incorrect response MIME type error On some servers, you may see the following error when trying to record a voice message: :::danger Error message Error: TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'. ::: There are two ways to fix this: 1. **Configure your server** to serve the WASM file at `https://yourdomain.com/wp-content/plugins/bp-better-messages-voice-messages/assets/js/encoder.wasm` with the `Content-Type: application/wasm` header. 2. **Add this line** to your website's `wp-config.php` file: ```php define('BETTER_MESSAGES_WASM_FALLBACK', true); ``` After applying either fix, voice message recording will work correctly. --- ## Better Messages AI & MCP Integration — Connect Claude, Cursor, ChatGPT # AI & MCP Integration :::caution Experimental Feature This feature is experimental and currently available only for site administrators. The WordPress Abilities API and MCP ecosystem are still evolving, and the API may change in future versions. ::: Better Messages registers [WordPress Abilities](https://developer.wordpress.org/apis/abilities-api/) that allow AI tools to interact with your messaging system. AI assistants can send messages, read conversations, search users, manage participants, and more. :::info Requirements - WordPress 6.9 or higher ([Abilities API](https://developer.wordpress.org/apis/abilities-api/) is included in WordPress core) - Better Messages 2.14.11 or higher - For MCP connections: [WordPress MCP Adapter](https://github.com/WordPress/mcp-adapter) plugin ::: ## Available Abilities ### Messages | Ability | Description | Parameters | |---------|-------------|------------| | `better-messages/send-message` | Send a message to a conversation | `thread_id`, `message`, `sender_id` (optional) | | `better-messages/get-messages` | Read messages from a conversation | `thread_id`, `count` (optional) | | `better-messages/search-messages` | Search messages by keyword (returns matching content) | `query` | | `better-messages/edit-message` | Edit an existing message | `thread_id`, `message_id`, `message` | | `better-messages/delete-messages` | Delete messages | `thread_id`, `message_ids` | ### Conversations | Ability | Description | Parameters | |---------|-------------|------------| | `better-messages/list-conversations` | List conversations for a user | `user_id` (optional), `exclude` (optional) | | `better-messages/get-conversation` | Get conversation with messages | `thread_id`, `messages_count` (optional) | | `better-messages/create-conversation` | Start a new conversation | `recipients`, `message`, `subject` (optional) | | `better-messages/get-private-conversation` | Get or create a 1-on-1 conversation | `user_id`, `create` (optional) | | `better-messages/delete-conversation` | Delete a conversation | `thread_id` | | `better-messages/mark-read` | Mark conversations as read | `thread_ids` (optional, empty = mark all) | | `better-messages/change-subject` | Change conversation subject | `thread_id`, `subject` | | `better-messages/get-stats` | Get messaging statistics | — | ### Participants | Ability | Description | Parameters | |---------|-------------|------------| | `better-messages/list-participants` | List conversation participants | `thread_id` | | `better-messages/add-participant` | Add users to a conversation | `thread_id`, `user_ids` | | `better-messages/remove-participant` | Remove a user from a conversation | `thread_id`, `user_id` | | `better-messages/make-moderator` | Grant moderator role | `thread_id`, `user_id` | | `better-messages/unmake-moderator` | Remove moderator role | `thread_id`, `user_id` | ### Users | Ability | Description | Parameters | |---------|-------------|------------| | `better-messages/search-users` | Search users by name | `query`, `limit` (optional) | | `better-messages/get-unread-count` | Get unread message count | `user_id` (optional) | ### Moderation | Ability | Description | Parameters | |---------|-------------|------------| | `better-messages/get-pending-messages` | View moderation queue | `page` (optional), `per_page` (optional) | | `better-messages/approve-message` | Approve a pending message | `message_id` | | `better-messages/reject-message` | Reject and delete a pending message | `message_id` | | `better-messages/blacklist-user` | Add user to blacklist | `user_id` | | `better-messages/unblacklist-user` | Remove user from blacklist | `user_id` | | `better-messages/whitelist-user` | Add user to whitelist | `user_id` | | `better-messages/unwhitelist-user` | Remove user from whitelist | `user_id` | ## Connecting AI Tools ### Option 1: Local WordPress (Claude Desktop, Cursor, VS Code) This method works when your AI tool runs on the same machine as WordPress (local development). **Step 1.** Install and activate the [WordPress MCP Adapter](https://github.com/WordPress/mcp-adapter) plugin. **Step 2.** Add the following to your AI tool's MCP configuration: **Claude Desktop** — Edit `claude_desktop_config.json` (Settings → Developer → Edit Config): ```json { "mcpServers": { "wordpress": { "command": "wp", "args": [ "--path=/path/to/your/wordpress", "mcp-adapter", "serve", "--server=mcp-adapter-default-server", "--user=admin" ] } } } ``` **Cursor** — Go to Settings → Tools and MCP → Add Custom MCP, use the same format. **VS Code** — Create `.vscode/mcp.json` in your project: ```json { "servers": { "wordpress": { "command": "wp", "args": [ "--path=/path/to/your/wordpress", "mcp-adapter", "serve", "--server=mcp-adapter-default-server", "--user=admin" ] } } } ``` Replace `/path/to/your/wordpress` with the actual path to your WordPress installation and `admin` with your WordPress username. ### Option 2: Remote WordPress (hosted sites) This method works with any hosted WordPress site accessible over HTTPS. Requires [Node.js](https://nodejs.org/) installed on your computer. **Step 1.** Install and activate the [WordPress MCP Adapter](https://github.com/WordPress/mcp-adapter) plugin. **Step 2.** Create an Application Password in WordPress: go to **Users → Profile → Application Passwords**, enter a name (e.g. "Claude Desktop"), and click **Add New Application Password**. Copy the generated password. **Step 3.** Add the following to your AI tool's MCP configuration: ```json { "mcpServers": { "wordpress": { "command": "npx", "args": ["-y", "@automattic/mcp-wordpress-remote@latest"], "env": { "WP_API_URL": "https://yoursite.com/wp-json/mcp/mcp-adapter-default-server", "WP_API_USERNAME": "your-username", "WP_API_PASSWORD": "xxxx xxxx xxxx xxxx xxxx xxxx" } } } } ``` Replace `yoursite.com` with your domain, and fill in your username and application password. ### Option 3: REST API (no MCP needed) You can use Better Messages abilities directly through the WordPress REST API without any additional plugins. **List available abilities:** ``` GET https://yoursite.com/wp-json/wp-abilities/v1/abilities?category=better-messages ``` **Execute an ability:** ``` POST https://yoursite.com/wp-json/wp-abilities/v1/abilities/better-messages/send-message/run Content-Type: application/json Authorization: Basic {base64(username:app_password)} { "input": { "thread_id": 123, "message": "Hello from the API!" } } ``` ## Usage Examples Once connected, you can ask your AI assistant things like: - "Show me the messaging statistics" - "List conversations for user 42" - "Send a message to conversation 123 saying hello" - "Search for messages containing 'invoice'" - "Create a new conversation with user 5 saying welcome" - "Show me the moderation queue" - "Approve all safe pending messages" - "Blacklist user 7" - "Make user 10 a moderator in conversation 200" ## Permissions All abilities require WordPress administrator access (`manage_options` capability). The authenticated administrator has full access to all conversations and messages across the site. ## Troubleshooting **Abilities not showing up in MCP?** Make sure the WordPress MCP Adapter plugin is installed and activated. Better Messages abilities are registered with `mcp.public = true` and should appear automatically. **Authentication errors?** For remote connections, make sure your site uses HTTPS (required for Application Passwords) and that the application password is entered correctly with spaces between each group. **"Ability not found" errors?** Make sure Better Messages is activated and you are running WordPress 6.9 or higher. You can verify abilities are registered by visiting: ``` https://yoursite.com/wp-json/wp-abilities/v1/abilities ``` ## Feedback & Missing Features This feature is under active development. If you need an ability that is not listed here or have suggestions for improvement, please contact us at **support@better-messages.com** — we would love to hear your feedback. --- ## Change Avatar Size in Better Messages — CSS Snippet # Change avatar size The Better Messages thread list renders each conversation with a circular **avatar** on the left. Solo conversations show one square image; group conversations stack up to four sub-avatars in a 2×2 grid inside the same circular container. Both layouts share the same `.pic` parent so a single CSS override scales them in step. This snippet bumps the outer avatar circle from the default 40px to 50px and resizes the inner group-sub-avatars to 24px so the four-up grid keeps clean proportions. Adjust the values to match your theme — anything from 32px to 64px works well; beyond 64px you may need to also raise the thread row height so the avatar no longer overflows. Drop the CSS into your theme's stylesheet or the WordPress Customizer's **Additional CSS**. The `!important` flag overrides Better Messages' own scoped styles without forcing you to copy the full selector chain. This is an example of how to increase or change avatar size in the threads list: ```CSS .bp-messages-wrap .bp-messages-side-threads .threads-list .thread .pic { width: 50px !important; height: 50px !important; } .bp-messages-wrap .bp-messages-side-threads .threads-list .thread .pic img { width: 50px !important; height: 50px !important; } .bp-messages-wrap .bp-messages-side-threads .threads-list .thread .pic.group>* { width: 24px !important; height: 24px !important; } .bp-messages-wrap .bp-messages-side-threads .threads-list .thread .pic.group>* .avatar { width: 24px !important; height: 24px !important; } ``` Larger Better Messages chat avatars after applying the CSS snippet --- ## Change Text & Font Size in Better Messages — CSS Snippet # Change text size Better Messages exposes its core typography through CSS custom properties so you can re-tune the messenger without forking any templates. The two most commonly tweaked properties are `--bm-message-font-size` (the body text of each message bubble) and `--bm-message-line-height` (vertical rhythm between lines inside a bubble). The thread list — the left-rail list of conversations — has its own set of selectors because the visual hierarchy there differs from the message bubble. The snippet below targets: - **`.last-message`** — the preview line under each thread title. - **`.bm-info .name + h4`** — the timestamp shown next to the conversation name. - **`.bm-info .name`** and **`.bm-info h4`** — the conversation name and unread badge counter. Drop the snippet into your theme's stylesheet, the WordPress Customizer's **Additional CSS** field, or a custom CSS plugin. The `!important` flags are deliberate — they win against Better Messages' own scoped styles without forcing you to copy the full selector chain. This is an example of how to increase or change text size in Better Messages interface: ```CSS :root{ --bm-message-font-size: 16px; --bm-message-line-height: 20px; } .bp-messages-wrap .threads-list .thread .bm-info .last-message{ font-size: 14px !important; line-height: 16px !important; } .bp-messages-wrap .threads-list .thread .bm-info .name+h4{ font-size: 12px !important; line-height: 14px !important; } .bp-messages-wrap .threads-list .thread .bm-info .name { font-size: 15px; line-height: 15px; } .bp-messages-wrap .threads-list .thread .bm-info h4 { font-size: 15px; line-height: 15px; } ``` Larger Better Messages chat text after applying the CSS snippet --- ## Customize Mobile Chat Button Border Radius — Better Messages CSS # Customize the radius of the mobile chat button On mobile, Better Messages shows a floating round chat button on the bottom of the screen that opens the messenger when tapped. The default style is a perfectly circular button — same width and height, full `50%` border-radius. You may want a softer, rounded-square look (closer to a chip), or a pill shape that matches your theme's other floating elements. The button has the DOM id `#bp-better-messages-mini-mobile-open`. A single border-radius override is all you need — the rest of the button styling stays untouched. Use a value of `0` for a square button, `12px` to `25px` for a rounded square, `50%` to keep the default circle. ```CSS #bp-better-messages-mini-mobile-open { border-radius: 25px !important; } ``` ### Example of rounded mobile chat button Rounded mobile chat button in Better Messages after applying the CSS snippet --- ## Replace the Verified User Icon — Better Messages CSS Snippet # Replacing verified icon Better Messages renders a small **check badge** next to the names of verified users (see [Verified User Badges](/docs/features/verified-badges/)). The badge is rendered as an inline SVG inside a `` element so it can be themed entirely from CSS — no PHP filter required. This snippet replaces the default checkmark icon with a **shield** icon. The technique works for any custom SVG: hide the default `` child via `display: none`, then draw your own icon with a CSS `::before` pseudo-element that uses a data-URL `content`. The same selectors apply across light and dark mode. ```CSS span.bm-name-verified{ height: 12px; } span.bm-name-verified svg{ display: none; } span.bm-name-verified::before{ content: url("data:image/svg+xml,%3Csvg stroke='currentColor' fill='currentColor' stroke-width='0' viewBox='0 0 24 24' height='12px' width='12px' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='none' d='M0 0h24v24H0z'%3E%3C/path%3E%3Cpath d='M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm-2 16l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z'%3E%3C/path%3E%3C/svg%3E"); } ``` ### Example of replaced verified icon --- ## Add a Custom AI Provider — Better Messages Developer Guide # Add a custom AI provider :::info REQUIREMENTS To be able to implement this guide, you need to learn how to insert PHP snippets to your website. You can find guide here: [WP Beginner](https://www.wpbeginner.com/beginners-guide/beginners-guide-to-pasting-snippets-from-the-web-into-wordpress/) ::: Better Messages ships with three built-in AI providers — **OpenAI**, **Anthropic** and **Google Gemini** — but you can register additional providers yourself using three PHP filter hooks. This guide walks through adding a provider that talks to any **OpenAI-compatible** Chat Completions endpoint. That single provider works with self-hosted servers like **Ollama**, **LM Studio**, **llama.cpp** (`--api`), **vLLM**, **LocalAI** and **AnythingLLM**, as well as hosted services like **Groq**, **Together AI**, **OpenRouter**, **DeepInfra** and **Perplexity**. The same mechanism also lets you build your own **wrappers around OpenAI, Claude or Gemini** — useful for Azure OpenAI, Amazon Bedrock, Google Vertex AI, LiteLLM proxies, or any time you need custom auth, logging, or routing in front of an API that Better Messages already supports. See [Wrapping the built-in providers](#wrapping-the-built-in-providers) below. :::note Requirements - Better Messages with the AI Chat Bots feature enabled - PHP 8.1 or newer (required by the AI addon) - Your LLM server must expose an OpenAI-compatible `/v1/chat/completions` endpoint with streaming support ::: ## Starter plugin A ready-to-install version of the snippet from this guide is available as a WordPress plugin: **Download bm-custom-ai-provider.zip** Unzip into `wp-content/plugins/`, edit the four constants at the top of `bm-custom-ai-provider.php` (or override them from `wp-config.php`), activate the plugin, and the new provider will appear in the **AI Chat Bots** editor. ## How it works Three filter hooks give you everything you need to plug a new provider into the AI Chat Bots admin UI: | Filter | Purpose | |---|---| | `better_messages_ai_providers_info` | Adds your provider to the **Provider** dropdown in the bot editor | | `better_messages_ai_provider_create` | Returns your provider class instance when Better Messages needs to generate a response | | `better_messages_ai_provider_global_key` | Returns the global API key for your provider (useful for hosted services) | Your provider class extends `Better_Messages_AI_Provider` and must implement a few abstract methods. The important one is `getResponseGenerator()`, which returns a PHP `Generator` that yields: - `string` — a text delta, streamed to the user as the bot types - `['finish', $meta]` — when the response is complete - `['error', $message]` — if something went wrong ## Complete example Paste the snippet below into a mu-plugin, a custom plugin, or `functions.php` in your theme. Edit the four constants at the top to point at your LLM server. ```php BM_CUSTOM_AI_ID, 'name' => BM_CUSTOM_AI_NAME, 'features' => array( 'temperature', 'maxOutputTokens' ), 'hasGlobalKey' => true, ); return $providers; } ); add_filter( 'better_messages_ai_provider_global_key', function ( $key, $provider_id ) { if ( $provider_id === BM_CUSTOM_AI_ID ) { return BM_CUSTOM_AI_KEY; } return $key; }, 10, 2 ); add_filter( 'better_messages_ai_provider_create', function ( $provider, $provider_id ) { if ( $provider_id !== BM_CUSTOM_AI_ID ) { return $provider; } if ( ! class_exists( 'Better_Messages_AI_Provider' ) ) { return null; // AI addon is not loaded } if ( ! class_exists( 'BM_Custom_AI_Provider' ) ) { class BM_Custom_AI_Provider extends Better_Messages_AI_Provider { public function get_provider_id() { return BM_CUSTOM_AI_ID; } public function get_provider_name() { return BM_CUSTOM_AI_NAME; } public function get_supported_features() { return array( 'temperature', 'maxOutputTokens' ); } public function check_api_key() { // Called when plugin settings are saved. No-op for self-hosted servers. } public function get_models() { try { $response = $this->get_client()->request( 'GET', 'models' ); $data = json_decode( $response->getBody()->getContents(), true ); $models = array(); if ( isset( $data['data'] ) && is_array( $data['data'] ) ) { foreach ( $data['data'] as $row ) { if ( isset( $row['id'] ) ) { $models[] = $row['id']; } } } sort( $models ); return $models; } catch ( \Throwable $e ) { return new \WP_Error( 'custom_ai_models', $e->getMessage() ); } } public function getResponseGenerator( $bot_id, $bot_user, $message, $ai_message_id, $stream = true ) { global $wpdb; $settings = Better_Messages()->ai->get_bot_settings( $bot_id ); $bot_user_id = absint( $bot_user->id ) * -1; // Load conversation history up to the triggering message. $rows = $wpdb->get_results( $wpdb->prepare( "SELECT id, sender_id, message FROM `" . bm_get_table( 'messages' ) . "` WHERE thread_id = %d AND created_at <= %d ORDER BY created_at ASC", $message->thread_id, $message->created_at ) ); // Build OpenAI-style messages array. $request_messages = array(); if ( ! empty( $settings['instruction'] ) ) { $request_messages[] = array( 'role' => 'system', 'content' => $settings['instruction'], ); } foreach ( $rows as $row ) { // Skip messages that are themselves failed AI responses. if ( Better_Messages()->functions->get_message_meta( $row->id, 'ai_response_error' ) ) { continue; } // Strip HTML comments (e.g. the marker) and tags. $text = preg_replace( '//', '', $row->message ); $text = wp_strip_all_tags( html_entity_decode( $text ) ); $request_messages[] = array( 'role' => (int) $row->sender_id === $bot_user_id ? 'assistant' : 'user', 'content' => $text, ); } $params = array( 'model' => $settings['model'], 'messages' => $request_messages, 'stream' => true, ); if ( $settings['temperature'] !== '' ) { $params['temperature'] = (float) $settings['temperature']; } if ( $settings['maxOutputTokens'] !== '' ) { $params['max_tokens'] = (int) $settings['maxOutputTokens']; } try { $response = $this->get_client()->post( 'chat/completions', array( 'json' => $params, 'stream' => true, ) ); $body = $response->getBody(); $buffer = ''; $model = ''; while ( ! $body->eof() ) { $chunk = $body->read( 1024 ); if ( $chunk === '' ) { continue; } $buffer .= $chunk; while ( ( $pos = strpos( $buffer, "\n" ) ) !== false ) { $line = trim( substr( $buffer, 0, $pos ) ); $buffer = substr( $buffer, $pos + 1 ); if ( $line === '' || strpos( $line, 'data: ' ) !== 0 ) { continue; } $json = substr( $line, 6 ); if ( $json === '[DONE]' ) { yield array( 'finish', array( 'provider' => $this->get_provider_id(), 'model' => $model, ) ); return; } $data = json_decode( $json, true ); if ( isset( $data['model'] ) ) { $model = $data['model']; } if ( isset( $data['choices'][0]['delta']['content'] ) ) { yield $data['choices'][0]['delta']['content']; } } } // Some servers don't emit a final [DONE]; finish cleanly anyway. yield array( 'finish', array( 'provider' => $this->get_provider_id(), 'model' => $model, ) ); } catch ( \Throwable $e ) { yield array( 'error', $e->getMessage() ); } } protected function get_client() { return new \BetterMessages\GuzzleHttp\Client( array( 'base_uri' => BM_CUSTOM_AI_BASE_URL, 'headers' => array( 'Authorization' => 'Bearer ' . $this->get_api_key(), 'Content-Type' => 'application/json', ), 'timeout' => 120, 'connect_timeout' => 10, ) ); } } } return new BM_Custom_AI_Provider(); }, 10, 2 ); ``` ## Using your custom provider 1. Save the snippet (edit the four constants at the top to match your setup). 2. Go to **WP Admin** → **Better Messages** → **AI Chat Bots**. 3. Create or edit a bot. 4. In the **AI Provider** section, pick your new provider from the **Provider** dropdown. 5. Pick a model from the **Model & Pricing** selector — the list is fetched live from your server via `GET /v1/models`. 6. Save the bot, add it to a conversation, and start chatting. ## Per-server notes - **Ollama** — Base URL `http://127.0.0.1:11434/v1/`. The API key is ignored; any string works. Install a model first with `ollama pull llama3.2`. - **LM Studio** — Start the local server from the **Developer** tab. Base URL defaults to `http://127.0.0.1:1234/v1/`. - **vLLM / llama.cpp** — Start the server with its OpenAI-compatible API and use base URL `http://127.0.0.1:8000/v1/` (or whichever port you configured). - **Hosted services** (Groq, Together AI, OpenRouter, DeepInfra, Perplexity) — Use the service's base URL and a real API key. :::info If your WordPress site and LLM server run on different machines, make sure the LLM server's port is reachable from WordPress. For self-hosted servers that listen on `127.0.0.1`, bind them to `0.0.0.0` or put them behind a reverse proxy with TLS. ::: ## Adding more features The example above supports **temperature** and **max output tokens**. If your backend supports more, add the matching feature IDs to both `get_supported_features()` and the `features` array in the `better_messages_ai_providers_info` filter — Better Messages will automatically show the corresponding fields in the bot editor. Available feature IDs: | Feature ID | What it enables in the bot editor | |---|---| | `temperature` | Temperature slider | | `maxOutputTokens` | Max output tokens field | | `images` | Image input toggle (vision models) | | `files` | File input toggle (PDFs) | | `webSearch` | Web search tool | | `fileSearch` | File search / vector store tool | | `imagesGeneration` | Image generation tool | | `reasoningEffort` | Reasoning effort selector | | `extendedThinking` | Extended thinking / thinking budget | | `serviceTier` | Service tier selector | | `audio` | Audio input/output | | `moderation` | Pre-send moderation | | `transcription` | Voice message transcription | To support image inputs, add `'images'` to the feature list and extend the message-building loop to include base64-encoded image attachments. The built-in OpenAI provider at `addons/ai/api/open-ai.php` is a good reference. ## Wrapping the built-in providers The same filter hooks let you register **wrappers around OpenAI, Anthropic (Claude) or Google Gemini**. This is useful when you need to reach one of those APIs through a non-default route: - **Azure OpenAI Service** — OpenAI's API surface, but on Azure with a different base URL, a different auth header (`api-key` instead of `Authorization`), and a model identifier that's actually your deployment name. - **Amazon Bedrock / Google Vertex AI** — Claude and Gemini models delivered through AWS or GCP credentials instead of the vendor's direct API. - **LiteLLM, OpenRouter, or a self-hosted proxy** — a single endpoint in front of several model providers, often with cost/quota controls bolted on. - **A transparent logging / audit layer** — send every prompt and response through your own service before forwarding to the real API. - **Multiple keys or tenants** — one "OpenAI (marketing)" provider and one "OpenAI (support)" provider, each with its own key, rate limit, and model allowlist. ### Two ways to build a wrapper **1. Reuse the built-in provider class.** OpenAI, Anthropic and Gemini all live in classes you can extend or compose. For example, to create an Azure OpenAI provider that keeps all of the streaming, moderation, transcription and cost-tracking logic of the built-in OpenAI provider, subclass it and only override the HTTP client: ```php add_filter( 'better_messages_ai_provider_create', function ( $provider, $provider_id ) { if ( $provider_id !== 'azure_openai' ) { return $provider; } if ( ! class_exists( 'Better_Messages_OpenAI_API' ) ) { return null; } if ( ! class_exists( 'BM_Azure_OpenAI_Provider' ) ) { class BM_Azure_OpenAI_Provider extends Better_Messages_OpenAI_API { public function get_provider_id() { return 'azure_openai'; } public function get_provider_name() { return 'Azure OpenAI'; } public function get_client() { return new \BetterMessages\GuzzleHttp\Client( array( 'base_uri' => 'https://YOUR-RESOURCE.openai.azure.com/openai/deployments/YOUR-DEPLOYMENT/', 'headers' => array( 'api-key' => $this->get_api_key(), 'Content-Type' => 'application/json', ), 'query' => array( 'api-version' => '2024-10-21' ), ) ); } } } return new BM_Azure_OpenAI_Provider(); }, 10, 2 ); ``` Register it with `better_messages_ai_providers_info` and `better_messages_ai_provider_global_key` the same way as the OpenAI-compatible example above. **2. Write a brand-new provider class** that speaks a different API shape internally but advertises itself with whatever id and name you like. Use this when you want to wrap **Claude via Amazon Bedrock** or **Gemini via Vertex AI**, where the request/response format is different enough from the vendor's direct API that subclassing isn't practical. Start from the OpenAI-compatible snippet above and replace the HTTP call and streaming parser with the Bedrock / Vertex equivalents. :::info Inside a wrapper you can still call the parent class's helper methods — `get_thread_messages()`, `resolve_sender_names()`, `get_group_context_instruction()`, `strip_mention_html()`, `convert_mention_placeholders()`, `enrich_with_reply_context()` — so you don't have to reimplement context building, group handling, or mentions. ::: --- ## Add Custom File Format to Better Messages Uploader — PHP Snippet # How to add a custom file format for uploader? :::info REQUIREMENTS To be able to implement this guide, you need to learn how to insert PHP snippets to your website. You can find guide here: [WP Beginner](https://www.wpbeginner.com/beginners-guide/beginners-guide-to-pasting-snippets-from-the-web-into-wordpress/) ::: Better Messages file uploader rely on WordPress file uploader and media gallery to ensure good compatibility with WordPress plugins ecosystem. To add a custom file format, you need to register it with special php filters. For example, if you want to add .emb format, the code will look like that: ```php $filetype['ext'], 'type' => $filetype['type'], 'proper_filename' => $data['proper_filename'] ]; } else { return $data; } } ``` This code is just an example. For other extensions, you will need to modify this code, based on your requirements. After this you will be able to enable this file format in Better Messages Attachments settings and be able to upload this type of files. --- ## Custom Messages Location in Better Messages — PHP Snippet # Custom messages location :::info REQUIREMENTS To be able to implement this guide, you need to learn how to insert PHP snippets to your website. You can find guide here: [WP Beginner](https://www.wpbeginner.com/beginners-guide/beginners-guide-to-pasting-snippets-from-the-web-into-wordpress/) ::: By settings custom messages location its possible to integrate plugin with any other plugin or theme as messages system. To display layout of plugin at any custom place of website you can use this function: ```php functions->get_page(); ``` After that done need to point to custom place location url with next filter, so the notifications of plugin are directing to the right place: ```php ## Without PWA plugin To make that working without additional PWA plugins, you need to make basic PWA version of your website. To make that easily website must have manifest.json file located in root of website. This is example of basic `manifest.json` file: ```json { "short_name": "wordplus.org", "name": "WordPlus.org", "icons": [], "start_url": "./", "display": "standalone", "orientation": "portrait" } ``` More advanced `manifest.json` file guide can be found [here](https://web.dev/add-manifest/) Besides that you need to add manifest.json link to your website head part, you can do it with php snippet for example: ```php add_action( 'wp_head', function (){ echo ''; } ``` After that website must be added to ios home-screen as web application and web push feature will start to work there. ## With PWA plugin If you want to make it work with ready to use [PWA Plugins](https://wordpress.org/plugins/tags/pwa/), you need to find the plugin which will be compatible with [OneSignal push notifications](/docs/integrations/onesignal/) integration as with most of PWA solutions the built-in WebPush notifications system of Better Messages will not work due to browser limitations to the number of service workers. --- ## Replace Default Email Notifications with Custom HTML # How to replace email notifications with custom layout? :::info Built-in Customization Options Before using this filter, consider the built-in [Email Template Customization](/docs/features/email-notifications#email-template-customization) options. You can customize colors, logo, text, and even use a custom HTML template directly from the plugin settings without writing code. ::: Use this filter only when you need programmatic control over email content, such as dynamic templates based on user roles or conditional content. :::info REQUIREMENTS To be able to implement this guide, you need to learn how to insert PHP snippets to your website. You can find guide here: [WP Beginner](https://www.wpbeginner.com/beginners-guide/beginners-guide-to-pasting-snippets-from-the-web-into-wordpress/) ::: ```php subject; $email_subject = '[' . get_bloginfo('name') . '] You have unread messages:' . $subject; $thread_url = esc_url( Better_Messages()->functions->add_hash_arg('conversation/' . $thread_id, [], Better_Messages()->functions->get_link($user_id) ) ); /** * Composing html messages list */ $messageHtml = ''; $last_id = 0; foreach ($messages as $message) { $sender = get_userdata($message->sender_id); $timestamp = strtotime($message->date_sent) + $gmt_offset; $time_format = get_option('time_format'); if (gmdate('Ymd') != gmdate('Ymd', $timestamp)) { $time_format .= ' ' . get_option('date_format'); } $time = wp_strip_all_tags(stripslashes(date_i18n($time_format, $timestamp))); $author = wp_strip_all_tags(stripslashes(sprintf(__('%s wrote:', 'bp-better-messages'), $sender->display_name))); $message = wp_strip_all_tags(stripslashes($message->message)); if ($last_id == 0 || $last_id != $sender->ID) { $messageHtml .= '' . $author . ''; } $messageHtml .= ''; $messageHtml .= '' . $message . ''; $messageHtml .= '' . $time . ''; $messageHtml .= ''; $last_id = $sender->ID; } $messageHtml .= ''; /** * Composing Email HTML */ ob_start(); ?> Simple Transactional Email   Hi display_name; ?>, You have unread messages: "" ">Go to the discussion to reply or catch up on the conversation. ">   user_email, $email_subject, $content ); remove_filter( 'wp_mail_content_type', $content_type ); // If true is returned the plugin will not send email itself, if false is returned it will send. return true; } ``` --- ## Per-Thread Participant Personas (Fake Users) — Better Messages Guide # Per-thread "fake users" (participant personas) :::info REQUIREMENTS To be able to implement this guide, you need to learn how to insert PHP snippets to your website. You can find guide here: [WP Beginner](https://www.wpbeginner.com/beginners-guide/beginners-guide-to-pasting-snippets-from-the-web-into-wordpress/) ::: Sometimes the WordPress user who actually receives a chat is **not** the identity the other side should see. Examples: - A buyer messages an "Agent CPT" that isn't linked to a real WP user — the chat is routed to a generic fallback account, but the buyer should still see the agent's name and profile photo. - A WooCommerce vendor's store-front persona should be shown to customers instead of the WP user behind the store. - A single fallback account routes inquiries for several different agent CPTs at once — each thread needs to show its own persona, all in the same conversation list. Better Messages exposes a **per-thread participant override** map for exactly this case. Same WP user, different identity in different threads — at the same time. ## What it looks like The buyer's view of two unrelated threads that are both **routed to the same underlying WordPress account**. Each thread shows its own persona — name, profile photo and clickable profile URL — both in the sidebar and in the message sender chips. The Houzez integration is used here as an example, but the pattern is reusable from any addon. Buyer-side view: two different agent personas (Mike Moore and Dave Harris) on threads that both route to the same fallback WP user, plus persona attribution on every reply The agent side (the WordPress user the chats are actually routed to) sees the buyer's real identity in the conversation header, sees their **own** WordPress profile in their bottom-left widget (no leak into self-view), and gets a yellow **"Chatting as Mike Moore"** banner so they know which persona they are representing for this conversation: Agent-side view: 'Chatting as Mike Moore' banner above the property card; bottom-left widget keeps the receiver's own WP identity ## How it works Add an optional `participantOverrides` map to the thread payload via the `better_messages_rest_thread_item` filter: ```php $thread_item['participantOverrides'] = array( (string) $user_id => array( 'name' => 'Display Name', // optional 'avatar' => 'https://…/photo.png', // optional 'url' => 'https://…/profile/', // optional ), ); ``` Keys are stringified user IDs (positive WP IDs and negative guest IDs both work). All fields are optional — omit any field and the participant's real record fills the gap. The map travels with the thread payload across every transport — REST, AJAX polling and WebSocket relays all build their payloads through the same filter, so the override flows everywhere automatically. On the frontend, every surface that renders a participant *inside* a thread (conversation header, sidebar item, message sender chip, reactions modal, mini-chat-head widget, call screen, info panel, toasts, etc.) merges the override on top of the real user record at render time. Surfaces that step outside the thread context — the current-user widget, mention picker, user search, "Add participant" modal, user profile popup — deliberately keep using the real record, so the override never leaks into self-view or non-thread contexts. ## Recipe ```php $persona['name'], 'avatar' => $persona['avatar'], 'url' => $persona['url'], ); return $thread_item; } ``` ## Three principles ### 1. Snapshot the persona on first resolve Resolve once from your data sources, then cache the result in thread meta so subsequent renders are stable even if the upstream data drifts later: ```php $cached = Better_Messages()->functions->get_thread_meta( $thread_id, 'my_persona_user_id' ); if ( $cached ) { // use cached values } else { // resolve fresh Better_Messages()->functions->update_thread_meta( $thread_id, 'my_persona_user_id', $resolved_user_id ); // …same for any other persona fields you need (CPT post id, type, etc.) } ``` This protects your buyers and agents from a confusing experience if a CPT title gets edited, a vendor changes their store name, or the linked WP account changes after the conversation already started. ### 2. Only override participants who are in the thread The `participants` array on the thread item is your source of truth. Don't add `participantOverrides` entries for user IDs that aren't part of the thread — they would never be rendered anyway, but you'd be putting noise into every payload (and in WebSocket pushes that fan out to many recipients). ### 3. Don't double-override If you also want the persona to apply to that user in **non-thread** contexts (user search, mention picker, "@" autocomplete) — meaning the user always appears as the persona, everywhere — additionally hook [`better_messages_rest_user_item`](/hooks/php-filters#better_messages_rest_user_item) and rewrite `name` / `avatar` / `url` there. The per-thread override and the global one compose cleanly. Do not implement ad-hoc "global override based on last thread we saw" tricks. That's exactly the kind of fragile global-state pattern the per-thread mechanism replaces, and it breaks the moment the same user appears in two threads with different personas. ## Optional: a "Chatting as X" banner If a thread is routed to a generic fallback account, you'll want to tell the receiver that the other side sees a different identity. Append HTML to `$thread_item['threadInfo']` only when the viewer is on the persona side **and** is not the persona's primary linked user: ```php if ( $viewer_is_on_persona_side && $viewer_id !== $persona_primary_user_id ) { $banner = '' . ' ' . sprintf( esc_html__( 'Chatting as %s', 'my-addon' ), '' . esc_html( $persona['name'] ) . '' ) . ''; $thread_item['threadInfo'] = ( $thread_item['threadInfo'] ?? '' ) . $banner; } ``` `threadInfo` is rendered above the conversation pane and is per-viewer — the filter receives the viewer's `$user_id`, so a banner you set there is correctly scoped to the receiver who needs it. ## Reference implementations Two integrations inside the plugin use this exact pattern and are the reference implementations: - **`addons/houzez.php`** — Houzez agent CPTs, including the case where the agent CPT has no linked WordPress user and the chat is silently routed to the property's post author. - **`addons/realhomes.php`** — RealHomes agent **and** agency CPTs, same routing behavior, plus the agency case (an agency CPT routed to its post author, with the agency name and logo shown to the buyer). Both share the same method names so the pattern is easy to copy: - `thread_item()` — the filter callback - `resolve_thread_persona()` — snapshots persona post id and type to thread meta - `resolve_thread_routed_user()` — snapshots the actual routed user id - `apply_realtor_to_user_item()` (and `resolve_realtor_avatar_url()` in Houzez) — build the override values - `persona_banner_html()` — the "Chatting as X" banner ## Testing checklist When adding a persona to a new integration: 1. Open a thread that should have the persona — header, sidebar item and message sender chip all show the persona name, avatar, and clickable profile URL. 2. The routed receiver opens their own dashboard — their bottom-left profile widget shows their **real** WordPress identity (the override does not leak into self-view). 3. Open a second thread routed to the same WP user but with a different persona — both threads in the sidebar must show their own persona side-by-side. No "last-write-wins" effects. 4. Send a message from each side over WebSocket — the inbound payload carries `thread.participantOverrides` and the receiving UI updates without a refresh. 5. Trash the persona's source post (CPT, vendor, etc.) — the override is dropped silently and the thread falls back to the routed user's real identity. 6. Reload the page — the override survives because it's snapshotted in thread meta and re-emitted on every fetch. ## Related - [`better_messages_rest_thread_item`](/hooks/php-filters#better_messages_rest_thread_item) — the filter where you write the override. - [`better_messages_rest_user_item`](/hooks/php-filters#better_messages_rest_user_item) — the global per-user filter; use it in addition to `participantOverrides` when you want a persona to apply everywhere, not just inside one thread. --- ## Customize Notification & Call Sounds — Better Messages Developer Guide # How to customize sounds in the plugin? ## Built-in Sound Customization Better Messages provides built-in options to customize sounds directly from the plugin settings without any code. Navigate to **Better Messages → Settings → Notifications** tab and scroll to the **Sounds Customization** section. ### Available Options #### Message Notification Sound - **Volume** - Set from 0 to 100 (set to 0 to disable the sound completely) - **Custom Sound** - Click "Select custom sound" to choose an MP3 file from your WordPress Media Library - **Reset** - Click "Reset default sound" to restore the original notification sound #### Message Sent Sound - **Volume** - Set from 0 to 100 (set to 0 to disable the sound completely) - **Custom Sound** - Click "Select custom sound" to choose an MP3 file from your WordPress Media Library - **Reset** - Click "Reset default sound" to restore the original sent sound #### Incoming Call Sound (WebSocket version) - **Volume** - Set from 0 to 100 (set to 0 to disable the sound completely) - **Custom Sound** - Click "Select custom sound" to choose an MP3 file from your WordPress Media Library - **Reset** - Click "Reset default sound" to restore the original incoming call sound #### Outgoing Call Sound (WebSocket version) - **Volume** - Set from 0 to 100 (set to 0 to disable the sound completely) - **Custom Sound** - Click "Select custom sound" to choose an MP3 file from your WordPress Media Library - **Reset** - Click "Reset default sound" to restore the original outgoing call sound :::info You can preview any sound by clicking the "Play" button before saving your changes. ::: ## Advanced: Replace Sounds Folder via Code :::info REQUIREMENTS To be able to implement this guide, you need to learn how to insert PHP snippets to your website. You can find guide here: [WP Beginner](https://www.wpbeginner.com/beginners-guide/beginners-guide-to-pasting-snippets-from-the-web-into-wordpress/) ::: If you need to replace multiple sound files programmatically, you can use the `bp_better_messages_sounds_assets` filter. Plugin keeps default sound files in this folder: **/plugins/bp-better-messages/assets/sounds** You can copy this folder to another location that won't be overwritten on plugin updates, then use this filter to point to your custom sounds folder: ```php functions->new_message()`](/hooks/php-functions/#new_message). Multiple `add_action()` lines bind the same callback to the different registration events used by BuddyPress, Ultimate Member, Paid Memberships Pro, and the standard WordPress user-registration flow — so the same snippet works on every site regardless of which membership / community plugin is active. Remove the `add_action` lines you don't need. Customize the `subject`, `content`, and `sender_id` (the WordPress user ID who will appear as the message author) to match your site. The `content` field accepts HTML and respects the same sanitization rules as the rest of the messenger. :::info REQUIREMENTS To be able to implement this guide, you need to learn how to insert PHP snippets to your website. You can find guide here: [WP Beginner](https://www.wpbeginner.com/beginners-guide/beginners-guide-to-pasting-snippets-from-the-web-into-wordpress/) ::: This snippet will automatically send a welcome message to user which just registered at your website. ```php 1, //Sender User ID 'thread_id' => false, 'recipients' => $user_id, 'subject' => 'Welcome to WordPlus.org', 'content' => "Welcome to WordPlus.org\n\n If you have any question about Better Messages you can ask it here directly.", 'date_sent' => bp_core_current_time() ); $result = Better_Messages()->functions->new_message( $args ); } // For BuddyPress add_action('bp_core_activated_user', 'bm_welcome_message', 10, 3); // For BuddyPress (if first one does not works) add_action('bp_core_signups_after_add_backcompat', 'bm_welcome_message', 10, 1); // For Not BuddyPress add_action('register_new_user', 'bm_welcome_message', 10, 1); // For Ultimate Member add_action('um_registration_complete', 'bm_welcome_message', 10, 2); // For Other Cases if above does not work, for example register at Paid Membership Pro Checkout add_action('user_register', 'bm_welcome_message', 10, 2); ``` --- ## How to Create Group Threads in Better Messages — Video Guide # How to create group threads? A **group thread** in Better Messages is a single conversation that includes three or more participants — the sender and at least two recipients. Group threads support the same features as one-on-one chats: replies, reactions, file uploads, voice messages, message editing, and (on the WebSocket version) typing indicators, read receipts, and group voice / video calls. Each member can leave a group thread without breaking it for the rest, and the group owner can add new participants at any time. To start a group thread, open the messenger, click **New Conversation**, and select **two or more recipients** from the user picker. Better Messages turns the conversation into a group automatically as soon as you pick the second recipient. You can also create groups programmatically with the [`Better_Messages()->functions->new_message()`](/hooks/php-functions/#new_message) helper, or by handing a comma-separated list of user IDs to shortcodes like `[better_messages_live_chat_button user_id="42,57,93"]`. The video below shows the full flow from inside the messenger UI. :::info Old guide This guide was created for **Better Messages 1.0**, styling and process can be different slightly in **Better Messages 2.0** ::: ## See also - [Group conversations](/docs/features/group-conversations/) — feature reference - [Conversation types](/docs/getting-started/conversation-types/) — overview of every conversation type - [Group video chat](/docs/websocket/group-video-chat/) — group video calls inside a group thread - [Group audio chat](/docs/websocket/group-audio-chat/) — group audio calls inside a group thread --- ## How to Set Up the Messages Location — Better Messages Video Guide # How to set up messages location? The **messages location** is the WordPress URL where the Better Messages inbox renders for logged-in users. The plugin does not pick the page for you — you decide whether the inbox lives on a standalone WordPress page, a tab inside an existing community plugin profile (BuddyPress, BuddyBoss, Ultimate Member, PeepSo, UsersWP, Profile Builder, JetEngine Profile Builder, FluentCommunity), or on the theme's account / "My Account" page (WooCommerce, MemberPress, LearnDash, LifterLMS, and similar themes). The video below walks through opening **WP Admin → Better Messages → Settings → Location**, picking the location mode that matches your site, and verifying the front-end. Most setups take less than two minutes. If you already have a community plugin active, Better Messages auto-detects it and the right option will be pre-selected — you just confirm and save. :::info Old guide This guide was created for **Better Messages 1.0**, styling and process can be different slightly in **Better Messages 2.0** ::: ## See also - [Messages location](/docs/getting-started/user-inbox/) — text reference for the same setup - [Conversation types](/docs/getting-started/conversation-types/) — what lives at that messages location once it's set - [User inbox](/docs/getting-started/user-inbox/) — full explainer with screenshots of each location mode --- ## AI Chat Bots for WordPress Chat — OpenAI, Claude, Gemini # AI Chat Bots Better Messages allows you to create AI-powered chat bots using multiple AI providers: OpenAI, Anthropic (Claude), and Google Gemini. ## How it works AI bots appear as regular users in the messaging interface. When a user sends a message to a bot, the message is processed through the selected AI provider and a response is generated. Each bot can be configured with its own provider, model, system instructions, and specific capabilities. In group conversations, bots respond when mentioned with @botname. ## Key capabilities - Multiple AI providers — choose between OpenAI, Anthropic (Claude), and Google Gemini per bot - Create multiple AI bots with different personalities and purposes - Custom system prompts to define bot behavior and knowledge - Welcome message — auto-sent by the bot when a user starts a new 1:1 conversation, with a live preview of the first-message experience - Dynamic placeholders and conditionals in system prompts and welcome messages — reference the user, site, current date/time, and bot identity - Per-bot settings — each bot can have its own provider, model selection, and API key override - Web search — bots can search the web for current information - File search — bots can search through uploaded knowledge base files (OpenAI) - Image generation — bots can generate images (OpenAI, Gemini) - Real-time response streaming in conversations - Group conversation support — add bots to group conversations, bots respond when mentioned with @botname - Conversation summarization — AI-generated summaries of conversation history, configurable per thread - Scheduled digests — AI-generated conversation digests on a schedule (hourly, twice daily, daily), configurable per thread - Token usage tracking — per-bot token usage tracking with cost estimation - Points charging — charge users MyCred or GamiPress points for AI responses - Online presence — bots appear as online users (WebSocket version) - Typing indicators — bots show a typing indicator while generating responses (WebSocket version) - E2E encryption exclusion — bots are automatically excluded from end-to-end encrypted conversations - Dedicated admin page for bot management ## How to enable **Step 1:** Configure your AI provider API keys at **WP Admin** → **Better Messages** → **Settings** → **Integrations**. - **OpenAI** — Enter your API key from [platform.openai.com](https://platform.openai.com) - **Anthropic** — Enter your API key from [console.anthropic.com](https://console.anthropic.com) - **Google Gemini** — Enter your API key from [aistudio.google.com](https://aistudio.google.com) You only need to configure the providers you plan to use. **Step 2:** Create and configure bots at **WP Admin** → **Better Messages** → **AI Bots**. - Click **Add New** to create a bot - Set the bot's display name and avatar - Select the AI provider and model - Write a system prompt defining the bot's personality and instructions - Enable desired capabilities (web search, file search, image generation — availability depends on provider) - Optionally override the global API key with a per-bot key - Configure points charging, summarization, and digest settings as needed - Publish the bot :::info Write detailed system prompts for your bots. The more specific the instructions, the better the bot will perform for your specific use case. ::: ## Welcome message Each bot can have a **Welcome message** — the first thing the bot says when a user starts a new 1:1 conversation with it. Bot welcome message shown virtually on the New Conversation screen The welcome message appears in two places: 1. **Virtually** on the *New Conversation* screen the moment the user picks the bot as the recipient — before the thread even exists, so visitors can see how the bot greets them before typing anything. 2. **Persisted** as the first real message of the thread once the user sends their first message, so it shows in the conversation history on reload. Delivery is silent: the welcome message does not increment the unread badge and does not send push notifications. The welcome message is sent only for **1:1 conversations**. Adding the bot to an existing group chat or a chat room does not trigger it. By default the welcome message is also passed to the AI provider as part of the conversation history, so the bot stays aware of what it said. You can turn this off per-bot with the **Include Welcome in Context** toggle to save input tokens. ### Formatting The welcome message supports both **Markdown** and raw **HTML** — use whichever is more convenient: ```text Hi **{first_name}**! Check out our [knowledge base](https://example.com/docs) or jump to support. ``` Unlike AI-generated replies (which are HTML-entity-encoded before rendering so that any `<` in model output shows as literal text), the welcome message template is authored by an admin and is therefore rendered as-is through the same Markdown + HTML pipeline used by other bot messages. This means you can embed links, bold text, line breaks, and simple tags like ``, ``, ``, and `` directly. ## Placeholders Bot Behavior panel with Instruction, Welcome Message and placeholder chips Both the **Instruction** (system prompt) and the **Welcome message** support curly-brace placeholders that are expanded at runtime. Unknown tokens are left unchanged. **User:** `{name}`, `{display_name}`, `{first_name}`, `{last_name}`, `{email}`, `{user_id}`, `{user_role}` **Site:** `{site_name}`, `{site_url}`, `{site_description}` **Date & time** (uses WordPress site timezone): `{current_date}`, `{current_time}`, `{current_datetime}`, `{current_year}`, `{day_of_week}`, `{time_of_day}` (morning / afternoon / evening / night) **Bot:** `{bot_name}`, `{bot_id}` The admin UI shows every available token as a clickable chip. Clicking a chip inserts the token into whichever field (Instruction or Welcome message) you last focused, so you don't have to type them manually. ### Conditionals You can also wrap content in conditional blocks that only render when the condition matches. Content inside non-matching blocks is stripped. - `{if_guest}...{/if_guest}` — shown only to guest visitors - `{if_user}...{/if_user}` — shown only to logged-in WordPress users - `{if_role:}...{/if_role:}` — shown only when the user has the given WP role (e.g. `administrator`, `editor`, `subscriber`). Opening and closing tags must reference the same role. - `{if_morning}` / `{if_afternoon}` / `{if_evening}` / `{if_night}` — shown only during that time-of-day band Conditionals can be combined with plain placeholders. Example welcome message: ```text {if_user}Welcome back, {first_name}!{/if_user}{if_guest}Hi! Create an account for a smoother experience.{/if_guest} It's {time_of_day} at {site_name} — how can I help? ``` ### Preview button Every textarea that supports placeholders has a **Preview** button next to it. Clicking it resolves the template against your current admin account and shows the rendered result, so you can verify tokens and conditionals produce the output you expect before saving. --- ## AI Content Moderation for WordPress Chat # AI Content Moderation Better Messages offers AI-powered content moderation to automatically detect and handle harmful content. Choose between two moderation providers depending on your needs. ## Moderation Providers ### Better Messages Moderation AI Included with the WebSocket license at no additional cost. No third-party API keys required. - Powered by Better Messages Cloud - 23 content categories including extended categories not available in OpenAI - Custom moderation rules — define your own rules in plain text - Conversation context awareness — detect patterns split across multiple messages (e.g. phone numbers sent in separate messages) - Text and image moderation ### OpenAI Moderation API Free to use with an OpenAI API key. - Requires an OpenAI API key configured in **Integrations** → **OpenAI** - Fixed set of content categories - Configurable confidence threshold - Text and image moderation ## How it works When enabled, messages are analyzed by the selected moderation provider. You can choose between two actions when harmful content is detected: - **Flag Only (Recommended)** — Message is delivered normally but marked for admin review. Best for user experience since no AI is 100% accurate and legitimate messages won't be blocked. - **Hold for Review** — Message is held until an admin approves or rejects it. More strict, but may delay legitimate messages. Moderators can review flagged and held messages in the admin Messages Viewer. ## Content Categories Both providers support the following base categories: - Hate / Hate Threatening - Harassment / Harassment Threatening - Sexual Content / Sexual Minors - Violence / Violence Graphic - Self-Harm / Self-Harm Intent / Self-Harm Instructions - Illicit / Illicit Violent **Better Messages Moderation AI** adds these extended categories: - Spam - Scam / Phishing - Minor Safety - Contact Sharing - Profanity - Impersonation - Doxxing - Drugs / Alcohol - Threats - Commercial Promotion Selecting a parent category automatically covers its subcategories. ## Better Messages AI — Additional Features ### Custom Rules Define your own moderation rules in plain text, one rule per line. For example: ``` Block contact info (phones, emails, social handles) and off-platform moves Block promotions, affiliate links, recruitment ``` Custom rules and content categories work independently. You can use either one alone or combine both. ### Conversation Context Set the number of previous messages to include for context (0–20). This helps detect patterns like phone numbers or emails split across multiple messages. Recommended: 5–10. ## How to enable Navigate to **WP Admin** → **Better Messages** → **Settings** → **Moderation**. 1. Select a **Moderation Provider** 2. Enable **AI Moderation** 3. Choose the **Flagged Message Action** 4. Select **Content Categories** to detect 5. Optionally enable **Moderate Images** 6. Set **Bypass Roles** for trusted user roles :::info Data Privacy Message content is sent to the selected provider for analysis. Better Messages Cloud does not store any message data — content is analyzed in real time and immediately discarded. If using OpenAI, please review OpenAI's data usage policy. ::: :::note Requirements - **Better Messages Moderation AI** requires a WebSocket license - **OpenAI Moderation API** requires PHP 8.1+ and an OpenAI API key ::: --- ## AI Message Translation in WordPress Chat # AI Message Translation Better Messages can **automatically translate incoming chat messages** to each user's preferred language using AI — in real time, with no third-party API keys to manage. Each user picks their language from a list of 69 supported languages. Messages arrive translated; a toggle reveals the original. The bridge for multilingual communities, international marketplaces, and cross-border support chats. :::info WebSocket version AI message translation is a WebSocket-version feature and is powered by Better Messages Cloud AI. Translation API access is included with the WebSocket license — no separate OpenAI / Anthropic API keys needed for this specific feature. ::: ## What it adds - Real-time translation of incoming messages to the recipient's selected language - 69 supported languages spanning Europe, Asia, Middle East, and Africa - Automatic source-language detection — no need for senders to specify their language - HTML formatting (bold, italic, links) preserved in the translated output - Translation toggle — users can switch between translated and original text - Reliable delivery — failed translations retry in the background - Admin-controllable language list (restrict to a curated subset if desired) - Privacy-respectful — translations happen via HTTPS and content isn't stored ## How it works 1. Admin enables Message Translation in the plugin settings 2. Each user selects their preferred language in the messenger settings panel 3. When a message arrives, the WebSocket relay forwards it through Better Messages Cloud AI for translation to the recipient's language 4. The user sees the translated message with a toggle icon to switch to the original | Action | Outcome | |---|---| | User in Spain sets language to Spanish | Receives all messages auto-translated to Spanish | | Friend in Germany sets language to German | Same conversation, friend sees German | | User toggles to show original | Sees the sender's original text | | Sender edits a message | Translated version updates automatically | | Translation API is slow / temporarily fails | Message arrives in original language; retry runs in background | ## Supported languages (69) | Region | Languages | |---|---| | **Western Europe** | Catalan, Danish, German, English, Spanish, Basque, Finnish, French, Irish, Galician, Icelandic, Italian, Dutch, Norwegian, Portuguese, Swedish | | **Eastern Europe** | Bulgarian, Bosnian, Czech, Welsh, Greek, Estonian, Croatian, Hungarian, Lithuanian, Latvian, Macedonian, Polish, Romanian, Slovak, Slovenian, Serbian | | **CIS & Central Asia** | Azerbaijani, Belarusian, Armenian, Georgian, Kazakh, Russian, Ukrainian, Uzbek | | **Middle East & Africa** | Afrikaans, Arabic, Persian, Hebrew, Swahili, Turkish | | **South Asia** | Bengali, Gujarati, Hindi, Kannada, Malayalam, Marathi, Nepali, Punjabi, Sinhala, Tamil, Telugu, Urdu | | **East & Southeast Asia** | Indonesian, Japanese, Khmer, Korean, Lao, Malay, Burmese, Thai, Tagalog, Vietnamese, Chinese | Admins can restrict which languages are available to users in the settings — useful for sites targeting a specific region (e.g., only EU languages). ## When AI translation matters most | Use case | Why it's transformative | |---|---| | International marketplace (Etsy-style) | Buyers and vendors communicate in their own language — purchase rates rise | | Cross-border support chat | Customer asks in Vietnamese, support replies in English, both see their language | | Multilingual community | Discussion threads include users from 5 countries naturally | | Dating site | Match conversations across language barriers | | LMS with international students | Course discussions in students' native languages | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Translation**. 1. Enable **Message Translation** 2. Optionally restrict the **Available Languages** to a curated set 3. Users select their preferred language in the messenger settings panel inside the chat interface ## Frequently asked questions ### Does the AI store my message content? No — Better Messages Cloud AI translates messages in real time over HTTPS and immediately discards the content. No retention, no training data, no logs of message bodies. See [Privacy & GDPR](/docs/features/privacy-gdpr/) for the full data-handling picture. ### Will translation work in group chats? Currently 1-on-1 conversations only. Group chat translation is planned for a future release — each participant would see messages in their own language regardless of the speaker. ### How accurate is the translation? The plugin uses state-of-the-art neural translation models. Quality is comparable to Google Translate / DeepL for major languages. For technical or specialized content, the original is always one tap away via the toggle. ### Does this work with the bad-words filter? Yes — the bad-words filter applies to the ORIGINAL sender's text (before translation). Translated views don't bypass moderation. ### How much does this feature cost? It's included with the WebSocket-version license. No per-message charges, no separate translation API key needed. ## See also - [Translations](/docs/features/translations/) — UI translations (the plugin chrome, not user messages) - [AI chat bots](/docs/features/ai-chat-bots/) — multi-provider AI chat bot integration - [AI content moderation](/docs/websocket/cloud-ai/) — AI moderation for safety - [Better Messages Cloud AI](/docs/websocket/cloud-ai/) — full Cloud AI feature set - [AI message translation blog post](/blog/ai-message-translation-wordpress/) — feature overview --- ## Auto-Delete Old Chat Messages # Auto-Delete Old Messages Better Messages can **automatically purge old messages and attachments** to manage database size and comply with data-retention policies. Set a retention period in days; a daily WP-Cron job removes anything older. Attachments have their own retention setting (often shorter than text). Useful for sites with GDPR obligations, large message volumes, or simply a policy of "no message older than 90 days." ## What it adds - Auto-delete messages older than N days (configurable) - Separate, optional **attachment retention** — typically shorter than text retention - Cleanup of messages from deleted user accounts (no orphaned data) - Daily cron job — runs in the background, no manual triggers needed - Useful for database size management on busy sites - Useful for data-retention compliance (GDPR, sector-specific regulations) ## How it works The plugin registers a daily WP-Cron task. On each run, it queries the messages table for any message older than the configured threshold, deletes them in batches (so very large purges don't time out), and removes any orphaned attachment files. | Action | Outcome | |---|---| | Cron fires | Messages older than N days are deleted in batches of 100 per tick | | User account is deleted | All of that user's messages are removed (if **Delete messages on user delete** is on) | | Attachment is older than its retention | File is removed from storage; the message stub remains saying "Attachment removed" | | Cron is disabled on the site | No auto-delete happens — wire up a real OS cron hitting `wp-cron.php`, or run `wp cron event run --all` from WP-CLI | Deleted messages are **permanently removed** — no soft-delete, no admin trash. Plan retention windows accordingly. ## When to enable auto-delete | Use case | Suggested setup | |---|---| | GDPR-strict community | 90-day text retention, 30-day attachment retention | | Large active community | 6-12 month retention to keep DB size manageable | | Customer support | 1-2 year retention for compliance + audit | | Casual social DMs | Disabled (users expect history to persist) | | Health / regulated industry | Per-regulation retention (HIPAA, etc.) — usually 6-7 years | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Messaging**. - **Auto-Delete Messages** — Delete messages older than N days (0 = disabled) - **Delete messages on user delete** — Wipe all of a user's messages when their WordPress account is removed For attachments: **WP Admin → Better Messages → Settings → Attachments**. - **Attachment Retention** — Delete attachments older than N days (0 = disabled) :::info Set retention windows thoughtfully — deletion is permanent. Communicate the retention policy to users so they don't expect indefinite history. ::: ## Frequently asked questions ### Can users export their messages before they're deleted? Not in the default UI. The REST API endpoint `GET /threads/{id}/messages` returns full thread history — users (or admins) can build a custom export with a script. ### Are pinned or favorited messages exempt from auto-delete? No — auto-delete is unconditional. A pinned message older than the retention window is deleted, and the pin is removed. ### Does auto-delete trigger notifications to users? No — deletion is silent. Users don't get a notification that old messages have been purged. The thread just shows newer messages going forward. ### What happens to a thread where all messages are deleted? The thread record itself is kept (so it can show up in the inbox empty, or be deleted manually). ### Can different chat rooms have different retention? Not in the default UI — retention is site-wide. To raise or lower the per-tick batch size, hook `better_messages_delete_old_messages_batch_size` (default `100`). ## See also - [Privacy & GDPR](/docs/features/privacy-gdpr/) — broader data-protection guide - [User-to-user block](/docs/features/user-block/) — different privacy mechanism - [End-to-end encryption](/docs/websocket/e2e-encryption/) — content-level privacy (WebSocket version) - [Pre-moderation](/docs/features/pre-moderation/) — control content quality --- ## Bad Words / Profanity Filter for WordPress Chat # Bad Words / Profanity Filter Better Messages includes a **server-side bad-words filter** that rejects messages containing any term on a configurable banned list. The block happens **before** the message is delivered — recipients never see it, and the sender gets a clear error message you can customize. Useful for family-friendly communities, paid memberships, support channels, and any site where moderation reduces friction. ## What it adds - Admin-managed banned-word list (one term per line) - Case-insensitive matching across the entire message text - Configurable error message shown to the sender on blocked attempts - Optional bypass for administrator accounts (or any role you choose) - Works pre-send — blocked messages never reach the recipient or the database ## How it works When a user submits a message, the filter walks each entry in the banned-word list and tests it as a **word-boundary regex** against the message text. If any term matches, the send is rejected and the configured error message is returned. The blocked message is **not stored** anywhere — there's no trail, no recipient notification, no database record. | Match scenario | Outcome | |---|---| | Message contains an exact banned word as a standalone token | Blocked, error shown | | Banned word appears inside a larger word (e.g. "ass" inside "class") | Allowed — matching is word-boundary, not substring | | Word in a different case | Blocked (case-insensitive) | | Banned word inside an attached file's name | Allowed (only message text is scanned) | | Sender is an administrator and "Skip admins" is on | Allowed | If you need substring matching for a specific term, type it with a leading or trailing fragment (e.g. `viagra` already matches `Viagra`, `viagra!` etc., but `cialis` will not match `cialispharma`). Multi-word phrases (e.g. `click here`) also work — the word-boundary regex treats the whole phrase as the token. ## When to use | Site type | Recommended setup | |---|---| | Family / kid-friendly community | Aggressive list, no admin bypass, friendly error message | | General community / forum | Standard profanity list + competitor brand names | | Marketplace | Block contact-info attempts: "WhatsApp", "Telegram", external emails, phone formats | | LMS | Block academic dishonesty terms ("answer key", paid-essay services) | | Support / commercial | Block spam keywords + common phishing terms | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Restrictions**. - **Bad Words List** — Enter banned words or phrases, one per line (case doesn't matter) - **Skip for Admins** — Let administrator-role accounts bypass the filter - **Bad Words Error Message** — Custom message shown to the sender when their message is rejected ## Frequently asked questions ### Can I bypass the filter for moderators, not just admins? The built-in **Skip for Admins** toggle covers only the WP `administrator` capability. For broader bypasses (e.g. a custom *Moderator* role), filter the rate-limit / restriction errors via `better_messages_can_send_message` — return `true` for roles that should be allowed through. ### Does the filter run on edited messages? Yes — edited messages re-validate against the bad-words list. If an edit introduces a banned word, the edit is rejected and the original text is preserved. ### Are message attachments scanned? No — only the message text is scanned. Attached file names and contents are not. For images that may contain text, an image moderation service (or [AI content moderation](/docs/features/ai-content-moderation/) on the WebSocket version) is more appropriate. ### What happens to a user who keeps trying to send banned words? Nothing automatic — each attempt is just rejected with the same error. For tiered escalation (e.g. temp-ban after N attempts), pair this with [pre-moderation](/docs/features/pre-moderation/) so a moderator sees the pattern. ### How big can the banned-word list be? Up to a few hundred entries performs fine. Beyond that, performance starts to drop — every message runs each term through a regex test. Consolidate variants with a single root form when possible. ## See also - [Pre-moderation](/docs/features/pre-moderation/) — admin reviews messages before delivery (stronger than word-based blocking) - [AI content moderation](/docs/websocket/cloud-ai/) — AI-driven moderation for nuanced content (WebSocket version) - [User-to-user block](/docs/features/user-block/) — let users block each other - [Role-based access](/docs/features/role-based-access/) — gate messaging entirely by user role --- ## WordPress Chat Rooms — Public, Private, Guest-Friendly # Chat Rooms A chat room is a **persistent, real-time group conversation** that lives at a fixed URL on your site. Anyone with access opens the page and steps into the existing room with its full history, rather than starting a new thread. Members come and go; the room stays. It is the difference between a Slack channel and a one-off DM. Chat rooms are the right shape for topic-based community discussion, live event lobbies, course cohorts, customer support drop-ins, team backrooms, alumni networks, fan communities, and anything else where the conversation needs to outlive any single member. Populated chat room on a WordPress page — multiple users, message bubbles, emojis, code block, online indicator ## How it works Each chat room is a WordPress custom post type (`bpbm-chat`). You create it in **WP Admin → Better Messages → Chat Rooms**, configure who can read it and who can reply, and embed it on any page, post, or page-builder block with a single shortcode: ``` [better_messages_chat_room id="123"] ``` When a logged-in user visits that page they see the running conversation immediately. Messages they post appear instantly to everyone else viewing the same room (WebSocket version) or within the next polling cycle (free version). Guests can be allowed to read, allowed to participate, or kept out entirely — per room. The room itself has no public URL — it always renders inside a page or post you control via the shortcode. Embed the same room on the homepage for guests, on a members-only page behind a membership plugin, on a course-cohort page, or inside a BuddyPress group — the conversation, participants, and history are shared across every embed. ## Key capabilities **Access & visibility** - Public, gated, or invite-only rooms — controlled per room via the **Role Based Access** panel - Optional guest entry: unregistered visitors can read, reply, or both - Per-role permissions for **Can Join**, **Can Reply**, and **Auto Add** - Hide a room from the user's inbox if it should only appear at the embed location - Close a room with one toggle to freeze it while keeping history visible **Conversation & presence** - No participant cap - Online users sidebar showing who is currently in the room - Typing, recording, and uploading indicators (WebSocket version) - Read receipts, mentions, replies, edit/delete/forward - Full text search across all messages in a room - Pinned messages and pinned conversations **Media & content** - File sharing with resumable uploads and direct-link protection - Emoji selector, sticker packs, GIPHY / Klipy GIFs - Embedded link previews and oEmbed for YouTube, Vimeo, Spotify, SoundCloud, and 20+ services - Markdown text formatting and inline code blocks - Voice messages (separate add-on plugin) - Voice and video calls inside the room, 1-on-1 or group up to 32 video / 50 audio participants (WebSocket version) **Administration** - Dedicated React admin under **WP Admin → Better Messages → Chat Rooms** with search, duplicate, and per-room delete - Per-room participant management with name / login / email search - Auto-join users when they visit the embed page - Auto-remove inactive participants on a configurable cadence (details below) - Mass messaging from WP Admin (broadcast to one or many rooms) - Per-room moderation that inherits the site-wide pipeline — [Pre-Moderation](/docs/features/pre-moderation/), [AI Content Moderation](/docs/features/ai-content-moderation/), [Bad Words Filter](/docs/features/bad-words-filter/), and [user-reported messages](/docs/features/report-messages/) all apply to chat rooms by default **Embedding & navigation** - A single shortcode `[better_messages_chat_room id="123"]` to drop a room onto any page, post, or page-builder block - Mini Widget tab listing every room the visitor belongs to, available on every page of the site - The same room can be embedded on more than one page — the conversation, participants, and history are shared ## Admin management Chat rooms have a dedicated administration page at **WP Admin** → **Better Messages** → **Chat Rooms** where administrators can: - Create, edit, and delete chat rooms - Manage participants — add or remove users - Search users by name, login, or email when adding participants WP Admin Better Messages Chat Rooms screen — sidebar with Create New Chat Room button, search box, and the list of existing rooms Selecting a room from the sidebar opens its editor with sections for Participants, Chat Room Settings, Role Based Access, Appearance, and Custom Texts. Role Based Access panel — Allow guests toggle on, per-role checkboxes for Can Join and Can Reply ## Online users sidebar Chat rooms include an expandable/collapsible sidebar panel that shows currently online members. A toggle button in the chat header allows users to show or hide the panel. ## Auto-remove inactive participants Chat rooms can automatically prune participants who have stopped engaging, keeping participant lists, unread counts, and notification fan-out focused on people who actually use the room. The job runs on the existing five-minute cleaner cron — no extra schedule to configure. Enable it per chat room under **WP Admin** → **Better Messages** → **Chat Rooms** → *Chat Room Settings* by toggling **Auto-remove inactive users**. Two more controls then appear: - **Inactivity threshold (days)** — how many days of inactivity before a participant is removed. Default `30`, minimum `1`. - **Inactivity is measured by** — pick one of three signals: - **User has not visited the site** — uses the user's last authenticated request anywhere on the site. Catches abandoned accounts. - **User has not sent a message in this chat room** — keys off messages posted in this thread only. Catches lurkers who are active site-wide but never participate here. - **User has not opened this chat room** — keys off the user's last visit to this specific chat. Catches uninterested participants. - **Apply to roles** — restrict cleanup to participants whose role matches one of the checked boxes. The list shows every editable WordPress role plus a synthetic **Guests** entry for unauthenticated visitors registered through the guest-chat flow. Leave everything unchecked to keep the original "remove anyone" behavior. :::info The most common case for **Apply to roles** is keeping auto-remove on but ticking only **Guests** — silent guest visitors get pruned and registered members are left alone. ::: :::info Every participant gets a built-in grace period equal to the **Inactivity threshold** before they become eligible for removal. A user who was just added to a room — by clicking Join, by an admin invitation, or via **Auto join users** — will not be purged until they have been a member for at least that many days, even if their site-wide last activity is older than the threshold. This prevents brand-new joiners from being deleted on the very next cron run. ::: :::info Removed users may rejoin if they meet the role requirements. If **Auto join users** is also enabled, an inactive user who later visits the page hosting the chat shortcode is auto-joined again automatically — that is the intended round trip: prune dormant, restore active. ::: AI chat bots are skipped automatically and never auto-removed. ### Pin specific users To prevent specific users (admins, room owners, guests of honor) from ever being auto-removed, drop the following into your theme's `functions.php` or a custom plugin: ```php add_filter( 'better_messages_clean_inactive_chat_users_exclude_user_ids', function( $ids ) { return array( 1, 42, 7 ); } ); ``` ### Tune the per-cron batch size By default the job removes up to 100 inactive participants per chat room per cron tick. To raise or lower that: ```php add_filter( 'better_messages_clean_inactive_chat_users_batch_size', function() { return 500; } ); ``` Setting the batch size to `0` disables the cleanup job entirely. ## How to enable Chat rooms are managed through **WP Admin** → **Better Messages** → **Chat Rooms**. **Creating a chat room:** 1. Click **Add New** to create a new chat room 2. Set the chat room name 3. Configure allowed roles (which user roles can join) 4. Optionally enable guest access for non-registered users 5. Publish the chat room **Embedding a chat room:** Use the shortcode on any page or post: ``` [better_messages_chat_room id="123"] ``` Replace `123` with the actual chat room post ID. ## Mini widget access When the Chat Rooms mini widget is enabled under **Better Messages** → **Settings** → **Mini Widgets**, every page on your site gets a bottom-bar or floating-bubble tab that lists the rooms the current user belongs to. Mini widget panel showing the Chat Rooms tab with four joined rooms (General Lounge, Coding & Dev, Movies & TV, VIP Lounge) and member counts ## See also - [Group conversations](/docs/features/group-conversations/) — multi-user threads that are *not* tied to a fixed page - [AI Chat Bots](/docs/features/ai-chat-bots/) — drop an AI participant into any chat room - [Pre-moderation](/docs/features/pre-moderation/), [AI Content Moderation](/docs/features/ai-content-moderation/), and [Bad Words Filter](/docs/features/bad-words-filter/) — automated moderation that applies to chat rooms - [Report messages](/docs/features/report-messages/) — let participants flag content for admin review - [Role-based access](/docs/features/role-based-access/) — the same role system that gates chat-room entry - [Guest access](/docs/features/guest-access/) — let unregistered visitors participate in public rooms - [Mini widgets](/docs/features/mini-widgets/) — surface chat rooms across every page of your site - [Video calls](/docs/websocket/video-calls/), [Audio calls](/docs/websocket/audio-calls/), and [Group video chat](/docs/websocket/group-video-chat/) — start a call directly inside a chat room (WebSocket version) --- ## Mute Conversations in WordPress Chat # Conversation Muting Better Messages lets each user **mute individual conversations** to stop receiving notifications for them — without leaving the thread or hiding it from the inbox. Useful for noisy group chats where the conversation is informational rather than urgent, or for chat rooms a user wants to keep accessible but quiet. ## What it adds - One-click mute toggle from any conversation - Mutes all notification channels for that thread: sound, on-site popup, email, mobile push - Conversation stays in the inbox and remains fully readable / replyable - Unread counts continue to update — mute is about delivery alerts, not visibility - Per-user setting — your mute state doesn't affect other participants - Optional admin setting: `@`-mentions still notify even inside muted conversations (**Force mentions notifications**) ## How it works When a user mutes a conversation, the plugin stores a per-user mute flag against that thread. From that point: | Channel | Behavior in muted thread | |---|---| | Sound notification | Silent | | On-site popup | Suppressed | | Email notification | Skipped | | Mobile push (app) | Skipped | | Unread count in inbox | Still updates | | In-conversation indicator | A muted-bell icon is shown in the thread header | If **Force mentions notifications** is enabled in the admin settings, a message that `@`-mentions the muted user inside a muted thread is treated as unmuted for that single message — popup, sound, and push fire. Useful for "lurk-mode" group chats where users want to be alerted only when directly addressed. ## When to mute | Use case | Why muting matters | |---|---| | Large community announcement room | Quiet ambient awareness, no constant pings | | Cohort group chat | Stay in the loop without sound interruption during deep work | | Information broadcast threads | Receive updates passively, not urgently | | Sales pipeline DMs | Mute closed deals to declutter without losing the history | | Personal "thinking thread" with self | Quiet personal notes channel | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Messaging**. - **Allow Mute Conversations** — Toggle the mute feature on or off site-wide The feature is **enabled by default**. ## Frequently asked questions ### Do muted conversations show in search results? Yes — search ignores the mute state. The mute affects notifications, not content visibility. ### Can I mute someone but not their other conversations? Mute is per-thread, not per-user. To stop all communication from a specific user, use the [user-block feature](/docs/features/user-block/) instead. ### Does mute apply to AI bot messages in the thread? Yes — AI bot replies are notifications like any other. Muting silences them too. ### Does muting affect the [unread filter](/docs/features/unread-filter/)? Yes — the unread filter and inbox badge respect the mute. Muted threads are quiet by design: they don't surface in the "unread only" view and they don't drive the header unread badge. Open the thread directly or switch back to **All conversations** to catch up when you're ready. ### Can administrators force-mute a conversation for all participants? No — muting is always a per-user choice. To silence a chat room globally, use the room's notification settings to disable notifications at the room level. ## See also - [Site notifications](/docs/features/site-notifications/) — overview of in-app notifications - [Email notifications](/docs/features/email-notifications/) — email delivery rules - [Sound notifications](/docs/features/sound-notifications/) — audio cues - [Unread filter](/docs/features/unread-filter/) — focus on threads needing attention - [User-to-user block](/docs/features/user-block/) — stronger silencing per-user instead of per-thread --- ## Customize WordPress Chat Plugin Design # Easy Customization Better Messages is **designed to blend into any WordPress site** — no coding required for the basics, full CSS access for advanced theming. Pick an accent color in the WordPress Customizer, choose between two layout templates, configure message alignment, and (for white-label sites) hide all plugin branding from end users. ## What it adds - Visual color customizer — pick your accent color with a live preview in the WordPress Customizer - Two layout templates — "Standard" (classic two-column inbox + thread) and "Modern" (compact, mobile-first) - Message bubble alignment — own messages left or right, configurable - Conversation list layout — wide / narrow / hidden modes - Custom CSS hooks — every UI surface has stable class names you can target - Responsive design — works with any WordPress theme; no specific theme dependency - White-label mode — hide all "Better Messages" branding from the user-facing UI (full white-label requires the WebSocket version's brand customization) ## How it works The accent color is applied as a CSS custom property across the entire messenger — buttons, links, focus rings, badges, highlights all derive from the single color you pick. Light and dark theme variants are automatically generated. The layout template switches between two rendering modes: | Template | Best for | |---|---| | **Standard** | Sites with their own header / sidebar — fits inside a content area | | **Modern** | Standalone messenger pages, mobile-first communities, social network feel | The two templates share 100% of the underlying functionality — switch anytime without data loss. ## What you can change visually | Without code | With CSS | |---|---| | Accent color | All colors, gradients, shadows | | Layout template | Component dimensions, spacing | | Message alignment | Bubble shape (rounded / squared / asymmetric) | | Conversation list layout | Custom avatars, badges, status indicators | | Branding visibility | Replace fonts, icons, animations | ## How to enable **Accent color** — Navigate to **WP Admin → Appearance → Customize → Better Messages** and use the color picker. Changes preview live. **Layout / dimensions** — Navigate to **WP Admin → Better Messages → Settings → General**. - Template selector (Standard / Modern) - Layout mode (full-width / contained / sidebar) - Width and height configurations for embedded views **Custom CSS** — Add CSS rules via: - Your theme's Additional CSS in **Appearance → Customize** - A plugin like Simple Custom CSS - A child theme's stylesheet Target Better Messages classes — they all start with `.bp-better-messages-` for backwards compatibility, or `.better-messages-` for the modern prefix. ## Frequently asked questions ### Can I use my brand font in the messenger? Yes — add CSS via your theme's Additional CSS area: ```css .better-messages * { font-family: "Your Brand Font", sans-serif; } ``` Or load a webfont then re-declare the family. ### Do customizations survive plugin updates? Yes — color, template, and layout settings persist in the database. Custom CSS in your theme survives any plugin update. Hooking PHP via a child theme also survives updates. ### Can I have different designs for different chat rooms? There's no per-chat-room custom-CSS field in the admin today. To restyle a specific room, scope your CSS in **Appearance → Customize → Additional CSS** to that room's body class or post id, e.g. `body.bpbm-chat-id-123 .bm-thread { ... }`. ### How do I match the design of an integration plugin (BuddyBoss / PeepSo)? Better Messages ships integration-specific stylesheets that align spacing and border-radius with the host theme's chat-related surfaces. For finer brand alignment, override the variables exposed by the messenger via the WordPress Customizer accent color, or add overrides under **Appearance → Customize → Additional CSS**. ### What about the mobile app — can I rebrand that? The mobile app is white-label-ready via the [mobile app build service](/docs/category/mobile-app/) — your own app icon, name, splash screen, push provider, and bundle ID. Contact support to start a custom build. ## See also - [White label](/docs/features/white-label/) — hide all Better Messages branding - [Modern design](/docs/features/modern-design/) — details of the Modern template - [Mobile app](/docs/category/mobile-app/) — native iOS / Android branding options - [Change avatar size CSS snippet](/docs/development/css-snippets/change-avatar-size/) — example of CSS customization --- ## Email Notifications for WordPress Chat # Email notifications ## How email notifications work? Instead of standard notification on each new message, Better Messages plugin will group messages by thread and send it within next 15 minutes with cron job. - User will not receive email notifications, if they are disabled in user settings. - User will not receive email notifications for already read messages. - User will not receive email notifications, if he was online at website last 10 minutes. ## Email Template Customization Better Messages allows you to customize the appearance of email notifications sent to users. ### Template Source (BuddyPress sites only) If you have BuddyPress installed, you can choose between two template sources: - **BuddyPress Email Template** - Uses your existing BuddyPress email customizations. This is the default option for BuddyPress sites. - **Custom Template** - Use the simple or custom HTML template options described below. ### Template Mode When using custom templates (or on non-BuddyPress sites), you can choose between two modes: #### Simple Mode Simple mode allows you to customize the email appearance without writing any code: - **Email Logo** - Upload a logo image to display at the top of emails. The logo will be displayed at its uploaded size, scaled down only if it exceeds the email width. - **Primary Color** - Used for buttons and links. - **Background Color** - Email outer background color. - **Content Background Color** - Main content area background color. - **Text Color** - Color of the email text. - **Header Text** - Custom greeting text. Use `‎{{user_name}}` placeholder for the recipient's name. Leave empty for default "Hi `‎{{user_name}}`,". - **Footer Text** - Custom footer text. Use `‎{{site_name}}` and `‎{{site_url}}` placeholders. - **Button Text** - Text for the "View Conversation" button. #### Custom HTML Mode For full control over email appearance, you can create a custom HTML template. Available placeholders: | Placeholder | Description | |-------------|-------------| | `‎{{site_name}}` | Your website name | | `‎{{site_url}}` | Your website URL | | `‎{{user_name}}` | Recipient's display name | | `‎{{subject}}` | Conversation subject | | `‎{{messages_html}}` | Formatted messages content | | `‎{{thread_url}}` | Link to the conversation | | `‎{{email_subject}}` | Email subject line | | `‎{{unsubscribe_url}}` | Unsubscribe link URL | Click "Load Default Template" to start with the default template structure and customize it. ### Unsubscribe Link You can optionally add an unsubscribe link to message notification emails. When enabled, users can click the link to stop receiving message email notifications. This setting is only available when using custom templates (not BuddyPress email templates, which have their own unsubscribe mechanism). ### Test Email Use the "Send Test Email" feature to preview how your email template looks. Enter an email address and click "Send Test Email" to receive a sample notification. :::info Save your settings before sending a test email to ensure all changes are applied. ::: ## Frequently asked questions ### Why batch emails every 15 minutes instead of sending immediately? A user in an active conversation might receive 20+ messages in a few minutes. Sending one email per message would flood inboxes. Batching groups all new messages per thread into a single email per 15-minute window — better signal-to-noise ratio. ### Are emails skipped when the user is active on the site? Yes — three conditions skip the email: user disabled emails in their settings, user already read the message, or user was online in the last 10 minutes. The assumption is that an active user doesn't need an email summary. ### Can I customize the email template per role? Not from the admin UI — the email template is a single site-wide setting. For per-role variations, override the outgoing email via the standard WordPress `wp_mail` filter and rewrite the body based on the recipient. ### Does the unsubscribe link unsubscribe from all chat emails or just one type? It unsubscribes from message email notifications globally for that user. They continue to receive other Better Messages emails (account-related, password reset, etc.). ### How does this work with the WebSocket version's instant delivery? Independently. Even on the WebSocket version, users get email notifications when they're not online. Instant delivery (web push, in-app) handles online users; email handles offline. ## See also - [Sound notifications](/docs/features/sound-notifications/) — audio alerts for online users - [Site notifications](/docs/features/site-notifications/) — on-site popups for online users - [Web push notifications](/docs/websocket/web-push/) — browser push when away (WebSocket version) - [Mass messaging](/docs/features/mass-messaging/) — broadcast emails for admin announcements - [Email notifications blog post](/blog/wordpress-chat-email-notifications/) — feature overview --- ## Emoji Picker for WordPress Chat # Emoji Selector Better Messages includes a **built-in emoji picker** with categorized browsing, multilingual keyword search, and a choice of visual emoji styles. Pick the Apple, Google, Twitter, Facebook, or Native set to render emojis consistently across browsers and operating systems — your users see the same 🤣 regardless of whether they're on iOS, Android, Windows, or macOS. ## What it adds - Emoji button in the message input that opens a full categorized picker - 8 categories: Smileys & People, Animals & Nature, Food & Drink, Activities, Travel & Places, Objects, Symbols, Flags - Keyword search bar — type "fire" → 🔥 (also works in 30+ other languages with [search translations](#multilingual-search)) - Recently-used row for fast access to common emojis - Choice of 5 rendering styles (Apple / Google / Twitter / Facebook / Native) - Per-category enable/disable for content moderation (e.g., hide Flags on a non-political site) - Drag-and-drop category reordering in admin ## How it works The picker is a React component that loads a JSON emoji map. When the user picks an emoji, it's inserted into the message input as a Unicode character. On render, emojis are converted to images from the chosen emoji set (or kept as Unicode for "Native"). | Style | Renders emojis as | |---|---| | **Apple** | Apple's emoji designs (iOS 16 look) | | **Google** | Google Noto Color emoji | | **Twitter / X** | Twemoji (open-source) | | **Facebook** | Facebook emoji designs | | **Native** | Unicode characters — uses the user's OS emoji | Apple/Google/Twitter/Facebook ensure consistency: a 👍 looks the same to every user regardless of their device. Native is the lightest option (no image loading) but renders differently on different devices. ## When to choose each style | Audience | Recommended style | |---|---| | Visual-design-sensitive community | Apple — most polished, premium feel | | Open-source / privacy focus | Twitter (Twemoji is open-source, no Apple/Google tracking) | | Performance-first / mobile-heavy | Native — no image loads | | International, mixed devices | Twitter — most consistent free option | | Brand alignment with iOS app | Apple | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Integrations → Emojis**. - **Emoji Set** — Choose the rendering style - **Categories** — Enable/disable individual categories - **Category Order** — Drag-and-drop to set the order in the picker - **Emoji Search Translations** — Download per-locale annotations so picker search works in the user's language (see below) ## Multilingual search A German user typing "gesicht" should find face emojis. A French user typing "cœur" should find ❤️. By default the picker ships with English keywords only, so non-English searches return nothing. Better Messages solves this with **on-demand emoji search translations**: 1. In **WP Admin → Better Messages → Settings → Integrations → Emojis**, scroll to the *Emoji Search Translations* section. 2. Find your site's language in the list and click **Download**. 3. The annotation file (~150 KB) is fetched from `better-messages.com` and stored in `wp-content/uploads/better-messages/emoji/annotations/`. 4. The emoji picker rebuilds with localized names and keywords merged on top of the English ones — both languages keep working. 30+ languages available, matching the WordPress translation locales: German, French, Spanish, Italian, Portuguese, Dutch, Polish, Russian, Ukrainian, Czech, Hungarian, Romanian, Bulgarian, Swedish, Danish, Norwegian, Finnish, Greek, Turkish, Arabic, Hebrew, Persian, Chinese (Simplified & Traditional), Japanese, Korean, Vietnamese, Thai, Indonesian, Hindi. :::info Bilingual search by design We **append** localized keywords rather than replacing English ones, so multilingual communities keep working. A German user can search "gesicht" *or* "face" — both return the same emoji. ::: The annotation data is sourced from the [Unicode CLDR](https://cldr.unicode.org/) (Common Locale Data Repository), the same dataset used by iOS, Android, and Windows for their native emoji pickers. ## Frequently asked questions ### Does the search support multiple languages? Yes — see [Multilingual search](#multilingual-search) above. Download the annotation file for your locale from the admin settings to enable localized keyword search. English keywords keep working alongside the localized ones. ### Can I add custom emojis (brand emojis, team-specific)? Stock emojis are fixed (the standard Unicode set). For custom branded reactions, use [stickers](/docs/features/stickers/) — Better Messages supports custom sticker packs you upload as images. ### Do emoji reactions use the same set as the picker? Yes — the [message reactions](/docs/features/message-reactions/) picker draws from the configured emoji set. The reaction set is a curated subset, but the rendering style matches. ### Why does the same emoji look different in different conversations? It shouldn't — the rendering is determined by the global emoji set setting. If you're seeing differences, check that you don't have a theme overriding emoji rendering, or that an old browser cache isn't stuck. ### Does the picker work on touch devices? Yes — the picker is fully responsive and touch-friendly. Categories scroll horizontally on small screens, and tap targets are sized for fingers. ## See also - [Message reactions](/docs/features/message-reactions/) — react to messages without sending a reply - [Stickers](/docs/features/stickers/) — custom sticker packs as message bodies - [GIPHY integration](/docs/features/giphy-integration/) — animated GIF picker - [Mentions](/docs/features/mentions/) — @-mention picker for users --- ## Mobile-Optimized WordPress Chat # Mobile-Optimized Layout Better Messages auto-detects mobile devices and switches to a **mobile-optimized interface** designed for thumbs and small screens. Full-screen takeover when opening a thread, swipe-left to go back, a floating chat button accessible from any page — the messenger feels like a native app even in the browser. For sites that want a true native app, the [iOS + Android mobile app](/docs/category/mobile-app/) takes this further. ## What it adds - Full-screen messaging mode — chat takes over the entire mobile viewport - Auto-enter full-screen when opening a conversation - Swipe-left gesture to navigate back to the conversation list - Floating chat button for one-tap access from any site page - Configurable floating button corner (left / right) and bottom margin - "Tap to open" prompt for first-time mobile users - Configurable mobile-only sidebar tabs (Chat Rooms, AI Bots, Users, Friends, Groups) with icon-only mode ## How it works Better Messages detects mobile based on viewport width (the responsive layout activates around 800px and below) plus user-agent hints. On mobile: 1. The messenger UI adapts to a single-column layout (inbox or thread, not both) 2. If "Mobile Full Screen" is enabled, opening a thread takes over the viewport 3. The floating chat button appears in the configured corner if enabled 4. Swipe-left from the open thread navigates back to the inbox | Mobile gesture / setting | Effect | |---|---| | Tap floating button | Opens the messenger inbox | | Tap a conversation | Opens thread (full-screen if enabled) | | Swipe left from thread | Returns to inbox | | Tap close X | Closes the messenger | ## When to customize each option | Setting | Recommendation | |---|---| | Full-screen mode | Enable on most sites — better mobile UX | | Floating chat button | Enable on community / marketplace sites; disable if the messenger is on a dedicated page | | Button position | Right side for most; left for RTL sites | | Bottom margin | Adjust if site has a fixed footer or bottom nav | | Tap-to-open hint | Helpful for first-time mobile users who don't notice the chat button | | Mobile tabs | Show only the tabs you need (Chat Rooms, AI Bots, Users) to keep the UI compact | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Mobile**. - **Mobile Full Screen** — Take over the mobile viewport when a thread is open - **Tap to Open** — Show a one-time "Tap to open" hint to first-time mobile users - **Swipe Back** — Enable swipe-left to go back from thread to inbox - **Mobile Popup** — Show the floating chat button for one-tap access - **Mobile Popup Location** — Left or right side of the screen - **Mobile Popup Bottom Offset** — Distance from the bottom edge in pixels (avoid overlap with footers) - **Mobile Tabs** — Enable Chat Rooms / AI Bots / Users / Friends / Groups tabs in the mobile sidebar - **Mobile Tabs — Icons Only** — Hide tab labels to keep the mobile sidebar narrow ## Frequently asked questions ### Does this work in mobile-app webviews? Yes — the mobile-optimized UI also runs inside the native iOS / Android app, which uses a webview for the chat surface. The native app adds extras the web messenger can't do, such as system push notifications and native call UI. ### Can I customize the mobile breakpoint? The mobile layout is driven by CSS media queries in the plugin's stylesheet (around the 800px viewport). To shift the breakpoint, add a custom CSS rule in your child theme or via **Appearance → Customize → Additional CSS**. ### Where can the floating button overlap with my site's other widgets? The button uses the **Mobile Popup Bottom Offset** setting (pixels). If you run a live-chat widget, cookie banner, or sticky footer on the same corner, raise the offset to clear them, or use the opposite corner via **Mobile Popup Location**. ### How does this compare to the native mobile app? The mobile-optimized layout is the **same web-based messenger** with a mobile UI. The [native mobile app](/docs/category/mobile-app/) is a separate iOS / Android app with system push notifications and native call UI. Most sites use both — the web layout for casual visitors, the native app for power users. ## See also - [Mobile app](/docs/category/mobile-app/) — native iOS / Android app - [Mini widgets](/docs/features/mini-widgets/) — embedded chat surfaces (counters, buttons) - [Modern design](/docs/features/modern-design/) — desktop + responsive layouts - [Easy customization](/docs/features/easy-customization/) — visual tuning --- ## Bookmark Favorite Messages in WordPress Chat # Favorite Messages Better Messages lets each user **star individual messages** to bookmark them for later. The starred messages appear in a dedicated **Favorites** section accessible from the user's messenger sidebar — no need to scroll through long histories to find the link, snippet, or decision shared weeks ago. ## What it adds - Star/unstar button on every message in every conversation - Dedicated "Favorites" view in the messenger sidebar - Per-user storage — your starred messages are private to you - Works in DMs, group chats, and chat rooms — even messages from blocked-or-removed users stay in favorites - Quick deep-link from a favorite back to its conversation context - Survives message deletion by the sender (the favorite stub remains) ## How it works When a user clicks the star icon on a message, Better Messages stores a `user_id → message_id` favorite record. The message remains in its original conversation; the favorite is just a saved pointer. | Action | Outcome | |---|---| | User stars a message | Star icon fills, message added to user's favorites | | User clicks "Favorites" in sidebar | List of all starred messages, newest first | | User clicks a favorite | Opens the source conversation, scrolled to that message | | Sender deletes the original message | Favorite stays, but body shows "Message deleted" | | User unstars | Favorite removed from list | | Sender edits the message | Favorite reflects the edited content | Favorites are **private per user** — there's no team/shared favorites view. Two users in the same conversation can independently star different messages with no interaction. ## When users benefit | Use case | What gets starred | |---|---| | LMS course chat | Lesson links, assignment due dates, instructor announcements | | Marketplace vendor inbox | Repeat customer info, shipping policies sent multiple times | | Community manager | Recurring FAQ answers ready to copy-paste again | | Personal DMs | Important addresses, phone numbers, links shared in conversation | | Support team | Solution snippets to reuse for similar tickets | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Messaging**. - **Disable Favorite Messages** — Toggle to turn the feature off The feature is **enabled by default** on every install. ## Frequently asked questions ### Can a user export their favorites? Not via the default UI. The favorites view in the messenger sidebar paginates over a REST endpoint, so a developer can hit that endpoint with the user's nonce to build a custom export tool. ### Is there a limit on how many messages can be favorited? No hard cap. Power users with thousands of favorites may see slower load times on the favorites view — pagination is built in. ### Do favorites work in guest conversations? Yes — guest users have a per-session favorites store (browser-local), since they don't have a persistent account. Their favorites disappear when they log out / clear browser data. Logged-in users get persistent server-side favorites. ### Can administrators see what users have favorited? No. Favorites are private. Admins cannot view another user's favorites through the admin UI. (Technically the data is in the database and a custom script could query it; that's a code-level decision, not a built-in feature.) ### Does the AI chat bot's response count as a starrable message? Yes — AI bot messages are normal messages from the favorites perspective. Users can star a particularly useful AI answer for future reference. ## See also - [Pinned messages](/docs/features/pinned-messages/) — admin-pinned messages visible to all participants (different use case) - [Search](/docs/features/search/) — search across all messages without bookmarking first - [Message reactions](/docs/features/message-reactions/) — emoji reactions, visible to all participants - [Reply, edit, forward](/docs/features/reply-edit-forward/) — other message-level actions --- ## File Sharing in WordPress Chat # File Sharing Better Messages allows users to share files, images, videos, and documents directly in conversations with support for resumable uploads, client-side media optimization, and file access protection. ## How it works Users can attach files to their messages using the attachment button in the message input area. Files can also be dragged and dropped directly onto the conversation. The plugin supports a wide range of file types including images, videos, documents, and archives. Uploaded files are stored in your WordPress media directory. Before uploading, images and videos can be automatically optimized in the user's browser — reducing file sizes, converting to modern formats, and stripping metadata. This happens entirely on the client side using WebAssembly, so your server receives already-optimized files with no additional load. For large files, the plugin supports **resumable uploads** using the TUS protocol, ensuring files can be uploaded reliably even on slow or unstable connections. If an upload is interrupted, it automatically resumes from where it left off. **File access protection** is available through a proxy system that serves files through your WordPress server instead of exposing direct URLs. This prevents unauthorized users from accessing files by guessing or sharing direct download links. ## Key capabilities - Share images, videos, documents, and other file types in messages - Drag-and-drop files directly onto conversations - Webcam photo capture directly in the message composer - Resumable uploads via TUS protocol for reliable large file transfers - Automatically convert images to modern formats (AVIF, WebP, or JPEG) in the browser before uploading - Convert MOV, AVI, WMV, and MKV videos to MP4 in the browser using FFmpeg WASM - Automatically convert iPhone HEIC photos to a compatible format - Remove EXIF data, GPS location, and camera info from images and videos to protect user privacy - Automatically downscale large images to a specified maximum dimension - File access protection through proxy serving (PHP, X-Sendfile, X-Accel-Redirect, LiteSpeed) - Configurable maximum file size and number of files per message - Whitelist of allowed file extensions - Optional auto-deletion of attachments after a specified number of days - Attachments browser tab in conversation details panel - Option to hide uploaded files from the WordPress Media Library ## Image optimization When enabled, images are converted to the best format supported by the user's browser before uploading. The conversion happens entirely in the browser using Web Workers and WebAssembly, so your server receives already-optimized files. The format fallback chain is: **AVIF → WebP → JPEG**. The browser automatically uses the best format it supports — AVIF for modern browsers, WebP for older ones, and JPEG as a universal fallback. Supported input formats: JPEG, PNG, BMP, TIFF, WebP, AVIF, HEIC/HEIF, and ICO. GIFs can optionally be transcoded to WebP, AVIF, or JPEG formats during upload using FFmpeg WASM. SVG files are not converted to preserve vector quality. **HEIC/HEIF photos** from iPhones are always converted to JPEG regardless of whether image optimization is enabled, since browsers cannot display HEIC files natively. This uses the libheif WASM decoder. You can also set a **maximum image resolution** to automatically downscale large images. The image is proportionally scaled so that neither width nor height exceeds the configured value. Set to 0 for no limit. ## Video optimization When enabled, videos in MOV, AVI, WMV, and MKV formats are converted to MP4 in the browser using the FFmpeg WASM engine before uploading. This provides cross-browser and cross-device compatibility. The conversion first attempts a fast **remux** (container change without re-encoding) which completes almost instantly for compatible codecs like H.264. If remuxing fails, it falls back to a full transcode using H.264 video and AAC audio. iPhone MOV files recorded with H.264 are typically remuxed instantly without any quality loss. :::info The FFmpeg WASM engine is approximately 30MB and needs to be downloaded to your server first. Use the **Download Engine** button in the settings to install it. ::: ## Metadata stripping When enabled, EXIF data, GPS coordinates, camera information, and other metadata are automatically removed from uploaded images and videos. This protects user privacy by preventing location and device information from being shared with other participants. For images, metadata is stripped during the browser-side conversion process. If browser-side processing is unavailable, the server automatically strips metadata as a fallback using WordPress image editor (Imagick or GD). For videos, metadata is stripped using FFmpeg's `-map_metadata` flag during video optimization. ## Upload methods Better Messages supports two upload methods: - **Standard POST** — Traditional file upload. Limited by your server's PHP `upload_max_filesize` and `post_max_size` settings. - **TUS (Resumable Upload)** — Files are uploaded in chunks and can resume after interruptions. Bypasses PHP upload size limits. Some hosting providers with aggressive WAF (Web Application Firewall) rules may block TUS uploads. ## File access protection When file proxy is enabled, all attachment URLs are routed through your WordPress server, which verifies the requesting user has access to the conversation before serving the file. Direct file URLs are blocked. Available proxy methods: - **PHP** — Uses `readfile()` to serve files through PHP. Works everywhere but uses more memory and CPU. - **X-Sendfile** — For Apache with mod_xsendfile. PHP handles authentication, then Apache serves the file directly. - **X-Accel-Redirect** — For Nginx. PHP handles authentication, then Nginx serves the file directly. Requires an `internal` location block in your Nginx configuration. - **LiteSpeed** — For LiteSpeed web server. Uses X-LiteSpeed-Location header for efficient file serving. :::info For best performance on high-traffic sites, use X-Sendfile (Apache), X-Accel-Redirect (Nginx), or LiteSpeed instead of the PHP method. ::: ## How to enable Navigate to **WP Admin** → **Better Messages** → **Settings** → **Attachments**. ### General settings - **Enable File Sharing** — Turn file attachments on or off - **Hide from Media Library** — Prevent uploaded files from appearing in WordPress Media (enabled by default) - **Attachments Browser** — Show an attachments tab in conversation details for browsing shared files - **Webcam Photo** — Allow users to capture photos from their webcam ### Upload settings - **Upload Method** — Standard POST or TUS resumable uploads - **Max File Size** — Maximum file size in megabytes - **Max Files Per Message** — Maximum number of files per message (0 for unlimited) - **Allowed Formats** — List of permitted file extensions ### Media optimization - **Image Optimization** — Convert images to the best browser-supported format (AVIF, WebP, or JPEG) before uploading - **Image Quality** — Quality level for converted images (1-100, default 85) - **Max Image Resolution** — Downscale images so neither dimension exceeds this value (0 for no limit) - **Video Optimization** — Convert videos (MOV, AVI, WMV, MKV) to MP4 in the browser before uploading - **Strip Metadata** — Remove EXIF, GPS, and camera data from images and videos (enabled by default) ### File access protection - **File Proxy** — Serve files through a proxy to protect direct URLs - **Proxy Method** — Choose between PHP, X-Sendfile, X-Accel-Redirect, or LiteSpeed - **Attachment Retention** — Automatically delete attachments after N days (0 to keep forever) --- ## GIPHY & KLIPY Animated GIFs in WordPress Chat # GIFs Better Messages supports GIFs through two providers — **GIPHY** and **KLIPY** — giving users a fun way to express themselves in conversations with animated images. GIF picker in chat ## How it works When enabled, a **GIF** button appears in the message input area. Clicking it opens a full-width picker at the bottom of the chat where users can: - **Browse trending GIFs** — the default view shows currently popular GIFs - **Search by keyword** — type in the search bar to find specific GIFs - **Send with one click** — tap any GIF to send it instantly; the picker closes immediately GIF button in chat The GIF grid uses a stable masonry layout — new results load as you scroll down without repositioning existing items, so the browsing experience stays smooth. ## Providers Better Messages supports one GIF provider at a time. Choose the one that best fits your site. ### GIPHY The world's largest GIF library with billions of GIFs. Free API keys are available. GIPHY settings **Settings** (at **Settings** → **Integrations** → **GIFs**, select GIPHY): | Setting | Description | |---|---| | **API Key** | Your GIPHY API key. Leave empty to disable. [Get a free key](https://developers.giphy.com) | | **Content Rating** | Filter GIFs by rating level. Options: **G** (all ages, default), **PG**, **PG-13**, **R**. [Learn more](https://developers.giphy.com/docs/optional-settings/#rating) | | **Language** | Two-letter language code for search results (e.g. `en`, `es`, `fr`). [Supported languages](https://developers.giphy.com/docs/optional-settings/#language-support) | :::info GIPHY's free tier is generous — it supports up to 1,000 API calls per hour and 42 calls per minute, which is enough for most messaging sites. ::: ### KLIPY A newer GIF platform with curated content and optional ad-supported monetization. KLIPY settings **Settings** (at **Settings** → **Integrations** → **GIFs**, select KLIPY): | Setting | Description | |---|---| | **API Key** | Your KLIPY app key from the partner dashboard. [Register for a key](https://klipy.co) | | **Locale** | ISO 3166 two-letter country or language code for localized results (e.g. `en`, `fr`) | | **Show Ads** | Enable KLIPY-sponsored GIFs in trending and search results. Requires ads to be activated for your KLIPY app key. Off by default | ## How to enable 1. Navigate to **WP Admin** → **Better Messages** → **Settings** → **Integrations** → **GIFs** 2. Select a **Provider** from the dropdown (GIPHY or KLIPY) 3. Enter your **API Key** for the selected provider 4. Configure content rating and language preferences 5. The GIF button will appear in the chat input area for all users ## Key capabilities - **Trending GIFs** — popular content shown by default when the picker opens - **Keyword search** — real-time search with debounced input for responsive results - **Stable masonry grid** — items never reposition when new results load on scroll - **Optimistic send** — the picker closes immediately on selection; the GIF appears in the conversation as soon as the server confirms - **Content filtering** — GIPHY's content rating system lets you control what's appropriate for your audience - **Transient caching** — trending results are cached server-side to reduce API calls (30 minutes for GIPHY trending, 15 minutes for search) - **Works everywhere** — private messages, group conversations, and chat rooms ## Switching providers You can switch between GIPHY and KLIPY at any time by changing the Provider dropdown. Only one provider can be active at a time. Previously sent GIFs from either provider will continue to display correctly in chat history regardless of which provider is currently active — the GIF URLs are stored directly in the message content. ## Frequently asked questions ### Does the GIF feature cost money? GIPHY's free tier is generous (1,000 API calls per hour, 42 per minute) — enough for most sites. KLIPY is also free for standard use. Heavy-traffic sites should review their provider's pricing tiers. ### Can I disable GIFs without removing the API key? Yes — switching the **Provider** dropdown back to *Disabled* hides the GIF button without removing the saved API key, so you can re-enable later without rotating credentials. ### Are GIFs included in the bad-words filter? The GIF URL is included in the message text; if a banned word appears in the URL it would be caught. The GIF visual content isn't moderated by the bad-words filter. For that, use the [AI content moderation](/docs/websocket/cloud-ai/) (WebSocket version) — it can flag inappropriate images. ### Do GIFs work in voice / video calls? GIFs are sent as messages, separate from the call media stream. A user in a call can still send GIFs in the conversation alongside the active call. ### Can I host my own GIFs instead of using GIPHY / KLIPY? For custom branded animated content, use [Stickers](/docs/features/stickers/) — they let you upload sticker packs as images stored locally. ## See also - [Stickers](/docs/features/stickers/) — custom sticker packs (alternative to GIFs) - [Emoji selector](/docs/features/emoji-selector/) — emoji picker - [oEmbed support](/docs/features/oembed-support/) — embed YouTube and other media inline - [WordPress chat GIF blog post](/blog/wordpress-chat-gif-giphy-klipy/) — feature overview - [File sharing](/docs/features/file-sharing/) — for static images and other files --- ## Group Chat / Multi-Participant Conversations # Group Conversations Better Messages supports **multi-participant group conversations** alongside private 1-on-1 DMs. Any user can start a group thread with multiple recipients, add or remove participants over time, and use every messaging feature — file sharing, reactions, calls, AI bots — exactly as in 1-on-1 chats. No participant cap, no separate "group plan", no premium gate. A four-participant group conversation showing avatars in the header, moderator badges, @-mentions rendered as pills, emoji reactions on messages, and a system message recording a moderator promotion ## What it adds - Unlimited participants per conversation - Any user can start a group conversation from the new-thread screen - Thread moderators (creator + WP admins) can invite additional users later; opt-in setting lets every participant invite - Participants can leave group conversations (opt-in setting) - Subjects help identify group threads in the inbox - Full feature parity with DMs: file sharing, reactions, replies, voice / video calls, AI bots - AI chat bots can be added — they respond to `@botname` mentions ## How it works A user starts a new conversation, opens the recipient picker, and adds multiple users. Submit creates a single thread with all participants. Every participant sees every message in real time (WebSocket version) or with a short polling delay (free version, AJAX polling). | Action | Outcome | |---|---| | User starts a group conversation | All recipients added; the creator is registered as the thread moderator | | Moderator invites a new participant later | New user joins and sees the full thread history | | Participant leaves the conversation | Their access ends; thread continues for the others | | Moderator removes a participant | Same effect — their access ends | | New message arrives | All current participants get notifications | | Last participant leaves | Thread is empty — orphaned conversation, retained in the database | New participants get access to the full thread history when they're added (same model as email-thread invites). If you need a "joined-at-this-point" privacy model, use a chat room with the **auto-remove inactive participants** setting instead. ## When to use group conversations vs chat rooms | Use case | Better choice | |---|---| | Ad-hoc team discussion (project, decision) | **Group conversation** — short-lived, private to the participants | | Persistent space (community channel, support room) | **Chat room** — public/private with admin-set members or roles | | One-time announcement to many | **Mass messaging** (each gets a 1-on-1) | | Cohort study group | **Group conversation** or **chat room** depending on persistence needs | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Messaging**. - **Disable Group Conversations** — Toggle off if you want only 1-on-1 chats - **Allow Users to Leave** — Let participants leave group conversations - **Allow Inviting Users** — Let participants invite others to existing conversations Group conversations are **enabled by default**. ## Frequently asked questions ### Is there a maximum number of participants? No technical cap. Practical considerations: very large groups (100+ participants) work better as chat rooms with role-based access controls than as ad-hoc group conversations. ### Can participants see who else is in the group? Yes — the conversation header shows the participant list. To hide the list (e.g. for anonymity), override the relevant React templates via the standard plugin override pattern under your child theme. ### Do voice / video calls work in group conversations? Yes (WebSocket version) — see [group video chat](/docs/websocket/group-video-chat/) and [group audio chat](/docs/websocket/group-audio-chat/) for the technical details. Up to 32 video / 50 audio participants per call. ### Can I add an AI chat bot to a group conversation? Yes. AI bots are added like any participant. They respond when @-mentioned with their configured name — `@assistant What's the weather?`. See [AI chat bots](/docs/features/ai-chat-bots/). ### What happens when a user is removed from a group? The user loses access to the conversation immediately. They can no longer see new messages or send. Past messages remain in the conversation for the remaining participants. ## See also - [Chat rooms](/docs/features/chat-rooms/) — persistent public/private rooms with admin-set membership - [Group video chat](/docs/websocket/group-video-chat/) — up to 32 video participants - [Group audio chat](/docs/websocket/group-audio-chat/) — up to 50 voice participants - [WordPress group chat plugin blog post](/blog/wordpress-group-chat-plugin/) — feature overview - [Mass messaging](/docs/features/mass-messaging/) — broadcast as individual DMs --- ## Community Group Messaging — BuddyPress, PeepSo, UM, FluentCommunity # Community Group Messages Better Messages auto-creates a **shared chat thread for every community group** in BuddyPress, Ultimate Member, PeepSo, and FluentCommunity. When a user joins a group, they're added to the group's chat. When they leave, they're removed. Group admins get a built-in chat channel without any per-group configuration — turn it on once, every group gets messaging. ## What it adds - One conversation per community group, shared by all members - Automatic member sync — joining/leaving the group updates the chat membership - Works with **BuddyPress**, **Ultimate Member**, **PeepSo**, and **FluentCommunity** out of the box - Optional file sharing in group conversations (per integration) - Optional email notifications for group messages (per integration) - Full feature parity with other Better Messages threads (reactions, replies, etc.) ## How it works When the group-messaging integration is enabled for a community plugin, every existing and new group of that plugin gets a corresponding Better Messages thread. The plugin hooks into the community plugin's "user joined group" / "user left group" events to sync membership in real time. | Action in the community plugin | Outcome in Better Messages | |---|---| | User joins a BuddyPress / PeepSo / UM / Fluent group | Added to the group's chat thread | | User leaves a group | Removed from the group's chat thread | | Group is deleted | The chat thread is archived | | Group is renamed | Thread title updates to match | | User is banned from the group | Removed from the chat and blocked from rejoining | ## When to use group messaging vs ad-hoc group conversations | Pattern | Use case | |---|---| | **Group messaging** (auto-synced) | Tied to community plugin's group — best when membership is managed via the group plugin | | **Ad-hoc group conversations** | One-off discussions across users not in any specific group | | **Chat rooms** | Persistent public/private rooms with manual admin-set membership | For most community sites running BuddyPress/PeepSo/UM/Fluent, **group messaging** is the right tool — it leverages the existing group structure and avoids manual membership management. ## How to enable Navigate to **WP Admin → Better Messages → Settings → Integrations → [BuddyPress / Ultimate Member / PeepSo / FluentCommunity]**. - **Enable Group Messaging** — Turn on group conversations for the integration - **Enable File Sharing in Groups** — Allow attachments in group conversations - **Enable Email Notifications for Groups** — Send email notifications for group messages :::info The integration tab for each community plugin only appears when that plugin is installed and active. ::: ## Frequently asked questions ### Can I enable group messaging for only some groups, not all? Yes — most integrations expose a per-group toggle on the group's settings screen (where the group admin can opt the group in or out). Site admins can also use filters to enable conditionally — e.g., only "Public" BuddyPress groups. ### What happens when a user is removed from a group by the group admin? They're removed from the chat thread immediately. Past messages remain in the thread for the other members; the removed user no longer sees the thread in their inbox. ### Does this work for nested / subgroups? For platforms that support nested groups (BuddyPress with extension, PeepSo, BuddyBoss), each level has its own chat thread. Membership in a parent doesn't automatically grant access to a subgroup's chat — each level is independent. ### Can users invite outside-the-group people to the chat? No — membership is strictly synced from the community plugin. To extend the membership, the user must be added to the underlying group. ### Are AI chat bots supported in group chats? Yes — add the AI bot's user account to the community group, and it joins the chat thread automatically. It responds to `@bot` mentions like any other participant. ## See also - [Group conversations](/docs/features/group-conversations/) — ad-hoc multi-user threads (not tied to community groups) - [BuddyPress integration](/docs/integrations/buddypress/) — full BuddyPress integration details - [PeepSo integration](/docs/integrations/peepso/) — PeepSo integration details - [Ultimate Member integration](/docs/integrations/ultimate-member/) — UM integration details - [FluentCommunity integration](/docs/integrations/fluentcommunity/) — FluentCommunity integration details --- ## Guest Chat — WordPress Chat Without Login # Guest Access Better Messages supports **guest chat** — visitors who aren't logged into WordPress can join chat rooms, send messages, share files, and participate just like registered users, without creating an account. Guest access is enabled per chat room, so admins control exactly which rooms are open to the public and which are members-only. ## What it adds - Non-registered visitors can join enabled chat rooms with one click - Auto-generated display names (with optional "enter your name" prompt) - Guests get full feature access — messaging, file sharing, emoji, GIFs, voice messages (with the add-on) - Per-chat-room enablement (each room can be guest-allowed or members-only) - Optional global redirect: send non-logged-in users to the login page for any non-guest room - Guest sessions persist via browser localStorage + IndexedDB — guests reconnect to the same identity across page reloads on the same browser ## How it works When guest access is enabled on a room, the room's URL is publicly accessible. A first-time visitor sees a name prompt (or is auto-assigned a name if you've disabled the prompt). Better Messages registers a `bm_guests` row server-side and issues a 30-character secret token that the browser stores in localStorage and IndexedDB. Subsequent visits from the same browser restore the same guest identity by sending `BM-Guest-ID` and `BM-Guest-Secret` headers on every REST request. | Action | Outcome | |---|---| | Guest opens a guest-enabled room | Sees a name prompt (or is auto-named) | | Guest sends a message | Message appears with their display name | | Guest leaves the page | Session persists in localStorage — they rejoin as same identity | | Guest clears browser site data | Loses session — becomes a new guest on next visit | | Guest reaches a non-guest-enabled room | Sees a login prompt or is redirected (if redirect setting is on) | Guests share many features with logged-in users (file sharing, GIFs, emoji, oEmbed) but cannot create new threads, can only message inside the room they joined, and don't have a persistent profile. ## When to use guest chat | Use case | Pattern | |---|---| | Public help / live support chat room | Open guest access on the support room, redirect all other pages to login | | Event-day live chat | Time-limited guest room during a conference / launch | | Marketplace pre-purchase questions | Guest pre-sales channel, registration required to complete a purchase | | Open community board | A "Lobby" guest room visible to all, then members-only rooms behind login | | Public testimonials / Q&A | Guests ask, admins / verified members answer | ## How to enable **Global enable** — Navigate to **WP Admin → Better Messages → Settings → General**. - **Guest Chat** — Enable guest access globally (must be on for any room to allow guests) - **Redirect Non-Logged Users** — Optionally redirect guests away from non-guest pages to the login screen **Per chat room** — Edit a chat room at **WP Admin → Better Messages → Chat Rooms**. - Add guest users to the allowed participants list to permit guest access on that room ## Guest Messages Page The **Messages Location** setting picks where the messenger renders. Anything except a regular WordPress page is an integration-embedded location that lives inside a login-walled UI — WooCommerce My Account, BuddyPress / BuddyBoss / Ultimate Member / FluentCommunity / UsersWP / ProfileGrid / WP User Manager profile tabs, LearnPress / Tutor LMS / MasterStudy account pages, Houzez and RealHomes dashboards, Directorist / Classified Listings / Motors dashboards, Asgaros Forum profile, SureDash Portal. Without a separate entry point, a guest who clicks a chat trigger (Live Chat button, message link from an email, etc.) lands on a page they can't access and is redirected to login. When the Messages Location is not a regular WordPress page and **Guest Chat** is on, a second picker appears: **Guest Messages Page**. Pick (or create with one click) a regular public WordPress page; guests reach that page from every chat trigger and notification link. Logged-in users continue to use the integration-embedded inbox as before, but visiting the Guest Messages Page also renders the messenger for them, so the page is safe to share publicly. :::info The picker is hidden when the Messages Location is already a regular WordPress page — guests can use the same page as logged-in users and no second page is needed. ::: `Better_Messages()->functions->get_link()` returns the Guest Messages Page URL for anonymous visitors when the setting is configured, otherwise the WordPress login URL. ## Frequently asked questions ### Can guests choose their own display name? Yes — by default, guests are prompted to enter a name when they first join. You can disable the prompt and have the plugin auto-generate names (like "Guest 4827") in the global settings. ### How does the plugin prevent guest abuse / spam? - Per-role rate limits for new threads and replies apply to the synthetic **Guest** role (set the thresholds in **Settings → Rate Limits**) - The [bad-words filter](/docs/features/bad-words-filter/) applies to guests - [Pre-moderation](/docs/features/pre-moderation/) can hold guest messages for admin review - The [AI moderation](/docs/features/ai-content-moderation/) provider can flag or block harmful guest messages automatically - Admins can remove a guest from a chat room from the room's participant list - Captcha can be added before the name prompt via the `better_messages_guest_register_allowed` filter ### Does the user-to-user block feature work for guests? Guests can't initiate user-to-user blocks the way registered users can. Admins can still remove a guest from any room from the chat-room admin panel. ### Are guest conversations stored permanently? Yes — guest messages persist in the database like any other message. Auto-delete settings apply to guest messages too if configured. ### Can guests join voice / video calls? Yes — if the room has calls enabled, guests can join. Call quality and participant cap apply equally. ### Does GDPR apply to guest users? Yes — the `bm_guests` table stores a display name, the request IP, and an optional email. The 30-character session secret lives only in the visitor's localStorage / IndexedDB, never on the server side. WordPress's built-in Tools → Export Personal Data and Erase Personal Data routes also cover guest messages. See the [Privacy & GDPR doc](/docs/features/privacy-gdpr/) for the full picture. ## See also - [Chat rooms](/docs/features/chat-rooms/) — overview of public/private rooms - [Privacy & GDPR](/docs/features/privacy-gdpr/) — data handling for guests - [Guest chat blog post](/blog/wordpress-guest-chat-without-login/) — feature deep-dive - [Pre-moderation](/docs/features/pre-moderation/) — review guest messages before delivery - [Bad words filter](/docs/features/bad-words-filter/) — server-side profanity blocking --- ## Markdown Support in WordPress Chat # Markdown Support Better Messages renders standard Markdown syntax in chat messages — users can type `**bold**` or `*italic*` and the formatting appears automatically when the message sends. This works in private conversations, group chats, and chat rooms across the free and WebSocket versions, with no setup required. A chat message rendering bold, italic, strikethrough, inline code, links, and a bulleted list — all in a single bubble ## What it adds - Markdown syntax recognized in every conversation type — DMs, group chats, chat rooms - Live rendering when the message is sent (no preview toggle needed) - Pairs with the visual formatting toolbar — users pick whichever method they prefer - Identical rendering on the web app and the mobile app - No admin setting to configure — enabled by default ## Supported syntax | Markdown | Rendered | |---|---| | `**bold**` | **bold** | | `*italic*` | *italic* | | `~~strikethrough~~` | ~~strikethrough~~ | | `` `inline code` `` | `inline code` | | ```` ```code block``` ```` | a multi-line monospaced block | | `[link text](https://example.com)` | a clickable hyperlink | ## How it works When a message is rendered, the frontend converts the raw message body through the `marked` Markdown parser in the browser. The original syntax characters are stored in the database — editing a message lets you tweak the same `**bold**` source you typed. Re-rendering happens on the fly, so changes propagate instantly to anyone with the thread open. URL detection is applied to plain links too, so a user typing a bare `https://...` gets the same clickable result as the explicit `[link](url)` form. Code blocks suppress URL detection and emoji expansion, which keeps technical content readable. The visual toolbar wraps the selection in the same Markdown delimiters — clicking the **Bold** button inserts `**…**` exactly as a Markdown user would type it. ## When it's useful | Audience | Why Markdown helps | |---|---| | Developer / technical communities | Inline `code` and fenced code blocks make sharing snippets natural | | Course cohorts (LMS) | Bold and italic emphasis in study discussions without learning a UI | | Marketplace vendors | Quick price/SKU emphasis in product Q&A messages | | Mobile-app users | Markdown is faster than reaching for a toolbar on small screens | ## Frequently asked questions ### Can administrators disable Markdown rendering? Markdown is part of the core client-side message renderer. There is no separate "disable Markdown" toggle. If you need to transform message text before render, hook the PHP filter `bp_better_messages_pre_format_message` (or `bp_better_messages_after_format_message` for post-render HTML) to strip or rewrite messages before they reach the client. ### Does Markdown work in chat rooms? Yes. Markdown is rendered identically in private conversations, group chats, and public/private chat rooms. ### What happens if a user types Markdown that doesn't render correctly? Unrecognized syntax is preserved as plain text. For example, an unmatched `**bold` (with no closing `**`) will display the asterisks literally. The renderer is conservative — it never produces invalid HTML. ### Does Markdown render in email notifications? Yes — email notifications pre-render the same Markdown into HTML before sending. Bold, italic, and links render correctly in modern email clients. Inline code and code blocks render in a monospace style. Strikethrough may not display in some older email clients. ### Can I add my own Markdown extensions? The PHP filter `bp_better_messages_after_format_message` runs on every server-rendered message body and lets a theme or addon transform the message before it is broadcast to clients. This is the supported way to add custom transformations (footnotes, callouts, internal-link rewriting, etc.). ## See also - [WordPress chat plugin overview](/docs/getting-started/about/) — the canonical "What is Better Messages?" page - [oEmbed support](/docs/features/oembed-support/) — auto-render YouTube / X / SoundCloud embeds in messages - [Stickers](/docs/features/stickers/) — pre-built sticker packs for non-text expression - [REST API for developers](/blog/wordpress-chat-rest-api-developers/) — programmatic message rendering --- ## Mass Messaging in WordPress — Broadcast to All Users # Mass Messaging Administrators can send a **broadcast message** from the WordPress admin to every registered user, or to specific roles. Each recipient receives the message as an **individual private conversation**, so replies route to the sender only — not to the whole audience. Useful for site-wide announcements, policy changes, paid-tier updates, course-cohort notices, or re-engagement nudges. ## What it adds - One admin form sends to all users, specific WordPress roles, or a hand-picked list of users - Each recipient gets a 1-on-1 conversation in their inbox (not a giant group chat) - Replies route privately to the admin sender — or can be disabled per job to make the broadcast one-way - Schedule a job for a future date / time, pause it mid-run, resume it, or cancel - Preview the recipient list and final message before starting - Send a test to yourself first to sanity-check formatting and attachments - Chained **follow-up** jobs — send a follow-up only to threads from a previous broadcast (with the option to also include any new users that match the audience since then) - Background-processed job handles large recipient lists without blocking the request - Standard notification channels apply: in-app, email, mobile push - No additional plugin required — built into Better Messages core ## How it works When the admin submits the mass-messaging form, Better Messages stores the job and queues a background worker that iterates over the target user list. For each user it ensures a 1-on-1 thread exists between admin and recipient and posts the broadcast text as a new message. Recipients see a normal DM in their inbox — same UI, same notification rules, same reply behavior (unless replies were disabled on this job). | Action | Outcome | |---|---| | Admin types message + picks audience ("All", role list, or specific users) | Job is created — runs immediately, or waits for the scheduled time | | Admin selects specific roles | Worker iterates only users in those roles | | Recipient sees the message | Appears as a regular DM from the admin | | Recipient replies (replies enabled) | Reply lands in the admin's inbox as a normal DM | | Recipient replies (replies disabled) | The thread shows the broadcast only; the reply box is locked with a notice | | Recipient already has a thread with admin | New message lands in that existing thread (no duplicate) | | Admin clicks Pause / Resume / Cancel | Worker honors the state change on the next batch | ## When to use | Use case | Recipients | |---|---| | Site-wide outage / policy update | All users | | Premium-only feature announcement | "Pro Member" role | | Course cohort announcement | Custom role for the cohort | | Staff-only message | Editor + Administrator + Shop Manager | | Re-engagement of free tier | "Subscriber" role | For event-triggered DMs (sent automatically on signup / course completion / payment), use [AutomatorWP](/docs/integrations/automatorwp/) or [Uncanny Automator](/docs/integrations/uncanny-automator/) instead — those send DMs in response to user actions, not as one-time broadcasts. ## How to use Navigate to **WP Admin → Better Messages → Mass Messaging**. 1. Enter the message content using the full message editor (formatting, attachments, emojis, GIFs all supported) 2. Choose your audience: **All users**, **specific WordPress roles**, or a **hand-picked list of users** 3. Optionally toggle **Disable replies** to make this a one-way broadcast 4. Optionally set a **scheduled send time** instead of running immediately 5. Optionally **Send Test** to yourself first 6. **Preview** the audience count and final message 7. Click **Create** — the job runs in the background You can monitor progress on the same page (pending / in-progress / done / paused / cancelled), and from any completed job spin off a **follow-up** message into the same set of threads. ## Frequently asked questions ### Is there a maximum number of recipients? There's no hard cap. Large lists (tens of thousands) work fine on a healthy site. For sites in the hundreds of thousands of users, contact support to discuss tuning the batch worker. ### Will recipients see who else received the broadcast? No — each recipient sees a 1-on-1 conversation with the admin. There's no "this was also sent to N users" indicator. The privacy boundary is identical to a normal DM. ### Can I personalize the message with each user's name? The default UI does not include token substitution like `` `{first_name}` `` (the same message body is sent to every recipient). For richer per-user personalization, trigger DMs via [AutomatorWP](/docs/integrations/automatorwp/) — Automator recipes can substitute user tokens per recipient. ### Can I schedule a broadcast for later? Yes. The job form includes a **Scheduled send time** field; the worker activates the job when that time is reached. You can also pause a running job and resume it later. ### What happens to a recipient who already has a thread with the admin? The broadcast lands as a new message in the existing thread rather than creating a duplicate. The recipient's full conversation history is preserved. ### What does the "follow-up" option do? From any completed broadcast you can create a follow-up job that posts a new message into the threads from the parent job. You can choose to send only to the original recipients, or to also include any new users that have matched the audience since the parent job ran. Follow-ups can themselves be followed up, so you can run multi-touch sequences from the admin without writing any code. ### How does this interact with email + push notifications? Each recipient receives the same notification treatment as a regular DM — in-app, the standard email notification batch, and mobile push if configured. ## See also - [Mass messaging blog post](/blog/wordpress-mass-messaging-broadcast/) — full feature write-up with examples - [AutomatorWP integration](/docs/integrations/automatorwp/) — for event-triggered automated DMs - [Uncanny Automator integration](/docs/integrations/uncanny-automator/) — for event-triggered automated DMs - [Email notifications](/docs/features/email-notifications/) — how mass-message emails are sent - [Role-based access](/docs/features/role-based-access/) — define the roles you target --- ## Maximum Message Length in WordPress Chat # Maximum Message Length Better Messages can **cap how long a single message is allowed to be**. When set, the composer shows a live character counter as users approach the limit and prevents sending messages that exceed it. Server-side enforcement ensures the limit is never bypassed by a custom client or API call. ## What it adds - Configurable per-message character limit, site-wide - Live counter that appears in the composer at 80% of the limit - Counter turns red and Send button is disabled when the limit is exceeded - Tooltip explains the limit on hover - Server-side enforcement via REST — over-limit messages rejected with a clear error - Applies to both new messages and edits - Emoji-aware counting — family emojis (👨‍👩‍👧), skin-tone variants (👍🏽), country flags (🇺🇸) count as one character each ## How it works Set a maximum number of characters in **Settings → Messaging → Maximum Message Length**. As soon as a user crosses 80% of the configured limit, a small counter appears in the composer next to the Send button. When the message goes over the limit: | State | UI behavior | |---|---| | < 80% of limit | No counter shown (clean UI) | | 80–100% of limit | Counter appears, showing used / total | | Over the limit | Counter turns red, Send button disabled | | User trims to under limit | Counter returns to neutral, Send button re-enabled | The limit is enforced on **both client and server** — client UI is fast feedback, server-side REST validation is the real guard. Bypass attempts via custom clients fail with a localized error response. Each grapheme counts as one character — including complex sequences: | Emoji | Counts as | |---|---| | 😀 | 1 character | | 👍🏽 (skin-tone) | 1 character | | 👨‍👩‍👧 (family ZWJ sequence) | 1 character | | 🇺🇸 (country flag) | 1 character | | `bold` | 4 characters ("bold") — HTML not counted | Attached files and image embeds don't count — only visible text contributes to length. Maximum Message Length setting in the admin Messaging tab Composer with the live character counter shown in red when the message exceeds the configured limit ## When to set a limit | Use case | Suggested limit | |---|---| | SMS-style brevity | 160 characters | | Twitter-style chat | 280 characters | | Forum-style discussion | 5,000 characters | | Long-form coaching / consulting messages | 20,000 characters | | Anti-spam baseline | 10,000 characters (catches dump-style spam) | | Uncapped (default) | `0` | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Messaging**. - **Maximum Message Length** — Maximum number of characters allowed (set to `0` for no limit) ## Frequently asked questions ### Can different roles have different limits? Not in the default UI — the setting is a single site-wide cap. Per-role limits are not exposed as a built-in option today; contact support if your site needs that pattern. ### What about messages that were already over the limit before I enabled this? Pre-existing messages are unaffected — only NEW sends and edits are validated. Editing an old over-limit message would force the user to trim it. ### Does the counter handle right-to-left languages correctly? Yes — character counting is direction-agnostic. The counter appears in the same place regardless of script direction. ### Is the limit shared across the message text and any attached caption? The limit applies to the message text only. File attachments and their auto-generated captions don't count. ### Can the limit be bypassed via the REST API? No — server-side validation rejects over-limit requests. The client UI is convenience; the server is the source of truth. ## See also - [Text formatting](/docs/features/text-formatting/) — formatted text counts the same as plain - [Markdown support](/docs/features/markdown-support/) — Markdown syntax is part of the rendered text - [Pre-moderation](/docs/features/pre-moderation/) — hold long suspicious messages for review - [Bad words filter](/docs/features/bad-words-filter/) — additional message-content checks --- ## @Mentions in WordPress Chat # @Mentions Better Messages supports **`@` mentions** in every conversation — type `@`, pick a participant from the autocomplete dropdown, and that user's name is highlighted in the message + they get a priority notification. The Slack / Discord / community-platform standard, built into every Better Messages thread. A group conversation where James mentions Sarah with an @Sarah Chen pill showing her avatar, and Sarah replies with an @James Rivera pill — both rendered as clickable mention chips ## What it adds - Type `@` to open the mention autocomplete picker - Live-filtered dropdown showing matching participants from the conversation - Mentioned users get a per-thread "mentions" badge in their inbox, on top of normal unread counts - Mentioned text is visually highlighted in the rendered message - Mention picker shows user avatars and online-presence dots (WebSocket version) - Each mention is a clickable link to the user's profile ## How it works When the user types `@` in the message input, an inline picker appears. As they keep typing, the picker filters participants whose name or username matches the input. Tab or click to insert — the user is added to the message as a mention token tied to the user's ID. | Action | Outcome | |---|---| | User types `@an` | Picker shows participants whose name starts with "an" (Anna, Andy, etc.) | | User selects "Anna" | Message text becomes "Hi @Anna, ..." with Anna's name highlighted | | Message sends | Anna's inbox shows a mention badge in addition to the unread count | | Anna clicks the mention | She's taken to her profile page | | Anna opens the conversation | The mention is cleared on read | The mention token stores the user ID, so renaming a user later still resolves correctly. Display text uses the user's current display name. ## When mentions matter most | Scenario | Why mentions help | |---|---| | Large group chat | Direct addresses cut through the noise — only the mentioned person is alerted | | Community announcements | Tag specific contributors for follow-up | | Bug-triage threads | Tag the developer responsible for a specific area | | LMS discussions | Tag the instructor when a question needs their input | | Cross-team coordination | Tag specific people across teams to pull them into a thread | ## How to enable Mentions are **enabled by default**. No setting to flip — the feature is built into the message input. ### Force notify on @-mention To ensure mentioned users are alerted even when they've muted the conversation, turn on **Settings → Messaging → Force mentions notifications**. With that switched on, an `@`-mention bypasses the mute on a per-message basis — useful for community managers reaching specific people in noisy threads. ## Frequently asked questions ### Can I mention everyone in a conversation with @everyone? Not in the default UI — only individual users can be mentioned. A global `@everyone` / `@channel` token isn't part of the picker today. ### Can users mention themselves? Yes — but no mention badge is set for the sender (you don't notify yourself). Useful for highlighting your own past comments by reference. ### What happens if I mention someone who isn't in the conversation? The picker only shows current participants, so this normally can't happen. ### Can I mention AI bots? Yes — `@bot` mentions trigger the AI bot to respond. In a 1-on-1 conversation the bot already replies to every message; in a group conversation it only replies when explicitly `@`-mentioned (to avoid spamming the group). ## See also - [Group conversations](/docs/features/group-conversations/) — where mentions are most useful - [AI chat bots](/docs/features/ai-chat-bots/) — bot invocation via @-mention - [Conversation muting](/docs/features/conversations-muting/) — context for the "force notify" override - [Notifications](/docs/features/site-notifications/) — overview of notification channels --- ## Auto-Save Message Drafts in WordPress Chat # Message Drafts Better Messages **auto-saves unsent message text** as the user types and restores it the next time they open the same conversation — across page reloads, browser restarts, and (for logged-in users) different devices. Users never lose a long reply because they navigated away mid-compose. ## What it adds - Continuous auto-save as the user types — no manual "save draft" button - Per-conversation drafts (each thread has its own independent draft) - Restored automatically when the user returns to the conversation - Survives page reload, browser close, accidental navigation - For logged-in users, drafts sync to the database so they restore on any device - For guests, drafts persist in browser storage on the same device ## How it works The plugin debounces draft saves — text is persisted to the server every ~2 seconds while typing stops. The save is silent (no spinner, no toast), but visible in browser DevTools as a small REST call. | User action | Outcome | |---|---| | Types in the message input | Draft auto-saves after a brief pause | | Sends the message | Draft is cleared from storage | | Navigates away mid-compose | Draft stays in storage | | Returns to the same conversation later | Draft text restored in the input field | | Logs in on a different device | Draft is fetched and restored from the server | | Closes the browser without sending | Draft survives — restored next session | If the user starts typing in the same conversation from a second device after the first device saved a draft, the most recent draft wins (last-write semantics). ## When it matters most | Audience | Why drafts help | |---|---| | Mobile-app users typing long replies | Easy to navigate away accidentally — draft prevents loss | | Support / vendor reps composing detailed answers | Multi-paragraph replies often interrupted by other tasks | | Multi-device users (desktop + phone) | Start a reply on phone, finish on desktop | | Long-form announcement messages | Admin can refine content over several sessions before sending | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Messaging**. - **Enable Drafts** — Toggle auto-save on or off Drafts are enabled by default. Disabling clears any existing drafts and prevents new ones from being saved. ## Frequently asked questions ### Does the draft include attached files? No — only text drafts are persisted. Files attached but not yet sent are not part of the draft. The user re-attaches if they return later. ### How long are drafts kept? Drafts persist until the user sends the message OR explicitly clears the input. There's no time-based expiration. Old drafts in unused conversations stay indefinitely. ### Can admins see other users' drafts? No. Drafts are private to the authoring user. No admin UI exposes them, and they're not visible through any other user's session. ### What happens if a user is blocked while composing a draft? The draft remains, but when the user tries to send, the block is enforced and the message is rejected. The draft can be cleared manually. ### Do drafts work in guest conversations? Yes, but drafts persist only on the same browser/device (localStorage), since guests don't have a server-side account to sync against. ## See also - [Message reactions](/docs/features/message-reactions/) — interact with messages - [Reply, edit, forward](/docs/features/reply-edit-forward/) — message-level actions - [Pre-moderation](/docs/features/pre-moderation/) — review messages before they land in recipient inboxes - [Auto-delete messages](/docs/features/auto-delete-messages/) — message lifecycle management --- ## Emoji Message Reactions in WordPress Chat # Message Reactions Better Messages supports **emoji reactions on messages** — the Slack / Discord / WhatsApp pattern where you click a reaction button to acknowledge or respond to a message without sending a full reply. Reactions reduce notification noise in busy threads and make group conversations feel more alive. A group chat with the reaction picker open above a message, and reaction count badges visible under several other messages ## What it adds - Tap-to-react button on every message - Multiple users can react with the same or different emojis - Reaction count badge below each message (e.g., 👍 5, ❤️ 2) - Click a reaction badge to see exactly which users reacted with that emoji - Customizable reaction emoji set — admins choose which emojis are available - Drag-and-drop reordering of the available reaction set in admin ## How it works When a user clicks the reaction button on a message, a small picker appears with the configured emoji set. Selecting an emoji adds a reaction record `(user, message, emoji)` to the database. Reactions are surfaced as small badges under the message body. | Action | Outcome | |---|---| | User clicks 👍 on a message | Their reaction appears as a 👍 badge | | Another user also clicks 👍 | Badge count increments to "👍 2" | | First user clicks 👍 again | Their reaction toggles off — count drops to "👍 1" | | User clicks the badge | Popup lists every user who reacted with that emoji | | Sender deletes the message | All reactions on that message are removed | Reactions are real-time on the WebSocket version (instant updates for all participants); on the free version, they appear after the next poll. ## When reactions help | Scenario | Why reactions matter | |---|---| | Busy group chat | Acknowledge a message without flooding the thread with "👍 thanks!" replies | | Community announcements | Members react to show interest without long comment threads | | Marketplace order chat | Vendor reacts ✓ to confirm receipt of buyer's address without typing | | Course discussion | Students react 💡 to mark "great explanation" — useful for instructor signal | | Support chat | Quick ✓ or ❌ for resolved / not-resolved status | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Messaging**. - **Enable Reactions** — Turn message reactions on or off - **Who Reacted Popup** — Show a popup listing reacting users when a badge is clicked - **Reaction Emojis** — Customize the available reaction set with drag-and-drop ordering ## Frequently asked questions ### Can users react with any emoji, or only the admin-defined set? Only the admin-defined set is exposed in the reaction picker. To change the available reactions, edit the **Reaction Emojis** list under **Settings → Messaging** — drag to reorder, click `+` to add, click `−` to remove. ### How many emojis can be in the reaction set? There's no hard cap, but for usability a curated 5–8 emoji set keeps the picker fast and the badges scannable. Long lists become harder to choose from quickly. ### Do reactions count as messages for notification purposes? No — reactions don't trigger sound, push, or email notifications. They're a low-friction signal by design. ### Are reactions translated for different locales? The emoji characters themselves are universal. The "Who reacted" popup labels are translatable through your WordPress translation tool. ### Can I export or analyze reaction data? Yes — the `bm_reactions` table is queryable. Common analyses: most-reacted messages, most-active reactors, reaction trends over time. Useful for community engagement reporting. ## See also - [Emoji selector](/docs/features/emoji-selector/) — full emoji picker for messages (different from reactions) - [Stickers](/docs/features/stickers/) — larger pre-built sticker packs as message bodies - [GIPHY integration](/docs/features/giphy-integration/) — animated GIF picker - [Reply, edit, forward](/docs/features/reply-edit-forward/) — other message-level actions --- ## Mini Chat Widgets for WordPress # Mini Widgets Better Messages provides **mini chat widgets** fixed to the bottom of the screen — giving users quick access to conversations, friends, groups, courses, AI bots, and chat rooms from anywhere on the site. Two display styles available: **Classic Bar** (tab bar at the bottom) or **Floating Bubble** (Intercom-style circular button). The mini widget floating on a regular WordPress page — the Conversations panel is open in the bottom-right corner, showing the six-tab navigation and a list of recent threads with avatars ## How it works Mini widgets are small panels anchored to the bottom of the browser window that remain visible as users browse your website. They provide quick access to conversations, friends lists, and group lists without navigating to the main messaging page. Each widget type can be independently enabled and restricted by user role. ## Available widgets Better Messages 2.15+ ships seven widget types, each with its own settings panel: - **Conversations** — compact list of recent conversations with unread counts - **Friends** — list of friends with online status (requires BuddyPress, Ultimate Member, or PeepSo) - **Groups** — list of social groups with quick access to group conversations (requires BuddyPress, Ultimate Member, PeepSo, or FluentCommunity Spaces) - **Courses** — list of courses the user is enrolled in or instructs (requires Tutor LMS, LearnPress, or LearnDash). LearnDash Group cohorts also appear here, alongside the actual courses - **Users** — browse and message any site member; optional online-only filtering, online-first ordering, sort by last activity or registration date, and three display modes (all users, by role, or a hand-picked list) - **AI Bots** — start or continue conversations with configured AI chat bots; supports "all enabled bots" or a curated subset - **Chat Rooms** — browse public chat rooms with an optional online-count badge ## Key capabilities - Three placement surfaces per widget — **Mini Bar** (bottom of screen), **Side Panel**, and **Mobile Bar** — each independently toggleable and role-restrictable - Two display styles for the Mini Bar: **Classic Bar** (tab bar at the bottom) or **Floating Bubble** (circular button that expands into a panel) - Custom Bubble Icon — choose from preset icons or paste your own SVG - Per-widget icon picker — customize the icon shown on the Mini, Side Panel, and Mobile bars - Per-widget Search Box toggle — show or hide the inline search field above each list - "Hide Tab When Empty" — hide the Friends / Groups / Courses / AI Bots / Chat Rooms / Users tab entirely when the current user has nothing to show, instead of rendering an empty list - Smooth open/close animations (toggleable) - Close button for each widget - Role-based visibility restrictions per placement - Customizable widget display order (drag-and-drop) - Points balance display when a points system (MyCred/GamiPress) is configured - Works alongside other page content :::note **Mini Chats** (popup chat windows), **Combined Mini Chat** widget, and **Bubble Chat Heads** require the [WebSocket version](/docs/websocket/mini-chats/). ::: ## Display Styles Better Messages supports two ways of displaying mini widgets: ### Classic Bar A tab bar fixed to the bottom of the browser window. Clicking a tab expands the corresponding panel above it. This is the traditional layout used in messaging widgets. ### Floating Bubble A circular floating button anchored to the corner of the screen, similar to chat widgets used by services like Intercom and Messenger. Clicking the bubble expands it into a chat panel. The bubble icon can be customized from a curated set of preset icons or by pasting custom SVG markup. ## How to enable Navigate to **WP Admin** → **Better Messages** → **Settings** → **Mini Widgets**. The Mini Widgets settings page is split into per-widget sub-tabs: - **Layout** — top-level layout options: Mini Bar display style (Classic Bar or Floating Bubble), Bubble Icon picker, animations, Side Panel and Mobile Bar enable toggles, drag-and-drop ordering of widgets within each placement, and the Mini Chats / Combined Chats / Bubble Chat Heads switches - **Conversations / Friends / Groups / Courses / AI Bots / Chat Rooms / Users** — one sub-tab per widget. Each exposes the widget's icon, the "Hide Tab When Empty" and "Show Search Box" toggles, role restrictions for the Mini / Side Panel / Mobile placements, and any widget-specific settings (e.g. display mode, online filtering, hand-picked lists) ## Customization The bubble button and chat heads can be customized via **WP Admin** → **Appearance** → **Customize** → **Better Messages** → **Mini Widgets & Mini Chats**: - Bubble Button Size — diameter of the floating bubble button (40–80px) - Bubble Button Roundness — border radius of the bubble (0% for square, 50% for circle) - Chat Head Size — diameter of recently closed chat avatar bubbles (30–70px) - Chat Head Roundness — border radius of chat heads - Mini widgets position — left or right side of the screen ## Frequently asked questions ### Can I hide the mini widget on specific pages? Yes — the per-widget role restrictions handle most cases (e.g. hide for guests). To hide every widget on specific pages (checkout, immersive course videos, etc.), add custom CSS scoped to those pages that targets the mini-widget container. ### Does the bubble icon support animated GIFs or only static images? The Bubble Icon picker accepts SVG markup. For animated icons, use animated SVG (works in all modern browsers). GIFs aren't supported in the icon slot. ### Are mini widgets visible to guest users? Yes — guests see the widget if guest chat is enabled. Use the role-based visibility settings to restrict if needed (e.g., hide for guests to encourage sign-up). ### How does the Floating Bubble interact with other sticky elements? Position the bubble (left/right) and tune the bottom margin to avoid overlap with cookie banners, live-chat plugins, or sticky footers. Test on mobile and desktop separately. ### Does the AI Bots widget work on the free version? The widget itself works on both versions, but AI Chat Bots is a WebSocket-version feature — clicking through to a bot conversation requires the upgraded version. ## See also - [WordPress chat widget blog post](/blog/wordpress-chat-widget-mini-widgets/) — feature deep-dive - [Mini chats (WebSocket)](/docs/websocket/mini-chats/) — popup chat windows that pair with mini widgets - [Floating chat / mini chats blog post](/blog/floating-chat-mini-chats-wordpress/) — UX overview - [Easy customization](/docs/features/easy-customization/) — visual customization options - [Enhanced mobile](/docs/features/enhanced-mobile/) — mobile-specific behaviors --- ## Modern Chat Design in WordPress # Modern Design Better Messages ships with a **modern, mobile-first interface** that fits naturally into any WordPress theme. Pick the layout template, align message bubbles, enable full-screen mode for desktop power users, and tune dimensions to match your design. The result feels like a native chat app — not a bolted-on plugin. ## What it adds - Modern message bubble layout with configurable alignment (own messages left, right, or all-left) - Combined view — conversation list and active conversation visible side-by-side on desktop - Full-screen mode — immersive chat experience that uses the full viewport - Customizable accent color from the WordPress Customizer - Configurable message area height, min-height, and sidebar width - Fully responsive — adapts to phone, tablet, and desktop without dead zones ## How it works Better Messages includes two templates — **Standard** and **Modern**. Both share 100% of the functionality but render differently. | Template | Visual character | Best for | |---|---|---| | **Standard** | Classic two-column inbox + thread, traditional WordPress feel | Sites with existing chrome around the chat | | **Modern** | Mobile-first, message-app aesthetic, full-bleed bubbles | Standalone chat pages, social network feel | In the Modern template, you can further configure: | Setting | Effect | |---|---| | **Modern Layout: left** | Both own and others' messages align left (chat-log style) | | **Modern Layout: right** | Own messages right-aligned, others left (iMessage-style) — default | | **Modern Layout: all-left** | Everything left, with sender avatar (Slack/Discord-style) | | **Combined View** | Inbox sidebar + open thread side-by-side on desktop | | **Desktop Full Screen** | Full-screen toggle button — chat fills the viewport | ## When to choose each style | Site type | Recommended setup | |---|---| | Social network | Modern template, right-aligned (iMessage feel) | | Slack-style community | Modern, all-left with avatars | | Marketplace messaging | Standard or Modern with Combined View — inbox always visible | | Standalone chat app | Modern + Full-Screen Mode + Combined View | | LMS / training site | Standard — fits within course content areas | ## How to enable Navigate to **WP Admin → Better Messages → Settings → General**. - **Template** — Standard or Modern - **Modern Layout** — Message bubble alignment (Left / Right / All Left) - **Combined View** — Show conversation list alongside active conversation - **Desktop Full Screen** — Add a full-screen toggle button to the messenger - **Messages Height** — Height of the message area (default 650px) - **Messages Min Height** — Minimum height (default 450px) - **Side Threads Width** — Conversation list sidebar width (default 320px) For accent color: **WP Admin → Appearance → Customize → Better Messages**. ## Frequently asked questions ### Can I switch templates without losing data? Yes — switching is a visual setting only. Messages, threads, and all data are template-agnostic. Switch back and forth freely. ### Does the Modern template work on older browsers? Yes — the Modern template uses standard CSS (flexbox, grid). Works on all browsers released in the last 5 years. Older IE versions are not supported but represent a vanishing user base. ### Can I have different layouts on different pages? The template is site-wide, but you can use [shortcodes](/docs/category/shortcodes/) like `[better_messages_single_conversation]` to embed a customized view in specific pages. ### How does the design adapt to mobile? On narrow viewports (around 800px and below), the layout collapses to a single-column view — the conversation list slides over the thread, similar to iMessage / WhatsApp. The Combined View setting is ignored on mobile. ### Can I override the design with custom CSS? Yes — all UI surfaces have stable class names. Use **Appearance → Customize → Additional CSS** for theme-scoped overrides. ## See also - [Easy customization](/docs/features/easy-customization/) — color picker + custom CSS - [White label](/docs/features/white-label/) — hide all plugin branding - [Mini widgets](/docs/features/mini-widgets/) — embedded chat surfaces (counters, buttons) - [Mobile app](/docs/category/mobile-app/) — native iOS / Android with consistent design --- ## Pay-to-Message with MyCred and GamiPress # Pay-to-Message via MyCred / GamiPress Better Messages integrates with the two leading WordPress point systems — **[MyCred](https://www.wordplus.org/mc)** and **[GamiPress](https://www.wordplus.org/gamipress)** — to charge users points for sending messages, starting new conversations, or placing voice/video calls. Pricing is per-role, so free-tier members might pay more (or be blocked) while paid-tier members message for free. Useful for monetized communities, paid expert advice platforms, and gamified engagement. Better Messages Points Systems settings — GamiPress provider selected with per-role New Message Pricing grid populated ## What it adds - Charge points **per message sent** - Charge points **per new conversation started** - Charge points **per call minute** of voice/video call duration - Per-role pricing — different rates for free / pro / admin - Per-conversation-type charging — private threads, groups, and chat rooms can be priced independently - Inline balance display in the messenger — up to six placements - Custom error messages when a user's balance is insufficient - Works identically with MyCred or GamiPress (pick whichever you already use) - Real-time balance check — message blocked before send if balance is too low ## How it works When a user submits a message, Better Messages queries the user's point balance from MyCred or GamiPress (whichever is configured). If the role's configured cost is less than or equal to the balance, the message sends and the cost is deducted via the `charge_for_message` action. If not, the send is rejected and the configured **Insufficient Balance Message** is shown. | Action | Outcome | |---|---| | User sends message in existing thread | "New Message Pricing" deducted; message sends | | User starts a new conversation | "New Conversation Pricing" deducted; thread cost applies in addition to the per-message cost | | User places a voice or video call | "Private Call Pricing" deducts per minute of confirmed call traffic; first minute charged at start | | User's balance drops below one more minute mid-call | Call ends gracefully with the configured **Insufficient Balance During Call** message; no charge taken for the partial minute | | User has insufficient balance to start a message | Send blocked; user sees the configured error | | Admin sends a message | Bypassed by default if admin's role has 0 cost configured | Per-role pricing means a "Subscriber" role might pay 10 points per message while a "Premium" role pays 0 — implementing a paid-messaging upsell directly in the chat UX. ## Same UI on both providers GamiPress and MyCred share a single Points System UI in **Better Messages → Settings → Integrations → Points Systems**. Switching providers swaps the per-role pricing tables, log entry tags, and balance integration — the structure of the settings panel stays identical. Better Messages Points Systems settings — MyCred provider selected with the same per-role New Message Pricing grid and MyCred-specific log entry tags ## Per-call billing Voice and video calls are priced separately under **Private Call Pricing**. The rate is **per call minute** (not per call), with the first minute charged immediately when the call connects. If the caller can't afford one minute up front, the call is blocked with the **Cannot Start Call Message**. Private Call Pricing section — per-role per-minute rates for voice and video calls, with Cannot Start Call and Insufficient Balance During Call messages :::info Per-call billing requires the **WebSocket version** — voice and video calls are not available in the free (AJAX) version. ::: ## Balance display in the messenger The user's current balance can be shown inline inside the messenger in up to six placements (toggled in the **Balance Display** section): in the conversations header, above or below the conversations list, in the user menu and its popup, and inside the reply form. Each placement is an independent toggle and the balance number links to a configurable **Balance Page URL** (typically a WooCommerce points-top-up product or a custom checkout). Messenger UI showing the user balance pill in the user menu (bottom-left) and inside the reply form area (next to the message input) ## When to use it | Use case | Pattern | |---|---| | Expert consultation platform | Charge users to message verified experts; experts message free | | Fan / creator community | Fans pay to DM the creator; creator replies free | | Premium content gating | Pay to start a conversation about a paid resource | | Engagement gamification | Cost is symbolic (1 point) — users earn points via activity, spend on messaging | | Limit messaging on free tier | Free users get N messages/day from earned points; paid users unlimited | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Integrations → Points Systems** and select either MyCred or GamiPress as the Points Provider. - **Point Type** — which point type (from your points engine) to charge against - **New Message Pricing** — per-role cost to send a message - **New Conversation Pricing** — per-role cost to start a new conversation - **Private Call Pricing** — per-role cost per minute of voice or video call (WebSocket version) - **Conversation Types** — which contexts the charge applies to (Private Conversations / Chat Rooms / Group Chats) - **Insufficient Balance Message** — custom text shown when a user lacks points - **Balance Display** — six toggles to surface the balance pill inside the messenger - **Balance Page URL** — where the balance pill links to (top-up product or checkout) :::info The MyCred or GamiPress integration only appears when the respective plugin is installed and active. AI Chat Bots have their own per-bot pricing — general message/conversation pricing is automatically excluded for AI bot conversations. ::: ## Frequently asked questions ### Can users see their current point balance inside the messenger? Yes — balance display is built into Better Messages with up to six placements (Chat header, threads list top, threads list bottom, user menu, user menu popup, reply form area). Toggle them under **Balance Display** and set the **Balance Page URL** to a checkout or top-up product to make the balance pill clickable. ### How is per-call billing handled mid-call? The first minute is charged at call start (the `check_call_balance` filter blocks the call if the caller can't afford that minute). Then `charge_call_usage` runs once per confirmed minute. If the balance drops below one more minute, the call ends gracefully with the **Insufficient Balance During Call** message — no charge is taken for the partial minute that would have pushed the balance negative. ### Does the cost apply to AI bot replies? No. The cost applies to the **user's outgoing message**, not the bot's reply. Users pay to ASK; the AI's response is free of point-cost. AI Chat Bots additionally have their own per-bot pricing configuration that overrides the general per-message rate inside AI bot conversations. ### Can group conversations have different costs from private threads? Yes. The **Conversation Types** checkbox set under each charge type (New Message / New Conversation) lets you enable charging only in selected contexts — Private Conversations, Chat Rooms, or Group Chats. A typical monetized-DM configuration enables charging only on Private Conversations so group chatter stays free. ### Will the point cost prevent guest messaging? Guests don't have point accounts, so they aren't charged — the per-role grid includes a separate Guests row that you can set independently (typically 0 to allow them, or block them via the [role-based access](/docs/features/role-based-access/) settings). ## See also - [GamiPress integration page](/docs/integrations/gamipress/) — provider-specific integration reference - [MyCred integration page](/docs/integrations/mycred/) — provider-specific integration reference - [Build a monetized DM platform](/blog/wordpress-monetized-messaging-platform/) — full vertical walk-through with per-message + per-call + balance-display setup - [GamiPress pay-to-message blog post](/blog/gamipress-pay-to-message/) - [MyCred pay-to-message blog post](/blog/mycred-pay-to-message/) - [Role-based access](/docs/features/role-based-access/) — per-role permission setup - [AI Chat Bots](/docs/features/ai-chat-bots/) — per-bot AI-reply pricing --- ## oEmbed Rich Link Previews in WordPress Chat # oEmbed Support Better Messages **auto-embeds rich media** when users paste a supported URL into a message — YouTube and Vimeo become inline video players, SoundCloud and Spotify embed audio, and any URL from WordPress's oEmbed provider list renders as a native widget. For regular non-oEmbed URLs, the plugin generates **"nice link" preview cards** with thumbnail, title, and description, so shared links look like rich attachments instead of bare URLs. A YouTube link pasted into a chat message rendering as an inline video player inside the conversation thread ## What it adds - Auto-embed inline media when a supported URL appears in a message - Native players for YouTube, Vimeo, SoundCloud, Spotify, Twitch, Twitter / X, TikTok, Reddit, Imgur, Flickr, and every other WordPress oEmbed provider - "Nice link" preview cards (thumbnail + title + description) for regular URLs - Media plays inline without leaving the conversation - Works in DMs, group chats, and chat rooms — same rendering everywhere ## How it works When a user submits a message, Better Messages scans the text for URLs. For each URL: 1. **Check oEmbed providers** — if the host matches an oEmbed-supporting service (YouTube, Vimeo, etc.), an embed iframe is rendered inline 2. **If not oEmbed, fetch metadata** — for regular URLs, the plugin requests the page and parses OpenGraph + Twitter Card metadata to build a "nice link" card 3. **Cache the result** — fetched metadata is cached in `wp_options` for 24 hours, so the same link doesn't re-fetch on every render 4. **Render in the bubble** — the embed or card appears below the message text | URL type | Rendered as | |---|---| | `youtube.com/watch?v=...` | Inline YouTube player | | `vimeo.com/12345` | Inline Vimeo player | | `soundcloud.com/.../track` | Inline SoundCloud player | | `spotify.com/track/...` | Inline Spotify widget | | `twitter.com/.../status/...` | Inline tweet card | | `tiktok.com/@user/video/...` | Inline TikTok player | | Regular site URL | Thumbnail + title + description card | | URL inside a code block | Plain text (no embed) | ## When it matters | Use case | Why oEmbed helps | |---|---| | Course / LMS discussion | Instructor shares a YouTube lecture — students watch inline | | Marketing / podcast community | Embedded SoundCloud / Spotify episode players | | Marketplace product help | Vendor shares a Vimeo demo of a product | | Social network DMs | Users share TikToks / tweets, rendered as native widgets | | Support chat | Knowledge-base link shows a thumbnail + summary preview | ## How to enable oEmbed expansion runs through the standard WordPress oEmbed system, so it's always on. Better Messages adds the **Enable Nice Links** toggle on top. Navigate to **WP Admin → Better Messages → Settings → Messaging**. - **Enable Nice Links** — Show link preview cards for URLs that aren't backed by an oEmbed provider ## Frequently asked questions ### Does the embed contact the original site? Yes — the embed iframe is served by the source (YouTube, Vimeo, etc.). Their tracking / cookies apply. For privacy-strict sites, consider the [Privacy-friendly oEmbeds](/docs/features/privacy-gdpr/) setting which shows a static thumbnail until the user clicks play, so the third-party iframe isn't loaded on page load. ### Can I block specific oEmbed providers? Yes — hook the `embed_oembed_html` WordPress filter (Better Messages uses standard WP oEmbed under the hood) and return an empty string for hosts you want to suppress. ### Why doesn't a link embed even though it's from a supported service? Possible reasons: the URL is inside a code block, the URL is a redirect that the provider doesn't recognize, or the WordPress oEmbed cache has a stale failure. Clear the post oEmbed cache via WP-CLI (`wp post meta delete _oembed_`) or by editing the message to re-trigger. ### Are embeds rendered in the mobile app? Yes — the mobile app uses a WebView for the messenger surface, so embeds render the same as on the web. Bandwidth-conscious users can disable embeds in the global settings. ### Does this work in email notifications? Email notifications include the link as a clickable URL, not as an embedded player (email clients don't support inline video). Nice-link previews appear as a thumbnail + title in the email. ## See also - [Markdown support](/docs/features/markdown-support/) — text formatting in messages - [File sharing](/docs/features/file-sharing/) — for attached media not coming from URLs - [Stickers](/docs/features/stickers/) — pre-built visual reactions - [GIPHY integration](/docs/features/giphy-integration/) — animated GIF picker --- ## Pin Messages & Conversations in WordPress Chat # Pinned Messages & Conversations Better Messages supports two distinct pinning behaviors: **moderators can pin messages** to the top of a conversation so they're always visible, and **users can pin entire conversations** to the top of their inbox so their most-used threads don't scroll away. Both are useful in different ways for keeping important content close at hand. ## What it adds - Pinned message — moderators select **one** message to stick to the top of the conversation - Pinned conversations — each user can pin their most-used threads to the top of their inbox - A pinned message is visible to all participants — useful for chat-room rules, announcements, key links - Pinned conversations are per-user — your pins don't affect others - Easy unpin from the same UI as pinning - The pinned message stays in place even as new messages are sent (it doesn't scroll away) ## How it works ### Pinned message (moderator action) A conversation or chat-room moderator selects a message and clicks **Pin**. The message moves to a sticky region at the top of the thread, visible to every participant. Pinning is **one message per thread** — pinning a new message replaces the previous pinned message. | Use case | Pinned content | |---|---| | Public chat room | Room rules, welcome message, link to docs | | Support chat | Key escalation contacts, hours of operation | | LMS cohort | Assignment due dates, syllabus link | | Marketplace vendor group | Shipping policies, store hours | | Event-day room | Schedule, speaker bios, live links | ### Pinned conversations (per-user action) A user clicks the pin icon next to a conversation in their inbox. That thread moves to the top, above the recency-sorted list, and stays there until unpinned. Pinned conversations are personal — other participants don't know which threads you've pinned. | Use case | Why pin | |---|---| | Daily-use thread | Easier access than scrolling past newer chats | | Important customer | Stays at top regardless of message recency | | Personal favorites | Family / close friend threads always accessible | | Active project | Keep the relevant group chat one click away | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Messaging**. - **Pin Messages** — Allow moderators to pin messages in conversations and chat rooms - **Pin Conversations** — Allow users to pin conversations to the top of their inbox ## Frequently asked questions ### Who can pin messages? Conversation moderators (the thread creator + WordPress administrators) can pin. In a chat room, the room creator and admins can pin. ### What happens if a pinned message is deleted? The pin is cleared automatically when the underlying message is deleted. ### How many messages can be pinned in one conversation? **One pinned message per thread.** Pinning a different message replaces the previous one — keep this in mind when surfacing important info; rotate the pin as content evolves. ### Are pinned conversations counted in the inbox count? Yes — pinned conversations participate normally in unread counts and notifications. Pinning only affects sort order in the inbox view. ## See also - [Favorite messages](/docs/features/favorite-messages/) — bookmark messages privately (different from public pins) - [Chat rooms](/docs/features/chat-rooms/) — where moderator pinning matters most - [Pinned messages blog post](/blog/pin-messages-wordpress-chat/) — feature deep-dive with screenshots - [Group conversations](/docs/features/group-conversations/) — context where pinning is most useful --- ## Pre-Moderate Messages in WordPress Chat # Pre-Moderated Messages Better Messages supports **pre-moderation** — messages from specific users or roles are held in a queue for moderator review before being delivered. Stronger than user-reporting (which is reactive), pre-moderation is **proactive**: bad content never reaches the recipient. Useful for sites that need extra control over new users, public chat rooms, or specific role-tiers. ## What it adds - Hold messages for moderator review before delivery - Per-role pre-moderation for **new conversations** (different policy than replies) - Per-role pre-moderation for **replies** - Email alerts to moderators when messages need review (multiple addresses supported) - One-click approve / reject from the admin Messages Viewer - Approved messages are delivered as if newly sent (notifications fire on approval) ## How it works When a user sends a message and any pre-moderation condition matches them, the message is stored with a "pending" status. Recipients don't see it. Moderators see the queue in the admin Messages Viewer. | Condition | Outcome | |---|---| | Sender's role is in **Roles for New Conversations** and this is a new thread | Held for review | | Sender's role is in **Roles for Replies** and this is a reply | Held for review | | Neither role list matches the sender | Delivered immediately | | Moderator approves a held message | Delivered to recipient + notifications fire | | Moderator rejects | Message deleted; sender is not notified by default | The moderator workflow takes seconds: open the email alert, click through to the Messages Viewer, approve or reject. Multiple moderators can share the queue. ## When to use pre-moderation | Site type | Recommended setup | |---|---| | New public community | First-time senders held + admin moderates first message before user can DM freely | | Marketplace | Buyer→vendor first messages held — protects vendors from scam attempts | | Dating site | All free-tier messages held until user verifies email + profile | | LMS with student DMs | First message to instructor held — protects instructor time | | Strict communities | All replies from anonymous / guest users held | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Moderation**. 1. **Enable Messages Viewer** — prerequisite — the admin UI for reviewing held messages 2. **Enable Pre-Moderation** — turn on the pre-moderation system 3. **Roles for New Conversations** — pick roles whose new threads need approval 4. **Roles for Replies** — pick roles whose replies need approval 5. **Moderation Notification Emails** — addresses notified when a message is held (one per line) :::info The Messages Viewer is the prerequisite — enable it first, then configure pre-moderation policies below. ::: ## Frequently asked questions ### Does the sender know their message is held? Yes — the UI shows a "waiting for moderator review" notice on their pending message. They see it in their thread; the recipient doesn't. ### How long does the moderator have to approve? No timeout by default — held messages stay pending indefinitely until reviewed. ### Can pre-moderation be combined with the bad-words filter and AI moderation? Yes. The bad-words filter blocks outright at send time. The [AI content moderation](/docs/features/ai-content-moderation/) (WebSocket version) can flag or hold messages on a per-category / threshold basis. Pre-moderation handles the broader "held for human review" pattern on top of both. ### What happens to held messages from a deleted user? If the user is deleted before review, the pending messages are deleted along with the rest of that user's data when **Delete messages on user delete** is enabled. ### Are AI bot messages subject to pre-moderation? No — AI bot replies bypass pre-moderation since the bot's output is already controllable via the AI provider's safety settings and the [AI content moderation](/docs/features/ai-content-moderation/) layer. ## See also - [Report messages](/docs/features/report-messages/) — reactive moderation (users flag bad content) - [Bad words filter](/docs/features/bad-words-filter/) — automatic content blocking - [AI content moderation](/docs/websocket/cloud-ai/) — AI-assisted moderation (WebSocket version) - [Role-based access](/docs/features/role-based-access/) — restrict messaging by role --- ## Privacy & GDPR Compliance # Privacy & GDPR Better Messages is designed with privacy in mind and provides the tools needed for GDPR compliance. ## Data Storage All message data is stored on your own server in your WordPress database. No message content is stored on external servers. When the WebSocket version is used for real-time delivery, data is transmitted encrypted and is not stored on external servers. An additional **end-to-end encryption (E2EE)** option is available in the WebSocket version for maximum privacy — messages are encrypted on the sender's device and can only be decrypted by the intended recipients. Browser-cached data (IndexedDB) stays on the user's device and is not shared with anyone. Users can clear it at any time by clearing their browser data. In the WebSocket version, cached data can be additionally encrypted for extra protection. ## No Cookies or Tracking The plugin does not set any cookies. No analytics or tracking scripts are loaded. No user behavior data is collected or sent to third parties. ## WordPress Privacy Tools Integration Better Messages integrates with the WordPress built-in privacy tools: - **Personal Data Export** (Tools → Export Personal Data) — exports all messages sent by the user - **Personal Data Erasure** (Tools → Erase Personal Data) — anonymizes the user's message content and optionally deletes their file attachments - **Suggested Privacy Policy** (Settings → Privacy) — provides a ready-to-use privacy policy text that adapts based on your plugin configuration ## Third-Party Services Better Messages minimizes third-party connections. The following external services may be used depending on your configuration: ### Emoji Images By default, emoji spritesheet images are loaded from a CDN (jsdelivr.net). You can switch to **self-hosted delivery** in the plugin settings (Privacy & GDPR tab) to download emoji images to your server, eliminating external requests. ### Video Embeds (oEmbed) When users share YouTube, Vimeo, or other video links, embedded players may load directly from those services. You can enable **Privacy-friendly oEmbeds** in the plugin settings — this shows a static preview with a play button, and the actual video loads only after the user clicks. ### GIFs and Stickers If GIF (Giphy) or Sticker (Stipop) integrations are enabled, images are loaded from their respective servers when displayed in conversations. These features are optional and can be disabled by removing the API keys in the settings. ### Real-Time Messaging (WebSocket Version) The WebSocket version routes real-time events through a cloud relay server (cloud.better-messages.com) for instant message delivery. Data is transmitted encrypted. The relay server does not store message content. ### Voice and Video Calls (WebSocket Version) Private one-on-one calls are established directly between users (peer-to-peer). Group calls are routed through a cloud service to connect multiple participants. ### AI Chat Bots If AI chat bots are enabled, messages in bot conversations are sent to the configured AI provider (OpenAI, Anthropic, or Google) to generate responses. This only applies to conversations with AI bots, not regular user conversations. ## Privacy Settings All privacy-related settings are consolidated in the **Privacy & GDPR** tab in the plugin settings: - **Emoji Sprite Delivery** — choose between CDN or self-hosted - **Privacy-friendly oEmbeds** — click-to-play video embeds - **Delete attachments on data erasure** — remove uploaded files when a user requests data erasure ## Guest Chat If guest chat is enabled, the following data is collected from guest users: - Display name (required) - Email address (optional) - IP address (for identification purposes) This data is stored in the site database and is not shared with third parties. ## Frequently asked questions ### Is the cloud WebSocket version GDPR-compatible? Yes. The cloud WebSocket relay is blind to message content — no storage, no inspection, no retention. All message data lives only in your WordPress database. For most sites, the cloud version is GDPR-compatible by default. ### When should I consider the self-hosted plan? For stricter cases — GDPR Article 9 regulated data (health, biometric, racial origin), HIPAA-adjacent workloads, jurisdictional rules about which servers may transit data — the self-hosted plan lets you run the WebSocket layer on infrastructure you control. Contact support for the build. ### Does AI chat bot use exempt my site from GDPR claims? The AI provider (OpenAI / Anthropic / Google) sees messages routed to a bot. Disclose this in your privacy policy. To avoid third-party AI, disable AI bots or use a self-hosted AI provider via the AI add-on's custom-provider hook. ### Are guest IP addresses subject to GDPR? Yes — IP addresses are personal data under GDPR. The IP value lives in the `ip` column of the `bm_guests` table and is used for the synthetic Guest role check and for AI-bot identification. If you need to anonymize it, drop the `wp_bm_guests.ip` column to a hashed value periodically via a custom cron, or filter the value before insert by hooking the `better_messages_guest_registered` action and updating the row. ### How do I respond to a "right to be forgotten" request? Use WordPress's built-in Tools → Erase Personal Data. Better Messages integrates with this — message content is anonymized and (optionally) file attachments are deleted. ## Questions? If you believe we missed something or have a suggestion to improve privacy compliance, please contact us at [support@better-messages.com](mailto:support@better-messages.com). ## See also - [Auto-delete messages](/docs/features/auto-delete-messages/) — retention policy configuration - [End-to-end encryption](/docs/websocket/e2e-encryption/) — content encryption (WebSocket version) - [GDPR-compliant messaging blog post](/blog/gdpr-compliant-wordpress-messaging/) — feature overview - [Guest access](/docs/features/guest-access/) — privacy considerations for guests - [User-to-user block](/docs/features/user-block/) — user-controlled privacy --- ## Real-Time WordPress Chat — AJAX vs WebSocket # Real-Time Messaging Better Messages delivers chat messages in **two distinct modes** — **AJAX polling** in the free version (the browser checks for new messages every few seconds) and **WebSocket push** in the WebSocket version (messages arrive instantly via a persistent connection). The mode determines the perceived speed of the chat — both deliver every message reliably, but the experience is dramatically different. ## What it adds - Two delivery mechanisms: AJAX polling or WebSocket push - Configurable polling intervals for AJAX mode (per-conversation and site-wide) - Instant delivery via persistent WebSocket on the paid version - Automatic reconnection when the network drops - Works site-wide — across any page where the plugin is loaded - Same backend for both modes — switching versions is a setting flip ## How each mode works ### AJAX mode (free version) The browser polls the WordPress server on a configurable interval (default 3 seconds for the active conversation, 10 seconds for other pages). When new messages exist, they're returned and rendered. This works on any standard WordPress hosting — no extra server, no Node.js, no third-party service. Trade-offs: a small (1-10 second) delay between sending and receiving, plus continuous low-volume requests to your server. ### WebSocket mode (paid version) A persistent WebSocket connection runs between the browser and the **hosted cloud relay** (included with the WebSocket-version license). When someone sends a message, the relay pushes it to all participants' open connections instantly. No polling, no delay. Trade-offs: requires the WebSocket version license; the cloud relay is the dependency (or self-hosted plan for sites with strict data-sovereignty needs). | Aspect | AJAX mode | WebSocket mode | |---|---|---| | Delivery latency | 1-10 seconds | Instant (\<200 ms) | | Server load | Continuous polling | Minimal — push only on activity | | Hosting requirements | Any WordPress hosting | Cloud relay included | | Typing indicator | Not supported | Supported | | Presence status | Not supported | Supported | | Web push notifications | Not supported | Supported | | Voice / video calls | Not supported | Supported | | End-to-end encryption | Not supported | Supported | | Site infrastructure | None extra | None extra (relay is hosted) | ## When to choose each | Site profile | Recommended mode | |---|---| | Casual community, hobby site | AJAX free version works fine | | Marketplace where buyer-seller messaging is core | WebSocket — instant response is competitive | | Live customer support | WebSocket — chat-app expectations | | Public chat rooms with many active participants | WebSocket — polling at scale becomes server-heavy | | Dating / fan community | WebSocket — real-time presence + delivery matters | | LMS office hours | WebSocket — instant Q&A feels like a real conversation | ## How to enable Navigate to **WP Admin → Better Messages → Settings → General**. - **Mechanism** — Choose between AJAX or WebSocket - **Thread Interval** — Polling rate for the active conversation (AJAX mode, default 3 seconds) - **Site Interval** — Polling rate for other pages (AJAX mode, default 10 seconds) :::info WebSocket version The WebSocket version (paid license) unlocks instant delivery plus typing indicators, presence, web push, voice/video calls, AI chat bots, end-to-end encryption, and group calls. The relay is hosted — no Node.js to deploy, no third-party service to bill against, no extra load on your WordPress server. ::: ## Frequently asked questions ### Can I run my own WebSocket server instead of the hosted relay? The **self-hosted plan** lets you run the WebSocket layer on your own infrastructure — useful for strict data-sovereignty requirements (GDPR Article 9, HIPAA-adjacent, jurisdictional rules). Contact support for the build and pricing. ### Will increasing polling frequency on free version cost performance? Yes — every 1 second of decrease in polling interval roughly doubles request load. Default 3 seconds is a balanced choice. For "near-instant" delivery on the free version, consider upgrading to WebSocket instead of polling at 1 second. ### Does the WebSocket version work on shared hosting? Yes — the WebSocket connection talks to the cloud relay, NOT to your WordPress server. Your WordPress hosting is unaffected; the connection bypasses it entirely. This is the key architectural advantage. ### What happens if the WebSocket connection drops? The plugin auto-reconnects when network connectivity returns. Messages sent during the disconnect are queued and delivered on reconnect. ### Can I switch between AJAX and WebSocket at runtime? Switching is a setting change in the admin — no reinstall. Site-wide for the moment (not per-user). Per-role overrides (e.g. WebSocket for paid members, AJAX for free) are not exposed as a built-in setting today — contact support if your site needs that pattern. ## See also - [Instant delivery](/docs/websocket/instant-delivery/) — WebSocket-version details - [Typing indicator](/docs/websocket/typing-indicator/) — WS-only real-time feature - [Presence indicator](/docs/websocket/presence-indicator/) — WS-only online status - [Load optimization](/docs/websocket/load-optimization/) — how WebSocket reduces server load - [Realtime messaging blog post](/blog/realtime-messaging-wordpress/) — feature overview --- ## Reply, Edit & Forward Messages in WordPress Chat # Reply, Edit & Forward Three core message-level actions every modern chat app needs — built into Better Messages: **reply with quoted context** for clarity in busy group threads, **edit a sent message** when a typo or fact-correction is needed (with an "edited" indicator for transparency), and **forward** a message to one or many other conversations. ## What it adds - Reply — quote a specific message inline as context for your response - Self-reply — quote your own past messages (configurable) - Edit — change a sent message; shows an "edited" indicator to other participants - Forward — send the message to one or multiple other conversations - Optional **"Forwarded from" attribution** showing the original sender ## How each works ### Reply Click the **Reply** action on any message. Your message input shows a quote preview of the target message. Type your response, send — the reply renders with the quoted original above your text, making the context unambiguous. | Scenario | Why reply matters | |---|---| | Busy group chat | Your "Sounds good" is clearly responding to the right earlier message | | Async DMs | Reply on a 3-day-old question without losing context | | Multi-topic threads | One conversation handling multiple parallel topics stays clear | ### Edit Click **Edit** on a sent message. Modify the text, save. The message updates for all participants with a small "edited" label appended. Past edit history isn't visible to participants by default (privacy choice). Edit window: configurable from the **Settings → Messaging → Edit time limit** field (in minutes). Set to `0` to allow editing indefinitely; set to e.g. `5` to enforce a 5-minute window for non-admin users. ### Forward Click **Forward** on a message, pick one or more target conversations (DMs or group chats), submit. The message appears in each target with an optional "Forwarded from [sender]" label. | Forward target | Result | |---|---| | Single DM | Message appears as a new message in that thread | | Multiple DMs | Same message duplicated to each thread | | Group chat | Message appears in the group with all members visible to the forwarder | | Chat room | Message posted to the room (requires sender to be a participant) | ## When to use each | Action | Typical use | |---|---| | Reply | Group chats, async DMs, threading multiple topics | | Edit | Typo fixes, fact corrections, clarifications | | Forward | Sharing important info across teams, escalating to managers, cross-posting announcements | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Messaging**. - **Enable Replies** — Allow quoted replies - **Allow Self Replies** — Let users quote their own past messages - **Allow Edit Messages** — Permit post-send editing - **Enable Message Forwarding** — Allow forwarding to other conversations - **Forwarded Attribution** — Show "Forwarded from" label on forwarded messages ## Frequently asked questions ### Can administrators see edit history? Not in the default UI. The database stores only the current text. To preserve full edit history, register a listener on the REST edit endpoint and log the previous body before the update lands. ### How long can a user edit a message after sending? Unlimited by default (the **Edit time limit** setting starts at `0` minutes = unlimited). Raise it to e.g. `5` to restrict non-admin users to editing within 5 minutes of sending. ### Does forwarding show the original conversation to recipients? No — forwarded messages don't reveal where they came from beyond the "Forwarded from [sender]" attribution. The original conversation participants don't see the forward action either. ### Can users edit messages that they replied to? Yes — the original sender can edit anytime. The reply quote updates to reflect the edited content automatically. ### Are edits and forwards subject to the bad-words filter? Yes — both go through the same content pipeline. An edit that introduces banned words gets rejected, preserving the original text. A forward of a banned-word message gets blocked. ## See also - [Message reactions](/docs/features/message-reactions/) — emoji reactions on messages - [Pinned messages](/docs/features/pinned-messages/) — moderator/user pinning - [Message drafts](/docs/features/message-drafts/) — auto-save unsent text - [Group conversations](/docs/features/group-conversations/) — where replies are most useful --- ## Report Inappropriate Messages # Report Messages Better Messages includes a **user-driven message reporting system** — when enabled, any user can flag a message they find inappropriate for moderator review. Reported messages surface in the admin **Messages Viewer**, where moderators can inspect the content, view the conversation context, and take action (delete the message, warn the user, ban the user, etc.). ## What it adds - "Report" action on every message in every conversation - Reported messages appear in the admin Messages Viewer for review - Moderators see the full conversation context, not just the flagged message - Mark-as-handled workflow to track which reports have been processed - Anonymized reporter — the reported user doesn't see who flagged them - Per-role configurable: control who can report, and whose messages are reportable ## How it works When a user clicks **Report** on a message, the plugin stores a report record `(reporter_id, message_id, conversation_id, timestamp)`. The reporter is anonymized in the moderator UI to prevent retaliation. | Action | Outcome | |---|---| | User clicks Report | Report is queued; reporter sees a confirmation | | Moderator opens Messages Viewer | List of reported messages, newest first | | Moderator opens a report | Full conversation context shown around the flagged message | | Moderator deletes the message | Message removed for all participants | | Moderator dismisses the report | Marked handled; the message remains | | Multiple users report the same message | Single report record, but report count visible | ## When to enable | Site type | Why message reports matter | |---|---| | Open community / public chat rooms | Members help moderate at scale | | Marketplace | Catches bad-faith vendor or buyer conduct | | Dating community | Critical for handling harassment quickly | | Course / LMS | Students can flag classroom-rule violations | | Public-facing app | Compliance with app-store moderation requirements | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Moderation**. - **Messages Viewer** — **Enable this first** — the prerequisite for the moderator review UI - **Allow Reports** — Enable the report action for users :::info The Messages Viewer must be enabled before the Allow Reports setting becomes useful — without it there's no UI for moderators to review the reports. ::: ## Frequently asked questions ### Who can see the report queue? Only WordPress users with the `bm_can_administrate` capability (which `manage_options` users get by default). The capability is grantable to other roles via your usual WordPress role-management plugin if you want a non-admin "Moderator" role to handle reports. ### Can a user be falsely accused via mass-reporting? The system stores who reported, so administrators can review patterns. A single user's reports don't auto-delete anything — moderator review is required. ### Are reports anonymous? The reporter is anonymized in the public-facing moderator UI (admins see "Reported by 3 users" rather than usernames by default). The full record IS stored in the database — accessible to admins if a forensic review is needed. ### Does reporting work in guest conversations? Yes. Guest users can report messages from other guests or logged-in users. The same moderator queue handles all reports. ### What if a user reports a message and then the sender deletes it? The report record stays for the audit trail. The message body shows "Deleted" in the moderator view, but the timestamp + reporter info are preserved. ## See also - [Pre-moderation](/docs/features/pre-moderation/) — review messages BEFORE delivery (stronger than reporting) - [Bad words filter](/docs/features/bad-words-filter/) — automatic blocking of banned terms - [User-to-user block](/docs/features/user-block/) — let users handle individual harassment directly - [AI content moderation](/docs/websocket/cloud-ai/) — AI-assisted moderation (WebSocket version) --- ## Role-Based Access Control for WordPress Chat # Role-Based Access Control Better Messages includes a **role-based send-permission system** — pick the WordPress roles that are allowed (or forbidden) to send messages, set a custom error message for blocked senders, and put per-role rate limits on top so high-volume roles can't be used to spam threads. ## What it adds - **Allow** or **Disallow** mode for role-based send permission - A single per-role list that defines who is in (or out, depending on the mode) - Custom error message shown to blocked senders - Per-role rate limits on **replies** (configurable per role, per time window) - Site-wide minimum delay between **new conversations** - Companion features: [user-to-user block](/docs/features/user-block/), [MyCred / GamiPress points](/docs/features/mycred-gamipress/), and [pre-moderation](/docs/features/pre-moderation/) for richer policies ## How it works The system checks the sender's role against the configured policy on every message send: 1. **Mode = Allow** — only roles in the list can send. Everyone else is blocked. 2. **Mode = Disallow** — roles in the list are blocked. Everyone else can send. 3. **Reply rate limit** — if the sender's role has a per-time-window cap, replies above the threshold are blocked until the window resets. 4. **New-conversation rate limit** — a minimum number of seconds between starting new threads, site-wide. A failed check rejects the send with the configured error message. | Mode | Effect | |---|---| | **Allow** | Sender's role must be in the configured list. Roles not in the list are blocked. | | **Disallow** | Sender's role must NOT be in the configured list. Roles in the list are blocked. | ## Common policy patterns | Site type | Example configuration | |---|---| | Marketplace | Disallow `customer` from starting new conversations more than once per 30 seconds; allow vendors / shop managers freely | | LMS | Allow only `instructor`, `course-leader`, and `subscriber` to use the messenger; rate-limit `subscriber` to 30 replies per hour | | Membership site | Disallow `subscriber` (free tier) from sending; allow paid roles | | Public community | Allow only verified roles; combine with the [user-block](/docs/features/user-block/) feature for individual safety | | Anti-spam baseline | Enforce a 30-second minimum between new conversations site-wide | ## Rate limiting examples | Use case | Rate limit | |---|---| | Free-tier guard rails | `subscriber` → 50 replies per day | | High-volume vendor role | No reply limit, but enforce 30s between new threads | | Anti-spam baseline | 30-second minimum between new conversations (site-wide) | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Restrictions**. - **Restriction Mode** — Allow or Disallow mode for the role list - **Restricted Roles** — Roles that are in / out depending on the mode - **Restriction Error Message** — Text shown to a blocked sender - **Rate Limit Replies** — Per-role replies-per-window cap (`replies` count + window in minutes) - **Rate Limit Replies Error** — Text shown when the cap is hit - **Rate Limit New Conversations** — Minimum seconds between starting new threads (site-wide, all roles) ## Frequently asked questions ### Are admins exempt from these rules? WordPress administrators (the `administrator` role) bypass the bad-words filter when **Skip for Admins** is on. Role-based access applies to admins the same as any other role — list them under **Allow** mode or leave them out of the **Disallow** list to keep them unrestricted. ### What error message does a blocked user see? The text from **Restriction Error Message** (or **Rate Limit Replies Error** when the rate limit is the cause). Both are configurable in the Restrictions tab. ### How do the rules interact with user-to-user block? Both apply — a user-to-user block and a role restriction each have to pass for the message to send. Either rejection blocks the message. Role rules are admin-set; user blocks are user-set. ### Can I create custom roles for this? Yes — the rule system reads ANY WordPress role, including custom ones added by membership plugins (Paid Memberships Pro, MemberPress, etc.). Define your roles in those plugins, then pick them in the Better Messages restrictions. ### What about guests / non-logged-in users? Guests have a synthetic `bm-guest` role and can be picked in the Restrictions role list. Combine that with the per-chat-room **Allow guests** toggle to control where guests can chat. ## See also - [User-to-user block](/docs/features/user-block/) — user-controlled blocking (different from role rules) - [Pre-moderation](/docs/features/pre-moderation/) — moderator review before delivery - [Bad words filter](/docs/features/bad-words-filter/) — server-side content filtering - [Role-based access blog post](/blog/role-based-access-wordpress-chat/) — feature deep-dive - [MyCred / GamiPress pay-to-message](/docs/features/mycred-gamipress/) — point-cost-based access control --- ## Arabic, Hebrew, Persian RTL Chat # RTL Layout Support Better Messages **automatically mirrors its entire interface for right-to-left languages** — Arabic, Hebrew, Persian (Farsi), Urdu, and any other language WordPress identifies as RTL. There's no separate RTL theme, no admin toggle, and no per-user setting — the messenger detects the site language direction and adapts everything: message bubbles, conversation list, navigation, input field, toolbars, attachments, and call UI. ## What it adds - Automatic detection of WordPress site language direction (no manual configuration) - Full interface mirroring — message bubbles align right, avatars on the right, controls on the left - Works with all 30+ shipped translations including ar, he, fa, fa_IR, ar_DZ, ar_MA, ur, ar_SY, ar_LB - Same RTL behavior in DMs, group chats, chat rooms, mini-chats, and the mobile app - Compatible with all integrations — BuddyPress, BuddyBoss, PeepSo, UM, etc. all render RTL correctly - No extra plugin or addon required ## How it works WordPress sets `is_rtl()` to `true` when the active locale is one of its known RTL languages (or when a translation file declares RTL). Better Messages reads this flag on every render and: | UI element | RTL behavior | |---|---| | Message bubbles | Own messages on the left, others' on the right (mirrored) | | Conversation list | Avatar on the right, name + last message reading right-to-left | | Message input | Cursor starts on the right, text flows right-to-left | | Toolbar (emoji, attachment, send) | Mirrored — send button on the left | | Conversation header | Title and back arrow mirrored | | Mini-chat popups | Open from the bottom-left instead of bottom-right | | Call UI | Controls mirrored, participant grid order reversed | | Notification badges | Position adapted to RTL flow | Mixed content (an Arabic message that contains an English URL or code block) is handled correctly — bidirectional Unicode rules apply within each message, so the URL stays left-to-right inside the RTL bubble. ## Supported RTL languages The plugin ships with translations and tested RTL support for: | Language | WordPress locale codes | |---|---| | Arabic (multiple dialects) | `ar`, `ar_DZ`, `ar_MA`, `ar_SY`, `ar_LB`, `ar_EG`, `ar_SA` | | Hebrew | `he_IL` | | Persian / Farsi | `fa_IR`, `fa_AF` | | Urdu | `ur` | Any RTL language not in this list is still supported visually — the layout mirrors based on `is_rtl()`. You just may need to provide your own .po translation file if the strings aren't bundled. ## How to enable RTL activates automatically when the WordPress site language is set to an RTL language. Set the site language at **WP Admin → Settings → General → Site Language**. For per-user multilingual sites (where some users prefer Arabic and others English), pair this with a translation plugin like [TranslatePress](https://wordpress.org/plugins/translatepress-multilingual/) or WPML — RTL direction follows the user's chosen language automatically. ## Frequently asked questions ### Does RTL break any feature? No. Every feature — voice/video calls, attachments, emoji picker, AI bots, mini-chats — is RTL-aware. If you spot a UI element that doesn't mirror, that's a bug — report it on the support forum. ### How does RTL interact with the mobile app? The mobile app respects the device's language direction. If the user's iOS/Android system is set to Arabic or Hebrew, the entire app mirrors. The web app respects WordPress site language; they're independent. ### Can a single user override RTL to use LTR layout? No per-user override exists. Direction is driven by site (or device on mobile) language. To allow LTR within an Arabic site, use a multilingual plugin and let users switch language. ### What about CSS customizations — will they break RTL? The plugin uses logical CSS properties (`margin-inline-start` instead of `margin-left`, etc.) wherever direction matters. Custom CSS that uses physical properties (`margin-left`) will work in LTR but may need mirroring for RTL. ### Is the AI chat bot's response in RTL too? Yes — the AI's response is just text. If the conversation is in Arabic, the AI replies in Arabic (using the configured AI provider's language detection), and the bubble renders right-to-left. ## See also - [Translations](/docs/features/translations/) — 30+ language packs bundled with the plugin - [Mobile app](/docs/category/mobile-app/) — iOS / Android with RTL support - [AI message translation](/docs/features/ai-message-translation/) — auto-translate messages between languages --- ## Full-Text Message Search in WordPress Chat # Search Better Messages includes a **full-text search** across every message in every conversation the user is a participant in. The search bar lives in the messenger UI — one query, results from DMs and group chats, click to jump straight to the message in context. ## What it adds - Search bar in the messenger interface for finding specific messages - Full-text matching across all of the user's threads (DMs, group chats, chat rooms) - Results show the matching message line + its conversation context - One-click navigation jumps to the matched message in its thread - Works on the web app and mobile app ## How it works The search executes a MySQL LIKE-based scan across the user's messages, scoped to threads they're a participant in. Results are sorted by recency by default — newest matching messages first. | Query | Matches | |---|---| | `invoice` | Any message containing "invoice" (case-insensitive) | | `shipping fee` | Messages containing both words (any order) | | Special characters | Punctuation is ignored; alphanumeric + whitespace tokens are matched | For very large message archives (10K+ messages per user), the LIKE search may slow down. Future versions will add MeiliSearch or Elasticsearch as an optional backend for high-volume sites — for now, the default works well for typical communities. ## When users search most | Audience | Common search patterns | |---|---| | Marketplace vendor | "tracking number", "refund", customer name | | LMS instructor | Assignment name, student name, due date keyword | | Community manager | Recurring topic keywords, link prefixes | | Support rep | Error message snippet, customer email | | Personal DMs | Address, phone number, restaurant name shared earlier | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Messaging**. - **Disable Search** — Toggle to turn the search feature off Search is **enabled by default**. The setting hides the search input from the messenger UI when disabled, but the underlying data is unaffected. ## Frequently asked questions ### Does search find content inside attachments? No — the search only matches message text, not file attachments. PDF text, image OCR, and audio transcripts are not searched. For voice messages, see [AI voice transcription](/docs/websocket/cloud-ai/) which can transcribe voice messages to text (WebSocket version) — once transcribed, the text becomes searchable. ### Are deleted messages searchable? No. Once a message is deleted (by the sender or by auto-delete), it's removed from the search index. Edits update the indexed text on save. ### Can administrators search across all users' messages? Not from the user-facing search. Admins can run direct SQL queries on the `bm_messages` table from phpMyAdmin or WP-CLI for compliance / audit purposes. There's no built-in admin search UI. ### Does search work in chat rooms with hundreds of participants? Yes — search is scoped to threads the user participates in, and one chat room is one thread regardless of participant count. Performance is dictated by total message volume in that user's threads, not by participant count. ### Why don't my search results include really old messages? By default the search covers all messages. If you've enabled [auto-delete](/docs/features/auto-delete-messages/), old messages may have been purged. The search reflects the current database state. ## See also - [Favorite messages](/docs/features/favorite-messages/) — bookmark messages for quick access without searching - [Pinned messages](/docs/features/pinned-messages/) — admin-pinned important messages in chat rooms - [AI voice transcription](/docs/websocket/cloud-ai/) — transcribe voice messages so they become searchable - [Auto-delete messages](/docs/features/auto-delete-messages/) — message lifecycle / retention --- ## On-Site Notification Popups in WordPress Chat # On-Site Notifications Better Messages displays **on-site popups and tab-title alerts** when a user receives a new message while they're browsing your website. A small toast appears in a screen corner with a message preview; the browser tab title can also show an unread count badge, so users notice activity even when on a different tab. ## What it adds - Pop-up toast notification on the user's screen when a new message arrives - Configurable position — left or right corner - Mobile-specific positioning — auto, top, or bottom (better for thumb reach) - Browser tab title badge showing unread message count (e.g., "(3) My Site") - Click the popup to jump straight to the conversation - Auto-dismiss when the conversation is read elsewhere (cross-tab sync) - Independent from web push / mobile push / email — runs while the site is open ## How it works When a new message arrives via the WebSocket relay (or via AJAX poll on the free version), the JavaScript front-end checks the user's notification preferences. If on-site notifications are enabled and the user isn't currently focused on the relevant conversation, a toast pops up. | Channel | When it fires | |---|---| | On-site popup | New message + user is browsing the site, NOT on that conversation | | Tab title badge | Any unread message — visible even when tab is in background | | Sound | Pairs with the popup (configurable, see [Sound notifications](/docs/features/sound-notifications/)) | | Web push (WS) | Fires when the tab is closed (different scope) | | Email | Fires when user is away from the site (different scope) | The popup auto-dismisses after a few seconds OR when the user opens the conversation in another tab. Cross-tab sync uses BroadcastChannel — no popup duplication if the same user has the site open in multiple tabs. ## When to customize position | Site type | Recommended position | |---|---| | Standard desktop | Bottom-right (the convention) | | Right-to-left language site | Bottom-left (mirrored) | | Mobile-heavy audience | Top (avoids interference with bottom navigation bars) | | Site with a fixed footer | Top-right (avoid the footer) | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Notifications**. - **On-Site Notifications** — Enable or disable the popup toasts - **Popup Position** — Left or right corner - **Mobile Position** — Auto, top, or bottom on mobile devices - **Title Notifications** — Show unread count in the browser tab title (recommended on) ## Frequently asked questions ### Why doesn't the popup show when I'm on the conversation page? By design — if you're already looking at the conversation, the popup would be redundant. The message just appears in the thread as expected. ### Does the popup work for messages received while the tab is in the background? The popup itself only renders on visible tabs. The tab title badge still updates so the user sees the unread count when they switch back. For background notifications, enable [web push](/docs/websocket/web-push/) (WebSocket version) or rely on email. ### Can I customize the popup design? Yes — the popup HTML uses stable class names. Override via CSS under **Appearance → Customize → Additional CSS**. For deeper customization, copy the React notification component into a child plugin / mu-plugin and replace it via your build pipeline. ### Does the popup respect muted conversations? Yes — muted conversations don't trigger popups. See [conversation muting](/docs/features/conversations-muting/). ### Are popups shown for AI bot replies? Yes — AI bot replies notify like any other message. Mute the bot's conversation if you'd rather not see them. ## See also - [Sound notifications](/docs/features/sound-notifications/) — audio cues that pair with popups - [Email notifications](/docs/features/email-notifications/) — for when users are away - [Web push notifications](/docs/websocket/web-push/) — browser push when tab is closed (WebSocket version) - [Conversation muting](/docs/features/conversations-muting/) — silence specific threads --- ## Sound Notifications for WordPress Chat # Sound Notifications Better Messages plays audio cues when a user receives a new message or an incoming call. Each event type (incoming message, sent confirmation, incoming call, outgoing dial tone) has independent volume controls and an optional MP3 upload, so you can match the audio personality of your site or community. ## What it adds - Distinct sounds for **incoming messages**, **sent messages**, **incoming calls**, and **outgoing dial tone** - Per-event volume control (0–100 %) — keep gentle pings for messages and louder rings for calls - Custom MP3 upload per event from the WordPress Media Library - Optional "Allow Sound Disable" toggle that exposes a Sound on/off control in each user's preferences - Sounds trigger on any tab where the messenger is mounted, so users hear them while browsing other parts of the site ## How it works Better Messages includes four default sounds bundled with the plugin: | Event | When it plays | |---|---| | **Notification sound** | A new message arrives and the user is on the site | | **Sent sound** | The user successfully sends a message (confirmation cue) | | **Call sound** | An incoming voice or video call rings — plays in a loop until answered or dismissed | | **Dialing sound** | The user places an outgoing call — plays in a loop until the recipient answers | When the admin uploads a custom MP3 via WP Admin → Better Messages → Settings → Notifications, the plugin stores the attachment ID and serves that file in place of the default. Volume is multiplicative — if the admin sets the call sound to 60 % and the user further lowers their browser/system volume, both apply. Sound playback respects modern browser autoplay policies. The first interaction (any click on the page) unlocks audio. From that point on, all sounds play without further prompting until the page reloads. ## When to customize | Use case | Recommended customization | |---|---| | LMS / serious-study site | Lower message sound volume to ~30 %, keep call volume default — students stay focused | | Marketplace customer support | Bump message volume to 80 % so vendors notice replies fast | | Public chat rooms | Upload a gentler MP3 and set volume below 40 % — frequent messages shouldn't be jarring | | Telemedicine / urgent comms | Loud incoming-call MP3 at 90 %, distinct from message tone | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Notifications**. - **Notification Sound** — Volume (0–100 %) and optional custom MP3 for new incoming messages - **Sent Sound** — Volume and optional custom MP3 for the sent-message confirmation tone - **Call Sound** — Volume and optional custom MP3 for the incoming-call ringtone - **Dialing Sound** — Volume and optional custom MP3 for the outgoing-call dial tone - **Allow Sound Disable** — Let users turn off notification sounds from their personal settings ## Frequently asked questions ### Can users opt out of sound notifications? Yes — when the **Allow Sound Disable** option is enabled, a "Notification sounds" toggle appears in each user's messenger settings. Their preference persists across devices. ### Do sound notifications play on the mobile app? The native iOS/Android app uses the operating system's native notification sounds, not the web-uploaded MP3. To customize those, configure your push provider (OneSignal / FCM / APNs) or the iOS/Android app build. ### Why doesn't the sound play immediately when the page loads? Browsers require a user interaction before allowing audio. After any click on the page, sounds will play normally for the rest of the session. ### Can I upload a different sound per chat room? No — sounds are configured site-wide. The four sound settings (notification, sent, call, dialing) apply to every conversation and chat room. If you need per-room variation, the maintained path is to override the audio asset via your child theme or a custom plugin. ### What file formats are supported? MP3 is the recommended format. M4A and OGG also work in modern browsers. Keep files small (under 100 KB) so they cache quickly. ## See also - [Email notifications](/docs/features/email-notifications/) — for users not currently on the site - [Web push notifications](/docs/websocket/web-push/) — desktop push when the tab is closed (WebSocket version) - [OneSignal integration](/blog/onesignal-push-notifications-better-messages/) — for mobile + browser push - [Email notifications guide](/blog/wordpress-chat-email-notifications/) — when to use email vs sound vs push --- ## Sticker Packs for WordPress Chat # Stickers Better Messages includes a built-in sticker system with a curated catalog of sticker packs, multi-language support, role-based access control, and inline typing suggestions. Sticker picker in chat ## How it works When enabled, a sticker button appears next to the message input area. Clicking it opens a full-width picker where users can browse installed sticker packs, search by keyword, and send a sticker with a single tap. The picker closes instantly after selection for a snappy experience. If **Inline suggestions** is turned on, typing a short keyword like "hi" or "thanks" in the composer will pop up a horizontal strip of matching stickers above the input — similar to how mentions work. The user can pick one with a click, arrow keys, or Tab. ## Key capabilities - **Built-in sticker catalog** with one-click installation from the Better Messages sticker library - **Multi-language packs** — packs with text-based images (e.g. "LOL", "HOLA") can ship different images per language; packs with universal images (e.g. cute characters) ship translated search keywords so stickers are findable in any language - **Custom packs** — create your own packs by uploading PNG, WebP, or animated WebP images - **Role-based access** — restrict individual packs to specific WordPress roles (including Guests) - **Inline suggestions** — type a keyword and matching stickers appear above the composer (per-pack opt-in) - **Per-locale cover and sticker images** — the picker automatically shows the viewer's language variant - **Recent stickers** tab for quick re-sending - **Search across all packs** by sticker name or keyword ## Setting up stickers ### 1. Choose a provider Navigate to **Settings** → **Integrations** → **Stickers**. Sticker provider settings Select **Built-in packs** from the Provider dropdown. This enables the catalog-powered sticker system. Optionally, enable **Inline suggestions** to show sticker matches as the user types. :::note The legacy **Stipop** provider is still available but is no longer recommended. Stipop changed their free plan to allow only 20 monthly active users. We recommend switching to Built-in packs. ::: ### 2. Install packs from the catalog Scroll down to the **Available sticker packs** section. The catalog lists all packs published by Better Messages. Available sticker packs catalog Each pack shows: - **Cover image** and name - **Version** and sticker count - **Pack type** — `reaction` (text-based typographic stickers) or `character` (illustrated character stickers) - **Available languages** — for text-based packs, select which image languages to import using the language chips; for character packs, label translations are included automatically Click **Install** to download and activate a pack. You can install multiple packs simultaneously — each shows its own progress indicator. ### 3. Manage installed packs Installed packs appear in the **Installed sticker packs** section above the catalog. Installed sticker packs Each pack row provides: - **Enabled** toggle — show or hide this pack in the chat picker - **Suggestions** toggle — include or exclude this pack from inline typing suggestions (only visible when the global Inline suggestions setting is on) - **Language badges** — which languages are currently imported - **+ Add languages** — add more image-language variants from the catalog without reinstalling - **Edit** — open the pack editor - **Delete** — permanently remove the pack and its images Use the **arrow buttons** on the left to reorder packs — the order determines the tab order in the sticker picker. ### 4. Edit a pack Click **Edit** on any pack to open the full pack editor. Pack editor The editor allows you to: - **Toggle Enabled / Inline suggestions** at the top - **Set allowed roles** — restrict this pack to specific WordPress roles (leave unchecked for "Everyone") - **Edit cover image** — upload or replace the pack's cover shown in the picker tabs - **Edit title and description** — displayed in the picker and admin - **Manage stickers** — reorder with arrow buttons, rename, edit keywords, or delete individual stickers - **Upload new stickers** — drag and drop or click "Add stickers" (PNG, WebP, or animated WebP) #### Translations Use the locale tabs at the top of the editor to manage per-language content: - **Default** tab — the primary language (title, description, sticker names, keywords) - **Language tabs** (e.g. `es`, `fr`, `de`) — translated title, description, and per-sticker name + keywords for that language - **Per-language images** — on a non-default tab, each sticker row shows an "Upload image" button to provide a language-specific version of that sticker (e.g. text-based stickers with translated text baked into the image) - **Per-language cover** — replace the cover image on a language tab to show a localized cover to viewers on that locale - Click **+ Add language** to add translations for additional installed site languages #### Creating a custom pack Click **+ New pack** in the Installed section to create a pack from scratch. Enter a name, then use the editor to upload sticker images, set keywords, and configure access roles. Custom packs work exactly like catalog packs — they appear in the picker, support translations, and respect role restrictions. ## How the picker looks in chat The sticker picker opens as a slide-up panel at the bottom of the chat area: - **Pack tabs** along the top — one icon per installed pack, plus Recent and Search - **Search bar** — filters stickers across all packs by name or keyword - **Sticker grid** — click any sticker to send it instantly - **Close button** in the top-right corner When only a single pack is installed, the picker simplifies: pack tabs and the recent tab are hidden, replaced by a persistent search bar. The full sticker list is shown immediately. ## Inline suggestions When enabled globally and per-pack, typing a single word (2-20 characters) in the message composer triggers a horizontal suggestion strip above the input: - Suggestions are scored by match quality (exact name > exact keyword > starts-with > contains) - Up to 8 matches are shown - **Click** or press **Tab** to pick a suggestion and send it - Press **Escape** to dismiss, or just keep typing — adding a space hides suggestions immediately - The sticker manifest loads lazily on the first keystroke, so it never delays the chat UI ## Role-based access Each pack has an **Allowed roles** setting with checkboxes for every WordPress role plus **Guests**. When no roles are checked, the pack is visible to everyone. When one or more roles are checked, only users with a matching role can see and use that pack. If a user doesn't have access to **any** enabled pack, the sticker button is hidden entirely from their chat interface. ## Multi-language support Better Messages stickers support two types of localization: ### Text-based packs (reaction type) Packs like "Reactions" and "Smitten" have text baked into the sticker images (e.g. "LOL", "THANKS"). These packs ship separate image sets per language. When installing, select which image languages you want. Each language variant has its own sticker images, cover, and translated keywords. ### Character packs (universal images) Packs like "Whiskers", "Mochi", and "Bruno" use illustrated characters without language-specific text. These packs have a single set of images that works in any language, with translated sticker names and search keywords shipped for multiple languages automatically. All label translations are included in a single install. The sticker picker automatically serves the correct language variant based on the viewer's WordPress locale setting. --- ## Conversation Subject Lines in WordPress Chat # Conversation Subjects Better Messages lets users set a **subject line** when starting a new conversation. The subject becomes the thread title shown in the inbox list, so a busy conversation list is scannable like an email inbox rather than a wall of names. Subjects are optional and work in both DMs and group chats. ## What it adds - Subject field on the new-conversation screen (optional) - Subject displayed as the thread title in the inbox / threads list - Helps users distinguish multiple conversations with the same person or group - Edit-the-subject controls in the conversation header (admin-configurable) - Falls back to participant names if no subject is set ## How it works When a user starts a new conversation, they see an optional **Subject** input above the recipient picker. If they enter text, it becomes the thread's title. If they leave it blank, the thread title defaults to a comma-separated list of participant names (e.g., "Anna, Mike, Sara"). | Subject state | Thread title in inbox | |---|---| | Subject set | The subject text | | Subject blank (1-on-1) | Other participant's display name | | Subject blank (group) | First N participant names + count | | Subject edited later | Updated title appears for all participants | Subjects are stored on the thread record, not per-user — every participant sees the same title. Renaming the subject (when permitted) updates it globally. ## When to require / encourage subjects | Use case | Subject strategy | |---|---| | Support / help desk | Require subjects — instant context for the assigned rep | | Marketplace buyer→vendor messages | Encourage subjects — useful when one buyer messages multiple vendors | | Internal team comms | Optional — names usually suffice | | Course / LMS cohort | Encourage subjects — clarifies which assignment / topic | | Personal DMs | Hide (disable) — feels formal between friends | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Messaging**. - **Disable Subject** — Toggle to **hide the subject field** from the new-conversation screen Subjects are **enabled by default**. Disabling hides the field entirely; existing thread subjects remain stored but new threads use participant names. ## Frequently asked questions ### Can the subject be required (not optional)? Not in the default UI — the field is always optional. If you need to enforce a subject, hook `better_messages_can_send_message` and return `false` when the new thread has no subject set in the request payload. ### Can participants change the subject later? Yes — the conversation header has an edit button that lets thread participants rename the thread. ### How long can a subject be? The UI truncates display at a reasonable width but the full subject is stored — there is no hard server-side cap. Keep it short for readability in the inbox list. ### Does the subject appear in email notifications? Yes — the configured email template uses the thread's subject as part of the heading / subject line. Without a subject, the email falls back to a generic "New message from `{sender_name}`" pattern. ### What about chat rooms — do they have subjects? Chat rooms have a name (set in the admin), which serves the same role as a subject for DMs and group chats. The name appears in the room's header and the user's inbox. ## See also - [Group conversations](/docs/features/group-conversations/) — multi-user threads where subjects are especially useful - [Chat rooms](/docs/features/chat-rooms/) — persistent public/private rooms with admin-set names - [Email notifications](/docs/features/email-notifications/) — how subjects appear in email subject lines - [Pinned messages](/docs/features/pinned-messages/) — pin important info per-conversation --- ## System Messages in WordPress Chat # System Messages System messages are the small inline notes you sometimes see in a group conversation, like *"Alice joined the conversation"* or *"Bob changed the subject to Project Sync"*. They keep everyone in the loop about what's changed, without anyone having to type a normal message. Group conversation showing a System messages are styled differently from regular chat — italic, centered, and without the usual avatar or message bubble — so they're easy to skim past. ## What can trigger a system message | Event | Example text | |---|---| | Someone joins on their own | *Alice joined the conversation* | | Someone is added by another participant | *Alice was added to the conversation by Bob* | | Someone leaves | *Alice left the conversation* | | The subject is changed | *Bob changed the subject to "Project Sync"* | | A chat-room cover image is changed | *Conversation image was changed* | | Someone is promoted to moderator | *Alice was promoted to moderator* | | Someone is removed as moderator | *Alice was removed as moderator* | | A moderator removes someone | *Alice was removed from the conversation* | | A moderator mutes someone | *Alice was muted* | | A moderator bans someone | *Alice was banned* | | Someone starts a group call | *Alice started a group video call* | Each event has its own admin toggle, so you can keep the ones you care about and silence the rest. System messages **never** make sounds, send push notifications, raise browser pop-ups, or send emails — they only update what you see inside the conversation. Guest visitors are treated exactly like logged-in users — when a guest joins or leaves, the message uses their display name (e.g. *Graceful Gecko*). AI chat-bots are skipped so bot threads stay clean. ## Smart grouping — fewer "joined / left" walls Better Messages is smart about how it stacks system messages so the conversation never fills up with a wall of identical lines. While no one is actively chatting, the plugin keeps merging and trimming related events: - **Same person joins twice in a row** — the second one is silently ignored (they're already announced). - **Several people join one after another** — they're combined into one line: *"Alice joined"* becomes *"Alice and Bob joined"*, and so on. Up to three names are shown by name; beyond that you see *"Alice, Bob and 5 others joined the conversation"*. - **Someone joins and immediately leaves before the chat picks up** — both events disappear. They leave no trace. - **Someone is promoted then demoted** — both lines are removed. - **The subject is changed three times in a row** — only one line stays, showing the change from the original subject to the final one. - **The cover image is changed twice** — only one *"Conversation image was changed"* line stays. - **Someone says something** — as soon as a real message arrives, everything above it is locked in as historical record. Any new join, leave, or change after that starts a fresh group below the message. - **Someone is kicked or banned right after joining** — the join announcement is dropped (they're not really joining), and the kick/ban line is shown instead. The end result: in a busy room you see one tidy *"Alice, Bob and 3 others joined the conversation"* instead of five separate "joined" lines, and a quick join-and-leave never spams the history. ## Enabling system messages Go to **WP Admin → Better Messages → Settings → Messaging → System Messages**. System Messages settings panel in WP Admin showing the System Messages master toggle, Allow per-conversation override, the new Ignore in conversations list sort toggle, the System Messages Types checkbox group with all ten event types, and the Repeat suppression window number input - **System Messages** — turn the whole feature on or off site-wide. - **Allow per-conversation override** — when on, conversation moderators can flip system messages on or off for their own thread. - **Ignore in conversations list sort** — when on, a system message will not move a conversation to the top of the list. See [Keep the conversations list calm](#keep-the-conversations-list-calm) below. - **System Messages Types** — pick exactly which events should produce a notice. All are on by default. - **Repeat suppression window** — an extra safety net (advanced, optional). If you set it to a number of seconds, a repeat event for the same person within that window is dropped completely. Most sites can leave this at `0` — the smart grouping above already handles repetition cleanly. :::info The **Group call started** event needs the WebSocket version of Better Messages. On the free / AJAX build it's disabled with a *Get WebSocket License* link beside it. ::: ## Keep the conversations list calm By default a system message — someone joining, the subject changing, a quick promotion — bumps the conversation to the top of the inbox just like a real chat message. In a busy chat-room that means quiet "joined" notices keep pushing your actual conversations down. Turn on **Ignore in conversations list sort** to make the inbox sort by the last *real* chat message instead. The system messages still appear inside the conversation and in the preview line, but they no longer reorder the list.
Conversations list with the toggle OFF: a chat-room with a recent
Toggle off — a fresh "changed the subject to 'Y'" pushes the chat-room to the top.
Same conversations list with the toggle ON: the chat-room with the system message stays in its original position, sorted by the last real chat message; the system message still shows in the preview line
Toggle on — same chat-room sits where its last real message left it.
This is purely a sort-order setting — it doesn't suppress system messages, doesn't change the preview text, and doesn't affect unread counters. A real chat message sent later still bumps the conversation to the top. Conversations whose only activity is system messages sink to the bottom of the list (they stay visible). The toggle works independently of the master **System Messages** switch, so you can leave it on as a permanent preference even on sites where system messages are otherwise disabled. ## Per-conversation override When **Allow per-conversation override** is on, moderators of a group conversation can toggle system messages just for that thread: 1. Open the conversation. 2. Click the conversation header to open the **Conversation Information** sidebar. 3. Find **Show system messages**, toggle it, and click **Save**. Once a moderator changes it, that conversation keeps the override no matter what the site default is. Conversations without an explicit override fall back to the site setting. The override toggle is **not** shown: - in one-on-one conversations (those always use the site default); - inside chat rooms (chat rooms have their own admin-side picker — see below); - to anyone if *Allow per-conversation override* is turned off. A group conversation can use its toggle to **silence** system messages, but it cannot **force them on** when the site setting is off — only chat rooms can do that. ## Chat-room defaults Chat Rooms admin editor showing the System messages master toggle on and the System Messages Types picker with all ten event types checked Each chat room has its own system-message settings, configured from **WP Admin → Better Messages → Chat Rooms → *select chat room* → Chat Room Settings → System messages**: - **System messages** — when on, this chat room shows system messages even if the global setting is off. Useful when you want clean inboxes for private conversations but full visibility inside chat rooms. - **System Messages Types** — same per-event picker as the global setting, but applied just to this chat room. Untick a type to silence it here only. Changes take effect immediately for everyone in the room. Test Chat Room showing a :::info Chat rooms are the only place where you can **force-enable** system messages past a site-wide off setting. Group and private conversations always respect the global toggle. ::: ## Good to know - **Removed vs. left** — when a moderator removes someone, the conversation shows *"Alice was removed from the conversation"*, not *"Alice left the conversation"*. The "left" line is reserved for voluntary leaves. - **Banned vs. left** — a ban also removes the participant under the hood, but only the *"was banned"* line is shown — there's no extra "left" line cluttering the history. - **Group calls aren't repeated** — once *"Alice started a group audio call"* appears, the same call type stays silent for the next five minutes. Audio and video are tracked separately, so a video call right after an audio one still gets its own line. - **Inviter attribution** — when someone is added by another participant, the line shows *"Alice was added to the conversation by Bob"*. If multiple people are added at once by the same person, you get *"Alice and Bob were added to the conversation by Carol"*. - **History is preserved** — turning a setting off later doesn't remove past system messages. It only stops new ones from being created. --- ## Rich Text Message Formatting in WordPress Chat # Text Formatting Better Messages provides a **visual formatting toolbar** above the message input — select text, click a button, formatting applied. No syntax to remember, no Markdown to learn. For power users who prefer typing syntax, [Markdown](/docs/features/markdown-support/) works alongside the toolbar — both produce identical results. ## What it adds - Visual toolbar above the message input with formatting buttons - Bold, *italic*, underline, ~~strikethrough~~, inline `code`, code blocks, and clickable links - Select-then-click or click-then-type — both workflows supported - Identical rendering for sender and recipient — what you see is what they see - Works in every conversation type — DMs, group chats, chat rooms - Pairs with Markdown — users can use either or both ## Available formatting | Toolbar action | Effect | Markdown equivalent | |---|---|---| | **B** | **Bold text** | `**bold**` | | *I* | *Italic text* | `*italic*` | | U | Underlined text | (no Markdown form) | | S | ~~Strikethrough~~ | `~~strikethrough~~` | | 🔗 | Clickable [link text](https://example.com) | `[text](url)` | | `<>` | `Inline code` and code blocks | `` `code` `` and ```` ```code``` ```` | ## When to use the toolbar vs Markdown | User profile | Recommended approach | |---|---| | Non-technical end users | Toolbar — visual, discoverable | | Developer / technical communities | Markdown — faster while typing | | Mobile users | Markdown — toolbar is harder on a phone | | Mixed audience | Both — each user picks naturally | The toolbar is **always available** even when Markdown is the user's preferred input method — they can fall back to clicking when they don't remember the exact syntax. ## How to enable Text formatting is **enabled by default**. No setting to flip. To hide the toolbar (e.g., for a minimalist chat surface), customize the CSS to hide the toolbar element. ## Frequently asked questions ### Can I extend the toolbar with my own button (e.g. for a custom format)? The toolbar buttons are built into the React component tree and aren't currently exposed as a public extension point. If you need a custom button, the maintained path is to copy the editor toolbar into a child JS bundle, register it via the standard plugin override pattern, or [open a feature request](/roadmap/). ### Does formatting survive when messages are edited? Yes — edits preserve formatting. The original Markdown source is what's stored, so structure is maintained across edits. ### What happens if a recipient is on an older device that doesn't support certain CSS? The HTML used for formatting (``, ``, ``, ``, ``, ``, `
`) is universally supported. Even older devices render formatted messages correctly.

### Does formatting appear in email notifications?
Yes — email notifications include the formatted HTML, so bold and italic render correctly in modern email clients. Inline code and code blocks render in monospace.

### Can administrators restrict which formatting options are available?
The toolbar is hard-coded in the frontend. To restrict (e.g. disable code blocks), hide the corresponding buttons with custom CSS targeting their class names in **Appearance → Customize → Additional CSS**.

## See also

- [Markdown support](/docs/features/markdown-support/) — typed syntax alternative to the toolbar
- [Message reactions](/docs/features/message-reactions/) — emoji reactions on messages
- [Reply, edit, forward](/docs/features/reply-edit-forward/) — message-level actions
- [Mentions](/docs/features/mentions/) — @-mention picker

---

## Translate WordPress Chat Into Any Language

# Translations

Better Messages is **fully translatable using WordPress's native i18n system**. Every user-facing string is wrapped with standard WordPress translation functions, so any translation tool — [Loco Translate](https://www.wordplus.org/loco-translate), WPML, Polylang, or hand-edited `.po` files — works out of the box. Translations are distributed through WordPress.org's translation platform: when your site language matches a published translation, WordPress installs the `.mo` file automatically into `wp-content/languages/plugins/`.

## What it adds

- Every user-facing string is translatable through standard WordPress tools
- WordPress.org auto-installs translations for the site language whenever they're available
- Customize beyond translation — rephrase strings to match your brand voice
- Compatible with Loco Translate, WPML, Polylang, and any `.po/.mo` workflow
- Text domain: `bp-better-messages`
- RTL languages (Arabic, Hebrew, Persian, Urdu) mirror the entire UI automatically

## Available translations

Better Messages is community-translated on [translate.wordpress.org](https://translate.wordpress.org/projects/wp-plugins/bp-better-messages/). The plugin ships with the source `bp-better-messages.pot` template; WordPress.org fills in `.mo` files for every locale that has been translated to the required coverage threshold. To see the current status of your locale (and contribute missing strings), visit the WordPress.org translations dashboard for the plugin.

## How it works

WordPress determines which language to load based on the site's WordPress language setting (or per-user language if a multilingual plugin is active). Better Messages relies on the standard WordPress `.mo` lookup — the file in `wp-content/languages/plugins/` (auto-installed from WordPress.org, or a custom file you place there) is loaded for the current locale.

| Translation source | Priority |
|---|---|
| Loco Translate site-specific overrides | Highest — overrides everything |
| Custom `.po/.mo` in `wp-content/languages/plugins/` | Higher than the WordPress.org default |
| WPML / Polylang per-user language | Per-user override |
| WordPress.org auto-installed translation | Default fallback when no custom file exists |

## When to translate

| Audience | Approach |
|---|---|
| Single-language site | Bundled translation activates automatically with site language |
| Multilingual site (per-user language) | Use WPML or Polylang — each user sees their language |
| Brand-customized strings | Loco Translate — override individual strings even in English |
| Untranslated language | Hand-create a `.po` file via Loco Translate or POEdit |
| RTL site | See [RTL support](/docs/features/rtl-support/) — direction auto-mirrors |

## How to translate

### Using Loco Translate (recommended)

1. Install and activate the [Loco Translate](https://www.wordplus.org/loco-translate) plugin
2. Navigate to **WP Admin → Loco Translate → Plugins → Better Messages**
3. Click **New language** to add a translation
4. Translate strings using the built-in editor
5. Save — strings activate immediately

### Using WPML or Polylang

These plugins automatically detect translatable strings from Better Messages and include them in their translation workflows. Each user sees the language they selected.

### Manual translation

Place your `.po/.mo` files in `wp-content/languages/plugins/` following WordPress naming: `bp-better-messages-{locale}.po`.

## Frequently asked questions

### Can different chat rooms have different languages?
The plugin renders in the user's session language, not per-room. To force a specific language per-room, hook the standard WordPress `locale` filter (or `determine_locale`) and return a custom locale based on the request context — Better Messages will then load the matching `.mo` file.

### Are AI bot replies translated?
The AI bot replies in whatever language the conversation is in (the LLM detects context). UI strings around the message (timestamps, sender labels) are translated via standard i18n.

### How do I contribute translations back to the project?
Translations are managed via Loco Translate locally. To contribute back to the bundled set, contact support — community translations are accepted and bundled in future releases.

### What if a string isn't translated yet — does it break the UI?
No — untranslated strings fall back to English. The UI never breaks; users see English text for any string not yet translated in their language.

### Does the mobile app respect translations too?
Yes — the mobile app uses the same translation files. The OS language determines what's loaded.

## See also

- [RTL layout support](/docs/features/rtl-support/) — Arabic, Hebrew, Persian, Urdu
- [AI message translation](/docs/features/ai-message-translation/) — auto-translate user messages between languages (WebSocket version)
- [Translate WordPress chat blog post](/blog/translate-wordpress-chat-multilingual/) — feature overview

---

## Unread Conversations Filter in WordPress Chat

# Unread Conversations Filter

Better Messages adds an **unread filter toggle** to the conversation list — one click hides every read thread and shows only the ones with new messages. Essential for users who run busy inboxes (community managers, marketplace vendors, support reps, instructors) where dozens of threads compete for attention.

## What it adds

- One-click filter button in the conversation list header
- Toggles between "All conversations" and "Unread only" views
- Configurable unread counter — count unread **messages** OR unread **conversations**
- Works across DMs, group chats, and chat rooms
- Filter state remembered per-session — survives page reloads
- Live updates — a new message arriving changes the filter result instantly (WebSocket version)

## How it works

The unread filter is a UI-only toggle that doesn't delete or archive anything — it temporarily hides read threads from the rendered list. The underlying data is unchanged. Clicking "All conversations" restores the full list.

| Counter mode | What the badge shows |
|---|---|
| **Unread messages** | Total count of unread messages across all threads (e.g., "47") |
| **Unread conversations** | Count of conversations with at least one unread (e.g., "12") |

The two modes serve different mental models:

- **"Unread messages"** is the traditional inbox count — useful when each message represents a task to address
- **"Unread conversations"** matches the Slack/Discord style — counts distinct threads regardless of message volume in each. Useful for community managers where one chatty thread shouldn't dominate the badge

## When to use each counter mode

| Site type | Suggested counter mode |
|---|---|
| Support / help desk | **Messages** — each message is potentially a question to answer |
| Community manager dashboard | **Conversations** — focus on which threads need attention, not how chatty each is |
| Marketplace vendor inbox | **Messages** — each buyer message is a potential sale |
| LMS instructor | **Conversations** — each student thread is one "context" to mentally load |
| Personal messaging | **Conversations** — matches the iMessage / WhatsApp pattern |

## How to enable

Navigate to **WP Admin → Better Messages → Settings → Messaging**.

- **Enable Unread Filter** — Show the unread filter button in the conversation list
- **Unread Counter** — Choose between counting unread **messages** or unread **conversations**

## Frequently asked questions

### Does the filter affect search and notifications?
No. Search results show matches across all threads regardless of the filter. Notifications continue to fire for new messages in read or filtered threads — the filter only changes the visual presentation of the list.

### What counts as "read"?
A conversation is read when the user has opened it and the latest message has appeared in their viewport for at least 1 second. The read flag is per-user — your read state doesn't affect other participants.

### Can I have separate counter modes for different users?
No — the counter mode is a site-wide setting. To support per-user preferences, customize the React component via the [JavaScript hooks](/hooks/js-filters/).

### Is the filter available in mini-chat popups?
Mini-chats show a single conversation at a time, not a list, so the filter doesn't apply there. The unread count badge on the mini-chat trigger respects the configured counter mode.

### Does the unread filter respect muted conversations?
Yes. Muted conversations don't contribute to the unread count and are not surfaced by the filter even when they have unread messages.

## See also

- [Conversation muting](/docs/features/conversations-muting/) — silence noisy threads without leaving
- [Search](/docs/features/search/) — find specific messages across all conversations
- [Site notifications](/docs/features/site-notifications/) — how unread state ties into in-app notifications
- [Favorite messages](/docs/features/favorite-messages/) — bookmark messages independent of read state

---

## Block Users in WordPress Chat

# User to User Block

Better Messages gives every chat user a built-in **Block** action that stops another user from sending them messages. The block is one-directional and reversible, with role-based controls for which user roles can block and which roles are immune from being blocked — so site staff and moderators can always reach users for safety reasons.

## What it adds

- One-click **Block** action from any conversation, profile, or message author menu
- One-directional logic — the blocker can still message the blocked user if they choose
- Blocked users cannot start new threads with or send messages to the blocker
- Role-based permission to use the Block action (e.g., paid members can block, anonymous can't)
- Role-based immunity from being blocked (e.g., moderators, support staff, admins)
- Unblock at any time from the user's personal block list

## How it works

When user A blocks user B, the plugin stores a one-directional block record in the database. From that moment:

| Action | Outcome |
|---|---|
| B tries to start a new thread with A | Blocked — UI hides the "Send Message" button on A's profile |
| B sends a message to an existing thread with A | Blocked — message rejected with a user-friendly notice |
| A sends a message to B | Allowed — the block is one-directional |
| B sends a message to a group chat that includes A | **Allowed** — group conversations are not affected |
| A unblocks B | Communication resumes immediately, prior history preserved |

The "Immune Roles" setting overrides the block — a user in an immune role (typically administrators or support staff) can still message a user who blocked them. This prevents the block feature from being used to evade moderation contact.

## When to use

Common deployment patterns:

| Site type | Configuration |
|---|---|
| Dating / fan community | Everyone can block; only admins immune |
| LMS with cohort discussions | Students can block peers but not instructors (instructor role immune) |
| Marketplace (Dokan / WCFM) | Vendors can block buyers; site admin and shop manager immune |
| Public support forum | Anonymous/guest users can't block (low trust); registered users can |
| Telemedicine / coaching | Clients can block other clients; coach + support staff immune |

## How to enable

Navigate to **WP Admin → Better Messages → Settings → Restrictions**.

- **Allow Users to Block** — Enables the Block action throughout the messenger UI
- **Roles That Cannot Block** — User roles whose users do NOT see the Block action (typically guest/anonymous)
- **Immune Roles** — User roles whose users are exempt from being blocked (typically Administrator, Shop Manager, custom moderator roles)

## Frequently asked questions

### Is the block visible to the blocked user?
No — the block is silent. The blocked user sees the same UI but their "Send Message" attempts fail with a generic "Cannot send message" notice rather than naming the blocker. This is intentional to avoid retaliation.

### Does blocking affect group chats?
No. Group conversations and chat rooms are not affected by user-to-user blocks. If user B and user A are in the same group, B's messages still appear to A. To exclude a user from a group, the room admin should remove them directly.

### Can administrators see who has been blocked by whom?
Yes — the block records are stored in the database and can be inspected by an admin via direct SQL or by extending the admin UI. There's no built-in admin "View all blocks" screen in the current version.

### Can a user be blocked by many people?
Yes, there's no cap. Each block is an independent A→B record. A user who is blocked by 100 others simply cannot message any of those 100, but can message everyone else normally.

### What happens if I block someone then we're both in a guest conversation?
Guest conversations follow the same rules as regular conversations — direct messages are blocked, but if both users participate in a multi-party guest chat (chat room), messages are still delivered.

## See also

- [GDPR-compliant messaging](/blog/gdpr-compliant-wordpress-messaging/) — privacy controls including blocking
- [Block users feature post](/blog/block-users-wordpress-chat/) — full feature write-up
- [Role-based access](/blog/role-based-access-wordpress-chat/) — granular role permissions across the messenger
- [Auto-delete messages](/docs/features/auto-delete-messages/) — message lifetime controls for privacy

---

## Verified User Badges in WordPress Chat

# Verified User Badges

Better Messages displays **verified-user badges** next to display names throughout the messenger — in conversation headers, member lists, mini-chat tooltips, and message author labels. The verification status is pulled from your community plugin (BuddyPress, PeepSo, BuddyBoss, Ultimate Member, etc.), so there's no separate database to maintain — verified once in your community plugin, badged everywhere in chat.

## What it adds

- Verified badge icon shown beside the user's display name in every messenger surface
- Automatic sync from the connected community plugin — no manual badge management
- Visible in DMs, group chats, chat rooms, mini-chats, and members directories
- Helps users distinguish official accounts, paid members, or trusted contributors at a glance
- No additional setting in Better Messages — the integration handles the lookup transparently

## How it works

When Better Messages renders a user item (in a conversation header, a message author label, a recipient picker, or a members directory), it calls the connected community plugin's "is user verified" check. If the plugin reports the user as verified, the badge icon is appended next to the display name.

The badge styling matches your community plugin's visual treatment, so verified users look consistent across the site:

| Plugin | Source of verification |
|---|---|
| **BuddyPress** | xProfile "Verified" field, or BuddyPress verified user extensions |
| **PeepSo** | PeepSo Profile Verification add-on |
| **BuddyBoss** | BuddyBoss "Verified Members" feature |
| **Ultimate Member** | UM "Verified Users" extension |

If multiple community plugins are active, Better Messages uses whichever one declares the user verified — verifying in any one source is enough.

## When verification badges matter

| Site type | Why verified badges help |
|---|---|
| Community / social network | Distinguishes original creators from look-alike accounts |
| Marketplace (Dokan / WCFM) | Marks officially-vetted vendor accounts vs new sign-ups |
| LMS | Shows instructors / TAs apart from students at a glance |
| Membership site | Visually rewards paying members with status |
| Fan / paid newsletter community | Signals creator accounts vs subscribers |

## Frequently asked questions

### Can I add a custom verified-badge source from my own plugin?
Yes — hook the `better_messages_is_verified` filter, which receives `(bool $verified, int $user_id)`. Return `true` for any user your plugin considers verified, based on whatever logic you choose (custom user meta, role check, external API, etc.).

### What does the badge icon look like?
The badge is a small checkmark icon rendered next to the user's name. It scales with the surrounding text and respects the messenger's light/dark theme.

### Are verified badges shown to non-logged-in users?
Yes — in chat rooms with guest access, guests see verified badges on participants too. The badge is a visual property of the message author and is rendered for all viewers.

### Does verification gate any messenger feature?
No. Verification is a display-only signal. To gate features by verification, combine the `better_messages_is_verified` check with the `better_messages_can_send_message` filter to allow or reject a send based on the sender's verified status.

### Why doesn't a verified user show the badge?
Check that the community plugin's verification field for that user is set correctly, and that the integration declaring verified status is enabled. The plugin reads the verification flag via the `better_messages_is_verified` filter — make sure that filter is hooked by the integration responsible for verifying users.

## See also

- [Role-based access](/docs/features/role-based-access/) — gate features by WordPress role
- [BuddyPress integration](/docs/integrations/buddypress/) — full BuddyPress integration details
- [PeepSo integration](/docs/integrations/peepso/) — PeepSo integration details
- [BuddyBoss integration](/docs/integrations/buddyboss/) — BuddyBoss integration details

---

## White-Label WordPress Chat Plugin

# White Label by Default

Better Messages is **white-label out of the box** — your end users see a messaging experience that looks like part of your site, with **no "Better Messages" branding, no "Powered by" link, and no attribution anywhere in the user-facing UI**. Combined with color customization and full string translation, you can make the messenger feel entirely custom-built for your platform.

## What it adds

- No "Better Messages" or "Powered by" attribution shown to end users
- Full color customization via the WordPress Customizer
- Every UI string is translatable / overridable to match your brand voice
- No outbound branding links from the chat interface
- Seamlessly inherits your active theme's design tokens (fonts, border radius, color scheme)
- Optional **white-label mobile app build** — ship your own iOS/Android app with your branding (WebSocket version + dedicated service)

## What's visible to end users

| UI element | What it says |
|---|---|
| Plugin labels | Your brand's terminology (configurable via translation strings) |
| Notification emails | Your site name and brand colors |
| Popup notifications | Your message preview, no plugin name |
| Mobile app (default web) | Branded as your site name |
| Mobile app (custom build) | Fully your brand — own app icon, name, splash screen |
| Admin UI (WP Admin) | Contains "Better Messages" branding (admin-only, not user-facing) |

The only place "Better Messages" appears is in the **WP Admin settings panel** (since admins need to know what they're configuring). Your end users never see the plugin name.

## How to customize for full brand match

### 1. Colors

**WP Admin → Appearance → Customize → Better Messages** — set the accent color used across buttons, links, badges, highlights.

### 2. UI strings

Translate or override any visible text using:

- [Loco Translate](https://www.wordplus.org/loco-translate) plugin — visual translation editor
- [WPML](https://wpml.org/) for multilingual sites
- A custom `.po` file in your child theme

Every visible label, button text, placeholder, and error message is translatable.

### 3. Notification email branding

Default emails use your WordPress site name and the same email layout your site uses for other transactional emails. If BuddyPress or BuddyBoss is installed, Better Messages registers its emails as standard BuddyPress email posts — you can edit subject, body, and styling at **WP Admin → Emails**. Without BuddyPress, a simple HTML template is used; you can also intercept the outgoing mail with the standard WordPress `wp_mail` filter.

### 4. Mobile app branding (advanced)

For sites that want a fully branded iOS / Android app with their own icon, name, and bundle ID, a [white-label mobile app build service](/docs/category/mobile-app/) ships a customized version of the native app on the App Store and Google Play under your brand. WebSocket version required; contact support for scope and pricing.

## How to enable

White label is **already on by default** — no setting to flip. Just install and customize colors/strings as you wish.

## Frequently asked questions

### Is there any "Powered by" link visible to my users?
No. The plugin shows zero attribution in the user-facing interface. The only branding appears in the WP Admin settings panel where admins log in — invisible to end users.

### Can I use my own logo in the messenger?
The messenger doesn't display a logo by default — it lives inside the page layout of your active theme, so the surrounding header/branding is whatever your theme already shows. To add a logo inside the chat surface, target the messenger DOM with custom CSS (for example a `::before` block on the conversation header) under **Appearance → Customize → Additional CSS**.

### What about the mobile app — does it say "Better Messages"?
The default native app on the App Store and Google Play is listed under the generic Better Messages name. Push notifications and the in-app messenger still show **your site's name** (taken from your WordPress site title), but the store listing and app icon are the generic ones. The white-label mobile-app build service ships your own listing, icon, and bundle ID — see the mobile app docs.

### Are notification emails branded?
Yes — emails use your WordPress site name, accent color, and site URL. The footer doesn't link back to Better Messages.

### Can I rebrand the admin panel too?
The admin panel keeps the "Better Messages" name (so site owners know which plugin they're configuring). To deep-customize the admin, fork a child plugin — not a supported scenario for most use cases.

## See also

- [Easy customization](/docs/features/easy-customization/) — colors, layouts, custom CSS
- [Mobile app](/docs/category/mobile-app/) — including the white-label app build service
- [White label blog post](/blog/white-label-wordpress-chat-plugin/) — feature deep-dive
- [Translations](/docs/features/translations/) — modify every UI string

---

## Better Messages Developer API — REST, Hooks, Filters

# WordPress-Native Developer API

Better Messages is built on **standard WordPress conventions** — every meaningful event in the messaging workflow is exposed as a PHP action, every data point is filterable, and every server interaction has a REST endpoint. Theme authors, plugin developers, and site builders can extend or override behavior without forking the plugin.

## What it adds

- REST API — full programmatic access to threads, messages, users, and settings ([REST reference](/rest-api/))
- PHP actions — hook into events like message sent, conversation created, participant added ([PHP actions reference](/hooks/php-actions/))
- PHP filters — modify data like message text, user permissions, displayed names ([PHP filters reference](/hooks/php-filters/))
- JavaScript hooks — extend the frontend with `wp.hooks`-style actions and filters
- Custom CSS hooks — every UI surface has stable class names for styling
- Standard WordPress coding patterns — no proprietary frameworks, no compiled-only formats

## Hook prefix

Hooks were originally prefixed `bp_better_messages_*` (legacy from BuddyPress origins). The current prefix is `better_messages_*`. Both prefixes are still honored for backwards compatibility — existing customizations don't break on upgrade.

```php
// Modern form (preferred — most new code uses this)
add_action('better_messages_message_sent', 'my_message_listener');

// Legacy form (still works — many established hooks live under this prefix)
add_filter('bp_better_messages_after_format_message', 'my_custom_renderer', 10, 4);
```

## What you can build with the API

| Customization | Hooks involved |
|---|---|
| Restrict who can send a message | `better_messages_can_send_message` filter (return `false` to block) |
| Add a custom message renderer (e.g. Markdown extensions) | `bp_better_messages_after_format_message` filter |
| Trigger an integration on every new message | `better_messages_message_sent` action |
| Auto-archive old threads | WP-Cron + REST API `DELETE /threads/{id}` |
| Display a custom badge next to user names | `bp_better_messages_display_name` filter |
| Override the verified-badge source | `better_messages_is_verified` filter |
| Notify external system on conversation creation | `bp_better_messages_new_thread_created` action |
| Customize the AI-bot mention placeholder behaviour | `better_messages_ai_providers_info` filter |

## REST API at a glance

The REST API lives at `/wp-json/better-messages/v1/`. Authenticated requests use the standard WordPress REST authentication (cookie + nonce for logged-in users, application passwords for external apps).

Key endpoints:

- `GET /threads` — list conversations for the current user
- `POST /threads` — create a new conversation
- `GET /threads/{id}/messages` — fetch a thread's messages
- `POST /threads/{id}/messages` — send a message
- `GET /users` — search users for the recipient picker

Full reference with request/response shapes is at [/rest-api/](/rest-api/).

## Frequently asked questions

### Is the REST API rate-limited?
WordPress's REST API doesn't rate-limit by default. Better Messages adds soft limits on a few endpoints (recipient picker, search) to prevent abuse. Rate limits are filterable — see the developer reference.

### How do I authenticate REST calls from a separate frontend app?
Use WordPress's [application passwords](https://wordpress.org/documentation/article/application-passwords/) feature. Each user can generate a per-app password and you authenticate via Basic Auth on the REST endpoint.

### Can I create messages on behalf of a user without their session?
Yes — server-side PHP code (running as the bot or as an admin) can call `Better_Messages()->functions->new_message()` directly, bypassing REST authentication.

### Do hooks fire for AI bot messages?
Yes. AI bot messages flow through the same hook pipeline as user messages — your custom action handlers will be invoked.

### Where can I see the full hooks reference?
See the [Hooks & functions reference](/hooks/php-functions/) in the sidebar, organized by PHP actions, PHP filters, PHP functions, JS actions, JS filters, and JS functions.

## See also

- [REST API reference](/rest-api/) — full endpoint documentation
- [PHP functions reference](/hooks/php-functions/) — internal functions you can call
- [PHP actions reference](/hooks/php-actions/) — events you can hook into
- [PHP filters reference](/hooks/php-filters/) — data you can modify
- [WordPress chat REST API blog post](/blog/wordpress-chat-rest-api-developers/) — practical examples

---

## What is Better Messages? Real-Time Messaging Plugin for WordPress

# What is Better Messages?

**Better Messages** is a real-time private messaging and chat room plugin for WordPress. It powers private one-to-one conversations, group chats, public and private chat rooms, voice messages, voice and video calls, AI chat bots, end-to-end encrypted threads, and native iOS / Android mobile apps — all on top of the standard WordPress stack you already run.

Whether you are building a social network, online community, marketplace, membership site, LMS, directory, or any other site where users need to talk to each other, Better Messages provides the messaging layer.

## What it powers

A short list of the major capabilities:

- **Private one-to-one conversations** and **group chats** with shared history
- **Chat rooms** — persistent public or members-only rooms with role-based or guest access
- **File sharing** with EXIF / metadata stripping, resumable TUS uploads, and proxy-protected URLs
- **Voice messages** (separate add-on, works on both versions)
- **Voice and video calls** — one-on-one and group, inside any thread (WebSocket version)
- **AI chat bots** powered by OpenAI, Anthropic Claude, and Google Gemini (WebSocket version + AI add-on)
- **Better Messages Cloud AI** — content moderation, message translation, voice transcription (WebSocket version)
- **End-to-end encryption** — opt-in per thread (WebSocket version)
- **Web push** and **mobile app push notifications**
- **34+ native integrations** with the major community, marketplace, LMS, directory, and creator-platform plugins
- **REST API** and **PHP / JavaScript hooks** for developer customization
- **Fully translatable** via standard WordPress tools (30+ community translations ship with the plugin)
- **White-label** by default — no plugin branding shown to end users

## Two versions

Better Messages comes in two flavors that share the same plugin codebase. The mode is determined by which license you activate — no reinstall, no separate plugin.

### Free (AJAX) version

The free version, available on [WordPress.org](https://wordpress.org/plugins/bp-better-messages/), uses **AJAX polling** for real-time messaging. The browser asks the server every few seconds for new messages — no separate server infrastructure required. Runs on any WordPress hosting, including shared hosts.

### WebSocket version

The WebSocket version is a paid license that switches real-time delivery from AJAX polling to **instant WebSocket push** on a hosted cloud relay. The relay is **included with the license** — no separate server to deploy, no third-party realtime service to configure or bill against, and no extra load on your WordPress hosting (the WebSocket connection talks to the cloud relay, not to your origin). Beyond instant delivery, the WebSocket version unlocks one-on-one and group voice / video calls, AI Chat Bots, Better Messages Cloud AI (content moderation, message translation, voice transcription), end-to-end encryption, web push notifications, mini-chat popups from profiles and members directories, mobile-app real-time delivery, and the white-label mobile app rebuild service.

Pricing for the WebSocket version starts at **$14.99 / month**, or **$11.99 / month** billed annually ($143.88 / year). Single-site license, paid via Freemius. See the [full pricing page](/docs/pricing/) for plan-by-plan details and a feature comparison.

### Self-hosted plan

For sites with strict data-sovereignty requirements (GDPR Article 9 regulated data, HIPAA-adjacent workloads, jurisdictional rules about which servers may transit data), consider upgrading to the **self-hosted plan**. The WebSocket layer runs on infrastructure you control instead of the Better Messages cloud relay. Pricing is **$25 / month** billed annually ($299.99 / year) and includes a one-time installation service. See the [pricing page](/docs/pricing/#self-hosted) for full details.

For most sites the default cloud WebSocket version is GDPR-compatible by itself — the relay is blind to message content (no storage, no inspection), and all message data lives only in your WordPress database. See [Privacy & GDPR](/docs/features/privacy-gdpr/) for the full data-flow picture.

## Get started

1. **[Install Better Messages from WordPress.org](https://wordpress.org/plugins/bp-better-messages/)** — it works immediately on any WordPress site.
2. Open **WP Admin → Better Messages → Settings → General** and set your **Messages Location** (the WordPress page where the messenger lives) or use a community-plugin profile tab if you run BuddyPress / BuddyBoss / Ultimate Member / PeepSo.
3. (Optional) Pick the integration for your community / marketplace / LMS / directory plugin under **Better Messages → Settings → Integrations**.
4. (Optional) Activate the WebSocket version under **Better Messages → Account** for instant delivery, calls, AI features, and the rest of the paid feature set.

## Where to go next

- [Installation guide](/docs/getting-started/installation/)
- [Conversation types](/docs/getting-started/conversation-types/) — DMs, group chats, chat rooms
- [User inbox](/docs/getting-started/user-inbox/)
- [Integrations catalogue](/docs/category/integrations/) — all 34+ supported plugins
- [Features catalogue](/docs/category/features/) — every messenger feature in detail
- [REST API reference](/rest-api/) — for developers
- [Hooks & functions reference](/hooks/php-functions/) — for theme / plugin authors extending Better Messages
- [Blog](/blog) — 80+ posts on features, integrations, and use cases

## Who builds Better Messages

I'm **Andrij Tkachenko**, an **indie developer from Ukraine**. Better Messages is my full-time work — and has been since the first version shipped on WordPress.org on **January 5, 2017**. Nine years and counting, one developer, one continuous line of development.

Working independently is what makes the plugin move fast on what matters most. A feature ships when it is ready. A bug fix lands the same day it is reported. A security patch goes out the same hour. Roadmap priorities adjust to what real WordPress sites actually need — not to what fits a quarterly chart somewhere else.

Security and reliability are personal commitments. I investigate every reported vulnerability, write the disclosure, and ship the fix. I monitor the WebSocket cloud and debug incidents on the live infrastructure when something goes wrong. After nine years of running this plugin in the wild, I have a hands-on understanding of what makes a WordPress messenger dependable, and I take that seriously.

Most of Better Messages' functionality is **free on WordPress.org**, and stays that way. If you need WebSocket features — instant delivery, voice / video calls, AI features, end-to-end encryption — upgrading to the WebSocket version is also a great way to support continued development of the plugin, which I greatly appreciate.

If you have any questions or need help, reach out at **support@better-messages.com**.

---

## Conversation Types in Better Messages — DMs, Groups, Chat Rooms

# Conversation Types

Better Messages supports several conversation types, each suited to a different community pattern. All types share the same messaging surface — file sharing, reactions, replies, mentions, calls, AI bots — but differ in how participants are added and how persistent the thread is.

## Private (one-to-one) conversations

The default type. Two users start a thread from the new-conversation screen, exchange messages with full history, and the conversation is private to those two participants. The most common pattern for member-to-member messaging on community sites and marketplaces.

## Group conversations

Multi-participant DMs — three or more users in a single private thread, started from the new-conversation screen by picking multiple recipients. Moderators (creator + admins) can invite or remove participants over time. See [Group conversations](/docs/features/group-conversations/) for the full feature reference.

## Chat rooms

Persistent rooms with admin-set membership rules. Administrators create chat rooms from **WP Admin → Better Messages → Chat Rooms**, then embed them anywhere with the generated shortcode. Each room defines its own role-based access (allowed roles, guest access, optional join restrictions). Rooms can be configured to appear in user inboxes or to be embed-only.

See [Chat rooms](/docs/features/chat-rooms/) for details.

## Synced group chats

A special integration mode that mirrors user groups from third-party plugins into Better Messages threads. The Better Messages addon listens for join / leave events on the host plugin and keeps the thread participants in sync automatically.

Currently supported group sources:

- [BuddyPress Groups](https://buddypress.org/) — see [BuddyPress integration](/docs/integrations/buddypress/)
- [BuddyBoss Groups](https://www.buddyboss.com/) — see [BuddyBoss integration](/docs/integrations/buddyboss/)
- [PeepSo Groups](https://www.peepso.com/) — see [PeepSo integration](/docs/integrations/peepso/)
- [Ultimate Member Groups](https://ultimatemember.com/extensions/groups/) — see [Ultimate Member integration](/docs/integrations/ultimate-member/)
- [FluentCommunity Spaces](https://fluentcommunity.co/) — see [FluentCommunity integration](/docs/integrations/fluentcommunity/)

## Mass messaging

Not strictly a conversation type, but worth knowing about: **mass messaging** lets administrators send a broadcast as individual 1-on-1 DMs to many recipients at once — each recipient gets a private thread with the sender, not a shared group. Useful for site-wide announcements that still feel personal. See [Mass messaging](/docs/features/mass-messaging/).

## See also

- [User inbox](/docs/getting-started/user-inbox/) — where conversations of all types appear
- [Chat rooms](/docs/features/chat-rooms/)
- [Group conversations](/docs/features/group-conversations/)
- [Integrations catalogue](/docs/category/integrations/)

---

## Install Better Messages — WordPress Plugin Setup Guide

# Installation

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## How to install

Installing Better Messages follows the standard WordPress plugin install flow — no special steps required.

### From WP Admin

1. Open **Plugins → Add New** in WP Admin
2. Search for **Better Messages**
3. Click **Install Now**, then **Activate**
4. Configure under **Better Messages → Settings**

### Manual upload

1. Download the plugin ZIP from the [WordPress.org plugin page](https://wordpress.org/plugins/bp-better-messages/)
2. Upload the ZIP via **Plugins → Add New → Upload Plugin**, or unzip into `/wp-content/plugins/bp-better-messages/`
3. Activate the plugin under **Plugins**
4. Configure under **Better Messages → Settings**

## Integration setup

If you run a community / marketplace / LMS plugin, follow its integration guide for the recommended setup:

* [BuddyPress](/docs/integrations/buddypress/)
* [BuddyBoss](/docs/integrations/buddyboss/)
* [PeepSo](/docs/integrations/peepso/)
* [Ultimate Member](/docs/integrations/ultimate-member/)
* [Full integrations catalogue](/docs/category/integrations/) — all 34+ supported plugins

## Activating the WebSocket version

After install, the free (AJAX) version is active by default. To unlock instant delivery, voice / video calls, AI bots, and the rest of the paid feature set, purchase a license on the [pricing page](/docs/pricing/) and enter it under **Better Messages → Account**.

---

## Messages Location & User Inbox — Better Messages WordPress Setup

# Messages Location

Every user has a personal inbox where every conversation they are part of is listed — DMs, group conversations, chat rooms, and synced group chats all show up here. The user can open any thread and reply directly from this page.

Better Messages — User Inbox

## Choosing the messages location

The messenger needs a **Messages Location** — the page on your site that hosts the inbox. Set it once under **WP Admin → Better Messages → Settings → General**:

Better Messages — Location setting

The location can be any of:

- A regular WordPress page (the page can be anywhere in your site — usually `/messages/` or similar)
- A community-plugin profile tab — BuddyPress, BuddyBoss, Ultimate Member, PeepSo, or FluentCommunity inject the inbox into the user's profile page
- A theme-provided account page — WooCommerce My Account, LearnPress / Tutor LMS / MasterStudy student account, Houzez / RealHomes / Directorist / Classified Listings / Motors dashboards, etc. (the specific integration page surfaces the inbox automatically)

## Guest Messages Page

If the chosen location is anything other than a regular WordPress page (i.e. an integration-embedded inbox) and **Guest Chat** is enabled, a second picker appears for the **Guest Messages Page**: a regular WordPress page where guests (and logged-in users) can reach the messenger directly without needing to navigate the host plugin's profile UI.

See [Guest access → Guest Messages Page](/docs/features/guest-access/#guest-messages-page) for the full setup.

## See also

- [Conversation types](/docs/getting-started/conversation-types/) — what shows up in the inbox
- [Mini widgets](/docs/features/mini-widgets/) — bottom-of-screen quick access to the inbox from anywhere on the site
- [Guest access](/docs/features/guest-access/) — letting visitors message without a WP account

---

## Better Messages for AutomatorWP: Send Automated Private Messages


The **AutomatorWP integration** for Better Messages registers a new action — **Send a private message to the user** — that any AutomatorWP automation can use. Trigger by any AutomatorWP event (form submission, course completion, role change, payment, etc.) and send a private Better Messages DM with full token support for dynamic content. Works on both the free and WebSocket versions.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install AutomatorWP

**[Download AutomatorWP](https://www.wordplus.org/automatorwp)** from official website and install following standard WordPress installation process

### How to install Better Messages with AutomatorWP
1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress
3. Use the **Better Messages** -> **Settings** menu to configure the plugin

### Supported actions

#### Send a private message to the user



## See also

- [AutomatorWP send private message](/blog/automatorwp-send-private-message/) — full feature write-up with use cases
- [Uncanny Automator integration](/docs/integrations/uncanny-automator/) — same feature on Uncanny Automator
- [GamiPress integration](/docs/integrations/gamipress/) — common pairing for points-based workflows
- [AI Chat Bots](/docs/features/ai-chat-bots/) — for automated bot-driven replies

---

## BuddyBoss Messaging Plugin: Modern Chat for Platform & ReadyLaunch

# Better Messages for BuddyBoss: Modern Messaging for BuddyBoss Platform & ReadyLaunch

The **BuddyBoss integration** for Better Messages takes over every BuddyBoss messaging surface — header inbox icon, profile dropdown unread counter, member-row Send Message button — and auto-disables BuddyBoss Live Messaging on activation. The integration ships **two theme paths**: a **BuddyBoss ReadyLaunch** path (header dropdown, side-menu badge, hover-card Message button, automatic dark mode sync) and a **classic BuddyBoss Theme** path that has been polished for years. BuddyBoss Friends drives the messenger's Friends widget; BuddyBoss Groups can be auto-paired with group chats; the WebSocket version adds members-directory Audio Call and Video Call icons. Works on both the free and WebSocket versions of Better Messages.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install BuddyBoss

**[Download BuddyBoss](https://www.wordplus.org/buddyboss)** from the official website and install it following the standard WordPress plugin installation process.

### How to install Better Messages with BuddyBoss
1. Install **[Better Messages from WordPress.org](https://wordpress.org/plugins/bp-better-messages/)** through the WordPress plugins screen, or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory
2. Activate the plugin through the **Plugins** screen in WordPress
3. Open **Better Messages → Settings** to configure the plugin
4. Set **Messages Location** to **Show in BuddyBoss profile**, or pick a dedicated WordPress page as the messages homepage

### Supported features

When you activate Better Messages on a BuddyBoss site:

- BuddyBoss Live Messaging is automatically deactivated (no double-messenger conflict)
- BuddyBoss Web Push is wired in
- Every BuddyBoss messages link (header inbox, profile dropdown, member rows) now points at Better Messages
- Avatars and profile URLs inside Better Messages map back to BuddyBoss profiles
- BuddyBoss Messages restrictions are honored

## BuddyBoss ReadyLaunch

Better Messages includes a dedicated **[ReadyLaunch](https://www.wordplus.org/buddyboss-readylaunch)** rendering path that lights up automatically the moment ReadyLaunch is enabled at *BuddyBoss → ReadyLaunch*. It matches ReadyLaunch's design tokens (typography, primary color, spacing), follows the ReadyLaunch dark mode setting, and lays the messenger out flush with the ReadyLaunch content area.

Better Messages on the BuddyBoss ReadyLaunch Messages page

### Header inbox dropdown

The chat-bubble icon in the ReadyLaunch header opens a dropdown listing the most recent conversations from Better Messages, with a live unread counter on the icon. Clicking a thread jumps straight into the conversation.

ReadyLaunch header inbox dropdown showing recent Better Messages conversations

### Profile Messages tab

When the messenger is rendered inside the profile (the default), it appears under the **Messages** tab of the ReadyLaunch profile alongside the native Timeline, Connections, and Groups tabs. The page header, tabs, and right-side Details widget all stay visible.

Better Messages rendered inside the ReadyLaunch profile Messages tab

### Full-page messenger

For sites that prefer a chat-first layout, the **Full-page messenger** setting hides the profile avatar, tabs, and right sidebar on the Messages screen so the messenger takes over the entire ReadyLaunch content area. The URL stays the same — `/members/{user}/bp-messages/` — only the chrome around the messenger is removed.

Three companion toggles let you fine-tune the full-page layout:

- **Full Width Layout** — removes the page padding so the messenger stretches edge to edge
- **Page Title** — shows a `Messages` heading at the top of the page, matching the secondary header used by Forums, Members, and Groups
- **Hide Mini Widget on Messages Page** — hides the floating chat bubble and mini chat windows while the messenger is already open

### Members directory: Send Message, Audio Call, Video Call

Each row in the ReadyLaunch members directory and group member list gets icons for **Send Message**, **Audio Call**, and **Video Call** alongside the native Connect button — styled to match ReadyLaunch's circular icon buttons.

ReadyLaunch members directory list view with Better Messages icons next to each row

:::info
Audio and Video Call icons are part of the **[WebSocket version](/docs/pricing/)**. Enable them at *Better Messages → Settings → Integrations → BuddyBoss* with the **Members Directory Audio Call** and **Members Directory Video Call** toggles. They respect the existing **Calls → Only Friends Can Call** restriction.
:::

### Hover-card Send Message button

Hovering an avatar on the ReadyLaunch activity feed and elsewhere opens the native BuddyBoss hover card. The integration restyles the **Send Message** button inside that hover card so its label is properly centered and the icon matches the rest of the ReadyLaunch action buttons.

### Automatic light / dark mode sync

ReadyLaunch has a built-in dark mode toggle (or it can be forced to dark via *BuddyBoss → Settings → General → ReadyLaunch*). The integration listens to the `bb-rl-dark-mode` class on `` and switches the messenger to its **dark** palette automatically — no second toggle to flip.

BuddyBoss ReadyLaunch dark mode with Better Messages following the same theme

### bbPress: Private Message in the actions dropdown

When bbPress is active alongside ReadyLaunch, every forum reply renders a **Private Message** entry inside the existing reply actions dropdown — next to Edit, Move, Split, Spam, and Trash — instead of as plain text under the author block. The classic BuddyBoss Theme path uses an inline icon between Reply and More actions; ReadyLaunch uses the dropdown because that is how ReadyLaunch organizes reply controls.

bbPress reply in ReadyLaunch with Private Message added to the More actions dropdown

### Settings reference

Open *Better Messages → Settings → Integrations → BuddyBoss* on a ReadyLaunch-enabled site to see the **BuddyBoss ReadyLaunch** and **BuddyBoss Theme** sections side by side. Only the section matching the currently-active theme rendering is editable; the other section shows an explanatory notice.

Better Messages admin settings: BuddyBoss ReadyLaunch and BuddyBoss Theme sections with all four toggles

## Classic BuddyBoss Theme

The classic BuddyBoss Theme (pre-ReadyLaunch) is fully supported and has the same full-page layout toggles in its own section — **Full-page messenger**, **Page Title**, and **Hide Mini Widget on Messages Page**. When ReadyLaunch is enabled, the BuddyBoss Theme section appears disabled with a notice explaining the active rendering.

Better Messages on the classic BuddyBoss Theme Messages page in full-page mode

### Header inbox dropdown

The chat-bubble icon in the classic BuddyBoss header carries a live unread counter and opens a dropdown listing the most recent conversations — same flow as the ReadyLaunch path.

Classic BuddyBoss header inbox dropdown showing recent Better Messages conversations

### BuddyBoss Friends

The Friends widget inside the messenger is populated from BuddyBoss Friends — no separate friends list to maintain. Three placements are available: mini bar, mobile bar, and the standard messenger sidebar.

Friends list inside the Better Messages sidebar

### BuddyBoss Groups

Each BuddyBoss group can have an attached group chat. The chat is created the first time the group is opened in Better Messages; members are synced both ways — joining the BuddyBoss group adds the user to the chat, leaving removes them. A group admin can disable the chat for any specific group.

Groups list inside the Better Messages sidebar

### Video & Audio call buttons on user profiles (WebSocket Version)

Call buttons on a BuddyBoss user profile

:::info
Profile-level call buttons are part of the **[WebSocket version](/docs/pricing/)**. Enable them at *Better Messages → Settings → Integrations → BuddyBoss* with the **Audio Call Button** and **Video Call Button** toggles.
:::

### Live unread counter in the BuddyBoss profile dropdown

The Messages item in the BuddyBoss Theme profile dropdown (top-right avatar) carries a live unread counter that updates in real time alongside the existing header inbox icon. The badge uses the same blue style as the native Connections / Notifications badges and hides automatically when there is nothing new.

Profile dropdown unread counter

### Audio & Video Call icons in the members directory (WebSocket Version)

Each row in the classic BuddyBoss members directory (and group member lists) gets dedicated **Audio Call** and **Video Call** icons next to the Send Message icon. Clicking the icon starts a one-to-one call without first opening a thread. The two icons are independent toggles, gated by the existing friends-only restriction (when **Calls → Only Friends Can Call** is enabled, non-friends won't see the buttons), and hidden on the current user's own row.

Audio and Video Call icons in the classic BuddyBoss members directory

:::info
Members-directory Audio and Video Call icons are part of the **[WebSocket version](/docs/pricing/)**. Enable them under *Better Messages → Settings → Integrations → BuddyBoss* with the **Members Directory Audio Call** and **Members Directory Video Call** toggles.
:::

BuddyBoss settings tab with Members Directory call toggles

### bbPress Private Message link in BuddyBoss Theme

When **[bbPress](https://www.wordplus.org/bbpress)** is also active, the **Private Message** link on every forum reply is rendered as a native inline icon — placed between the **Reply** and **More actions** controls — so it matches the BuddyBoss action-row design instead of floating as plain text between the author header and the post body. Hovering shows a "Private Message" tooltip; clicking opens a new conversation with the reply's author.

bbPress reply with native Private Message icon between Reply and More actions

:::info
Enable the link at *Better Messages → Settings → Integrations → bbPress* with the **Show "Private Message" link in BBPress** toggle. Vanilla bbPress sites without the BuddyBoss Platform are unaffected — the link renders below the author block as plain text per bbPress's standard template.
:::

## Frequently asked questions

### Does Better Messages replace BuddyBoss Live Messaging?

Yes — on activation, BuddyBoss Live Messaging is automatically disabled to avoid a double-messenger conflict. BuddyBoss's underlying message data is preserved.

### Does the integration support BuddyBoss ReadyLaunch?

Yes. The moment ReadyLaunch is enabled at *BuddyBoss → ReadyLaunch*, Better Messages switches to the ReadyLaunch rendering path automatically — header dropdown, side-menu badge, profile Messages tab, members-directory call icons, and automatic dark mode sync. No setting needs to be flipped on the Better Messages side. The classic theme path is preserved for sites that have not enabled ReadyLaunch.

### Will the BuddyBoss header inbox icon still work?

Yes — the icon stays where it is, with the same blue badge style, but now opens the Better Messages inbox. On ReadyLaunch the same icon opens a dropdown listing recent conversations; on the classic theme it links straight to the messages screen.

### Does dark mode work?

Yes. On ReadyLaunch the messenger follows the site's dark mode setting (forced light, forced dark, or per-user choice) automatically. On the classic BuddyBoss Theme, the messenger uses its own light / dark setting under *Better Messages → Settings → Appearance*.

### Does it work with the BuddyBoss native mobile app?

The BuddyBoss native app uses BuddyBoss's own messaging stack. Better Messages ships its own **[iOS / Android app](/blog/wordpress-chat-mobile-app/)** (Capacitor-based) with white-label rebuild support.

### Can members block each other?

Yes — the **[User Block](/docs/features/user-block/)** feature lets any member block another. Admins can also globally block users from **Better Messages → Reports**.

### Does it work with bbPress on BuddyBoss?

Yes — on the classic BuddyBoss Theme, every forum reply gets an inline Private Message icon between the Reply and More actions buttons. On ReadyLaunch the Private Message entry is added to the reply actions dropdown instead of as a separate icon.

## See also

- [BuddyBoss messaging plugin](/blog/buddyboss-messaging-plugin/) — full feature write-up
- [WordPress community chat plugin](/blog/wordpress-community-chat-plugin/) — comparing community platforms
- [BuddyPress integration](/docs/integrations/buddypress/) — for BuddyPress sites
- [PeepSo integration](/docs/integrations/peepso/) — for PeepSo sites
- [Group conversations](/docs/features/group-conversations/) — how group chats work
- [WordPress video call plugin](/blog/wordpress-video-call-plugin/) — group calls inside thread
- [WordPress chat mobile app](/blog/wordpress-chat-mobile-app/) — native iOS / Android apps
- [Real-time messaging](/docs/features/realtime-messaging/) — what changes with the WebSocket version

---

## Better Messages for BuddyPress: Modern Real-Time Private Messaging


The **BuddyPress integration** for Better Messages takes over every BuddyPress messaging link — header inbox, profile Messages tab, member-row Send Message button — and replaces the legacy messenger with a modern real-time experience. BuddyPress Friends drives the messenger's Friends widget; BuddyPress Groups can be auto-paired with group chats whose members sync with the source community group. Works on both the free and WebSocket versions of Better Messages.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install BuddyPress

**[Download BuddyPress](https://www.wordplus.org/buddypress)** from official website and install following standard WordPress installation process

### How to install Better Messages with BuddyPress
1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress
3. Use the **Better Messages** -> **Settings** menu to configure the plugin
4. Set **Messages Location** to **Show in BuddyPress profile** or you can also set any WordPress page to be a messages homepage

### Video demonstration



### Supported features

When you install BuddyPress plugin with Better Messages:

- All links to private messages automatically points to Better Messages
- All avatars in Better Messages interface automatically displayed from BuddyPress user profiles
- All links to user profiles in Better Messages interface automatically points to BuddyPress user profiles
- Automatically integrated to BuddyPress Friends with ability to create Friends List directly in plugin interface
- Automatically integrated to BuddyPress Groups with ability to create Groups List directly in plugin interface

    The feature also allow to create Better Messages Group chats automatically based on groups members,
    with automatic removal and adding users from chat, when they're leaving or joining the group.

## Frequently asked questions

### Does Better Messages replace the BuddyPress messages component or coexist with it?

It takes over the same URLs, so members never see the old component. The BuddyPress messages component can be left active — Better Messages does not require disabling it.

### What happens to existing BuddyPress message threads?

The data stays in the database. Better Messages reads existing BuddyPress threads on first install and continues them inside the new messenger.

### Does it work with BuddyBoss?

Yes — BuddyBoss is a BuddyPress fork. Better Messages has a dedicated BuddyBoss integration. See the [BuddyBoss integration](/docs/integrations/buddyboss/).

### Can members block each other?

Yes — the **User Block** feature lets any member block another. Configure under **Better Messages → Settings → Restrictions**.

### Is there a mobile app?

Yes — a native iOS / Android app (Capacitor-based) with push notifications. White-label rebuild is available.

## See also

- [BuddyPress messaging plugin](/blog/buddypress-messaging-plugin/) — full feature write-up
- [WordPress community chat plugin](/blog/wordpress-community-chat-plugin/) — comparing community platforms
- [BuddyBoss integration](/docs/integrations/buddyboss/) — for BuddyBoss Platform sites
- [PeepSo integration](/docs/integrations/peepso/) — for PeepSo sites
- [Ultimate Member integration](/docs/integrations/ultimate-member/) — for UM sites
- [Group conversations](/docs/features/group-conversations/) — paired group chats
- [Real-time messaging](/docs/features/realtime-messaging/) — what changes with the WebSocket version

---

## Better Messages for Classified Listing (RTCL): Seller ↔ Buyer Chat


The **Classified Listing integration** for Better Messages adds a Live Chat button on the listing page (inside Seller Information), on archive cards (opt-in), on author and store pages, plus a Messages tab inside the My Account dashboard, and a floating header chat icon with live unread badge. Conversations started from a listing show the listing's image, title, price, and location as a context card. Works on both the free and WebSocket versions.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install Classified Listing

**[Download Classified Listing](https://www.wordplus.org/classified-listing)** from the WordPress.org plugin directory and follow the standard WordPress installation process.

### How to install Better Messages with Classified Listing

1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress.
3. Use the **Better Messages** -> **Settings** menu to configure the plugin.
4. Go to **Integrations -> Directories** and enable the **Enable Classified Listing Integration** toggle in the **Classified Listing Integration** section. Each placement below has its own toggle so you can enable only what you need.

Settings

## Setting Classified Listing as the messages location

Better Messages → **Settings** → **General** has a **Messages Location** dropdown that controls which page hosts the user inbox. Selecting **Show in Classified Listing Account** routes every "open inbox" link in the plugin (notification emails, push notifications, the floating header icon, the unread-counter shortcode, etc.) into the Classified Listing **My Account** → **Messages** tab. The dashboard tab is force-enabled and locked while this option is selected — change Messages Location away from Classified Listing to unlock it again.

Messages location

## Using Classified Listing Pro alongside Better Messages

Classified Listing Pro ships its own bundled realtime chat. Better Messages will happily coexist with it — both buttons render side by side on the listing page, and both inboxes work independently.

:::info
For the cleanest experience we recommend disabling Pro's built-in chat (Classified Listing → Settings → Chat → uncheck **Enable Chat**) so visitors only see one **Live Chat** button. Better Messages gives you a WordPress-native inbox, guest chat, attachments, calls and AI bots without any third-party dependencies.
:::

## Supported features

#### Live Chat button on the listing page

Renders inside the **Seller Information** widget next to the existing **Chat** and **Email to Seller** rows. The button is hidden when the listing is not published or when the visitor is the listing's author.

Listing page

#### Live Chat button on archive listing cards

Adds a small icon button on each card in the archive grid and list views. Disabled by default — opt in via the **Archive Card Button** toggle.

:::note
Some commercial themes (e.g. Classima) replace Classified Listing's card template with their own and skip the loop hooks the integration uses, so the auto-injected card button only appears on themes that keep the default RTCL loop templates. On those themes the **Listing Page Button** and **Header Chat Icon** still work as expected.
:::

#### Live Chat button on author and store pages

Adds a Live Chat button on the listing author archive and on the store profile page (when the **Classified Listing Store** add-on is in use). Renders via the `rtcl_author_after_info` and `rtcl_store_after_seller_information` hooks; on themes that replace those templates use the shortcode below instead.

#### Header chat icon

Injects a chat-bubble icon into the site header next to the existing **My Account** and (when Pro is active) **Chat** icons. Inherits the theme's native header-icon styling so it looks like a built-in menu item, and shows a live unread-count badge that updates in real time. Disabled by default — opt in via the **Header Chat Icon** toggle.

Header chat icon

#### Messages tab inside the My Account dashboard

Adds a **Messages** tab to the Classified Listing **My Account** sidebar next to *My Listings*, *Store*, *Payments* and (when Pro is active) *Chat*. The full Better Messages inbox renders inside the dashboard layout.

:::info
After enabling this option for the first time, visit **Settings → Permalinks** and click **Save Changes** to register the new endpoint. Without that step the tab will appear in the sidebar but its URL will 404.
:::

Dashboard tab

#### Listing info card inside the conversation

Conversations started from a Classified Listing listing show the listing's image, title, price and location inside the Better Messages thread. The seller's name in the conversation links to their author archive on the site.

Thread info

## Shortcodes for custom placement

If the auto-injected buttons don't land where you want them (custom layout, sidebar widget, page builder, etc.), drop the matching shortcode wherever you need.

:::info
Disable the corresponding toggle (**Listing Page Button** / **Author Profile Button** / **Header Chat Icon**) before placing the shortcode, otherwise the button will be rendered twice — once auto-injected and once by the shortcode.
:::

### `[better_messages_classified_listing_button]`

Renders the **Live Chat** button targeted at the listing owner. Falls back to the current Classified Listing post when no `listing_id` is supplied.

| Attribute | Default | Notes |
|---|---|---|
| `listing_id` | current post | Override the listing the button targets |
| `user_id` | listing author | Override the message recipient |
| `class` | RTCL primary button classes | Override CSS classes |
| `text` | `Live Chat` | Override the button label |

```text
[better_messages_classified_listing_button]
[better_messages_classified_listing_button listing_id="42"]
[better_messages_classified_listing_button text="Contact seller" class="rtcl-btn rtcl-btn-secondary"]
```

### `[better_messages_classified_listing_author_button]`

Renders the **Live Chat** button on a listing author archive or store page. Resolves the author from the queried object by default.

| Attribute | Default | Notes |
|---|---|---|
| `user_id` | author of the page | Override the message recipient |
| `class` | RTCL primary button classes | Override CSS classes |
| `text` | `Live Chat` | Override the button label |

```text
[better_messages_classified_listing_author_button]
[better_messages_classified_listing_author_button user_id="17"]
```

### `[better_messages_classified_listing_header_button]`

Renders the header chat icon (chat bubble + unread badge) — useful when you want to place it inside a custom header block or page-builder layout instead of letting the integration auto-inject it next to the existing **Chat** / **My Account** icons.

```text
[better_messages_classified_listing_header_button]
```

## Frequently asked questions

### Does it work with Classified Listing Pro?

Yes — Pro is optional. With Pro, the Better Messages buttons render next to (or instead of) Pro's bundled chat, depending on whether you disable Pro's chat.

### Will the dashboard tab work on commercial themes like Classima?

Yes — the Messages tab uses RTCL's My Account endpoint registration, which commercial themes respect. The archive-card button depends on RTCL's default loop templates and may not auto-render on heavily-customized themes.

### Can visitors message without an account?

Optional — enable Guest Chat in **Better Messages → Settings → Guest Chat**.

### Does the header chat icon support translation / dark mode?

Yes — inherits the theme's native header-icon styling, so dark mode and RTL are handled by the theme.

### Can I place the header chat icon in a custom location?

Yes — use the shortcode `[better_messages_classified_listing_header_button]` inside a page-builder block.

## See also

- [Classified Listing chat](/blog/classified-listing-chat/) — full feature write-up
- [Directorist integration](/docs/integrations/directorist/)
- [HivePress integration](/docs/integrations/hivepress/)
- [GeoDirectory integration](/docs/integrations/geodirectory/)
- [Motors integration](/docs/integrations/motors/) — for automotive classifieds

---

## Directorist Messaging: Real-Time Chat on Listings & Profiles

# Better Messages for Directorist: Real-Time Chat on Listings and Profiles

The **Directorist integration** for Better Messages adds a Send Message button on the listing page (inside the Author Info card), on archive listing cards (opt-in), on the author profile page, and a Messages tab inside the Directorist user dashboard. Conversations started from a listing show the listing's image, title, price, and address as a context card. Works on both the free and WebSocket versions.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install Directorist

**[Download Directorist](https://www.wordplus.org/directorist)** from the WordPress.org plugin directory and follow the standard WordPress installation process.

### How to install Better Messages with Directorist

1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress.
3. Use the **Better Messages** -> **Settings** menu to configure the plugin.
4. Go to **Integrations -> Directories** and enable the **Enable Directorist Integration** toggle in the **Directorist Integration** section. Each placement below has its own toggle so you can enable only what you need.

Settings

## Setting Directorist as the messages location

Better Messages → **Settings** → **General** has a **Messages Location** dropdown that controls which page hosts the user inbox. Selecting **Show in Directorist Dashboard** routes every "open inbox" link in the plugin (notification emails, on-site links, push notifications, the floating bubble, etc.) into the Directorist user dashboard's Messages tab. The tab is force-enabled and locked while this option is selected — change the Messages Location away from Directorist to unlock it again.

Messages location

## Supported features

#### Send Message button on the listing page

Renders inside the **Author Info** card, next to Directorist's existing **View Profile** button. The button is hidden when the listing is not published or when the visitor is also the listing's author.

Listing page

#### Send Message button on archive listing cards

Adds a small icon button on each card in the archive grid and list views. Disabled by default — opt in via the **Archive Card Button** toggle.

Archive card

#### Send Message button on the author profile page

Adds a Send Message button below the author's name and "member since" line on Directorist's author profile page.

Author profile

#### Messages tab inside the Directorist user dashboard

Adds a **Messages** tab next to **My Listings**, **My Profile**, and **Favorite Listings** in the Directorist user dashboard, so users can read and reply to conversations without leaving the dashboard.

Dashboard tab

#### Listing info card inside the conversation

Conversations started from a Directorist listing show the listing's image, title, price and address inside the messages UI. Clicking the author's name or avatar in a conversation opens their Directorist author profile page rather than the default WordPress author archive.

Thread info

## Shortcodes for custom placement

If the auto-injected buttons don't land where you want them (custom layout, sidebar widget, page builder, etc.), drop the matching shortcode wherever you need.

:::info
Disable the corresponding toggle (**Listing Page Button** / **Author Profile Button**) before placing the shortcode, otherwise the button will be rendered twice — once auto-injected and once by the shortcode.
:::

### `[better_messages_directorist_listing_button]`

Renders the **Send Message** button targeted at the listing owner. Falls back to the current Directorist listing post when no `listing_id` is supplied.

| Attribute | Default | Notes |
|---|---|---|
| `listing_id` | current post | Override the listing the button targets |
| `user_id` | listing author | Override the message recipient |
| `class` | Directorist primary button classes | Override CSS classes |
| `text` | `Send Message` | Override the button label |

```text
[better_messages_directorist_listing_button]
[better_messages_directorist_listing_button listing_id="42"]
[better_messages_directorist_listing_button text="Contact owner" class="directorist-btn directorist-btn-secondary"]
```

### `[better_messages_directorist_author_button]`

Renders the **Send Message** button on a Directorist author profile. Resolves the author from the `author_id` query var by default, falling back to the standard WordPress author archive when used in a sidebar.

| Attribute | Default | Notes |
|---|---|---|
| `user_id` | author of profile | Override the message recipient |
| `class` | Directorist primary button classes | Override CSS classes |
| `text` | `Send Message` | Override the button label |

```text
[better_messages_directorist_author_button]
[better_messages_directorist_author_button user_id="17"]
```

## Frequently asked questions

### Does it work with Directorist Pro extensions?

Yes — the integration listens to Directorist's core listing and author hooks, which Pro extensions extend rather than replace.

### Can visitors message without registering?

Optional — enable Guest Chat in **Better Messages → Settings → Guest Chat**.

### Can I enable the archive-card button without the listing-page button?

Yes — each placement has its own toggle. Enable archive cards, disable the listing page button (or vice versa).

### Does it support multi-directory sites?

Yes — the button appears for every listing regardless of which Directorist directory it belongs to.

### Will it work with custom Directorist templates?

Most Directorist themes use the standard template hooks. For heavily customized themes, place buttons manually via shortcode.

## See also

- [Directorist chat](/blog/directorist-listing-chat/) — full feature write-up
- [HivePress integration](/docs/integrations/hivepress/) — for HivePress-driven sites
- [GeoDirectory integration](/docs/integrations/geodirectory/) — for GeoDirectory sites
- [Classified Listing integration](/docs/integrations/classified-listing/) — for RTCL classifieds
- [Motors integration](/docs/integrations/motors/) — for automotive listing sites

---

## Better Messages for Dokan: Live Chat for Marketplace Vendors


The **Dokan integration** for Better Messages adds a Live Chat button to every Dokan product page, vendor shop page, and vendor dashboard tab — so customers can ask a question before checkout and vendors can reply from inside their own dashboard. The integration is enabled with a single toggle, works on both the free and WebSocket versions of Better Messages, and uses Dokan's own vendor avatars and shop-profile links inside the messenger.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install Dokan

**[Download Dokan](https://www.wordplus.org/dokan)** from the official website and install it through the standard WordPress plugin installation process.

### How to install Better Messages with Dokan

1. Install the Better Messages plugin through the WordPress plugins screen, or upload the plugin files to `/wp-content/plugins/bp-better-messages`.
2. Activate the plugin through the **Plugins** screen in WordPress.
3. Use the **Better Messages → Settings** menu to configure the plugin.
4. Go to **Integrations → WooCommerce** and **Enable Live Chat for Vendors** in the **Dokan Marketplace Integration** section. When Dokan is the active marketplace plugin, this section is sorted to the top of the WooCommerce sub-tab.

Better Messages Dokan integration settings: Enable Live Chat for Vendors toggle

## Supported features

When you install Dokan plugin with Better Messages:

- Vendors get a new setting in **Shop Configuration** to enable Live Chat for their shop
- When Live Chat is enabled in Shop Configuration, a **Live Chat** tab appears on the vendor dashboard
- All vendor avatars in the Better Messages interface are automatically displayed from Dokan vendor shop profiles
- All links to vendors in the Better Messages interface automatically point to the Dokan vendor shop profile

### Live Chat tab on the vendor dashboard

The integration adds a **Live Chat** tab to the Dokan vendor dashboard, embedding the full Better Messages interface so vendors never leave their dashboard to reply to customers.

Live Chat tab on the Dokan vendor dashboard

### Live Chat button on product pages

A **Live Chat** button is added to every product sold by a vendor. If you use a custom page builder or the button does not auto-render due to template differences, use this shortcode to place it manually:

```text
[better_messages_dokan_product_button]
```

Live Chat button on a Dokan product page, below the Add to Cart form

### Live Chat button on the vendor shop page

A **Live Chat** button is added to every vendor shop page so customers browsing a vendor's full catalog can start a conversation without first picking a product.

Live Chat button on a Dokan vendor shop page next to the vendor info

## Video walkthrough



## Free vs WebSocket version for Dokan stores

| Feature | Free version | WebSocket version |
| --- | :---: | :---: |
| Live Chat on product / shop / dashboard | yes | yes |
| Per-vendor enable / disable | yes | yes |
| Vendor avatars and profile links from Dokan | yes | yes |
| Product context card in threads | yes | yes |
| Support for Dokan 4.x and 5.0+ | yes | yes |
| Real-time delivery | polling | instant |
| Mini-widget popup chat | — | yes |
| One-on-one voice and video calls inside the thread | — | yes |
| Group voice and video calls (vendor team) | — | yes |
| Web push notifications for new messages | — | yes |
| Read receipts | — | yes |
| End-to-end encryption (optional) | — | yes |

:::info
For Dokan marketplaces where vendors compete on responsiveness, the WebSocket version's instant delivery plus web push pulls vendors in even when their dashboard is closed — and the mini-widget popup keeps the customer on the product page while they wait for a reply.
:::

## Frequently asked questions

### Can customers message a vendor without registering?

Yes — enable **Guest access** in **Better Messages → Settings → Guest Chat**. A first-time customer enters a name and email, then chats with the vendor. The thread is preserved if they later register.

### Can vendors message each other?

Yes. The vendor dashboard chat is a full messenger, not a vendor-to-customer-only widget. Vendors can also be added to group conversations.

### Does it work with WooCommerce subscriptions and bookings?

Yes — Dokan's WooCommerce extensions do not change the product page template hook that Better Messages uses. If you have heavily customized the product template, place the shortcode above manually.

### Does the Live Chat button work with the new Dokan Vendor Dashboard UI?

Yes — Better Messages added support for the new Dokan Vendor Dashboard UI in v2.11.0.

### Is the WebSocket cloud server hosted by you?

Yes — the WebSocket license includes hosted relay servers, no extra Node.js server to run. A self-hosted option is also available if your data residency rules require it.

## See also

- [Dokan vendor chat plugin](/blog/dokan-vendor-chat-plugin/) — full write-up with screenshots and use-case framing
- [WordPress marketplace chat](/blog/wordpress-marketplace-chat/) — comparing Dokan, WCFM, WC Vendors, and MultiVendorX
- [WCFM Marketplace integration](/docs/integrations/wcfm/)
- [MultiVendorX integration](/docs/integrations/multivendorx/)
- [WC Vendors integration](/docs/integrations/wc-vendors/)
- [WooCommerce integration](/docs/integrations/woocommerce/) — for WooCommerce stores without a multi-vendor layer
- [Real-time messaging](/docs/features/realtime-messaging/) — what changes with the WebSocket version

---

## Better Messages for FluentCommunity: Real-Time Spaces and Course Chat


The **FluentCommunity integration** adds a real-time messenger to your FluentCommunity portal. It plugs straight into the parts of FluentCommunity people already use — Spaces, Courses, member profiles, and the portal header.

You get:

- Paired **group chats for every Space** with messaging enabled.
- Auto-managed **Course group chats** and a **Message Instructor** button on every course page.
- Voice and video call buttons on every profile (WebSocket version).
- Automatic dark-mode mirroring — the messenger follows your portal theme.

Works on both the free and the WebSocket version of Better Messages.

If you already use **Fluent Messaging**, deactivate it after you install Better Messages. Running both at once causes a double-messenger conflict.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install FluentCommunity

**[Download FluentCommunity](https://www.wordplus.org/fluentcommunity)** from official website and install following standard WordPress installation process

### How to install Better Messages with FluentCommunity
1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress
3. Use the **Better Messages** -> **Settings** menu to configure the plugin
4. Set **Show in FluentCommunity Portal** in Better Messages location settings.
5. If you are using **Fluent Messaging** - disable it as it makes no sense to use it together with **Better Messages**
6. Go to **WP Admin** -> **Better Messages** -> **Settings** -> **Integrations** -> **FluentCommunity** and configure integration

:::note
The **FluentCommunity** tab in Better Messages integration settings only appears when the FluentCommunity plugin is installed and active.
:::

### Supported features

When you install the FluentCommunity plugin with Better Messages:

- Automatically place messages page button to header menu and mobile bottom menu
- Automatically adds private message, video and audio call buttons to user profiles
- All avatars in Better Messages interface are automatically displayed from FluentCommunity user profiles
- All links to user profiles in Better Messages interface automatically point to FluentCommunity user profiles
- Automatic switch between dark and light modes based on FluentCommunity settings
- Automatically integrated to FluentCommunity Spaces with ability to create Spaces List directly in plugin interface

    The feature also allows to create Better Messages Group chats automatically based on Space members,
    with automatic removal and adding users from chat, when they're leaving or joining the Space.

- Automatically integrated to FluentCommunity Courses — auto-managed Course Group Chats, a "Course Chat" button next to "Continue Course", and a "Message Instructor" button on the course creator card

### Profile page

Profile Page

## Spaces Integration

Better Messages integrates with FluentCommunity Spaces to provide group messaging for Space members.

### How it works

- Each Space with messaging enabled automatically gets a group chat thread
- When users join or leave a Space, they are automatically added to or removed from the group chat
- Space admins can enable or disable messaging per Space from the Space settings

### Spaces settings

You can configure Spaces messaging from **WP Admin** -> **Better Messages** -> **Settings** -> **Integrations** -> **FluentCommunity**:

- **Space Messages** — enable or disable group messaging for Spaces globally
- **File Uploading** — allow or disallow file uploads in Space messages
- **Email Notifications** — send email notifications for new messages in Spaces
- **Push Notifications** — send push notifications for new messages in Spaces (requires WebSocket license)

### Spaces widgets

Spaces can be displayed in multiple widget locations within Better Messages:

- **Mini Widgets** — small widget fixed to the bottom of the browser window showing the list of Spaces
- **Side Panel Tab** — a "Spaces" tab in the side conversations panel
- **Mobile Tab** — a "Spaces" tab at the bottom of the screen in mobile full screen mode

These can be enabled from **WP Admin** -> **Better Messages** -> **Settings** -> **Widgets**.

### Per-Space settings

Each Space has its own messaging toggle. Space admins and moderators can enable or disable group messaging from the Space settings page within FluentCommunity.

## Courses Integration

Better Messages also integrates with FluentCommunity Courses — a separate post type from Spaces, with its own enrollment model and creator-as-instructor concept. Course chats are kept distinct from Space chats: they live in the dedicated [Courses widget](/docs/features/mini-widgets/), alongside LearnDash, LearnPress, Tutor LMS and MasterStudy LMS courses.

### Course page buttons

When a student opens a published course, two buttons appear on the course detail page:

- **Course Chat** — sits next to **Continue Course** at the top right of the course page. Opens the auto-managed group chat that includes the course creator and every active student.
- **Message Instructor** — appears under the course creator card in the right sidebar. Opens a private one-on-one conversation with the course creator. Hidden when the current user *is* the creator (you don't need a button to message yourself).

FluentCommunity course page with Course Chat and Message Instructor buttons

Clicking **Course Chat** opens the auto-managed Course Group Chat:

Course Chat opened from the course page

Clicking **Message Instructor** opens a private conversation with the course creator:

Message Instructor opened from the course page

### Course Group Chat

Each Course gets its own Better Messages thread.

- The **course creator** is the instructor in the chat.
- **Students** join the chat on enrollment and leave on un-enrollment.
- Membership stays in sync through FluentCommunity's `course/enrolled` and `course/student_left` hooks.
- A self-healing diff sync runs on every event, so one missed hook will not leave the chat out of sync.

The conversation header shows the course title and image. Better Messages uses the course `logo` first, then `cover_photo`, and falls back to a graduation-cap icon if neither is set.

A **course info card** with title, image, and instructor name appears above the conversation. The same card shows on the private DM opened by **Message Instructor** — so the creator can see which course the question is about. This card is shared with LearnDash, LearnPress, Tutor LMS, and MasterStudy LMS integrations. To hide it everywhere, turn off **Better Messages → Settings → Integrations → LMS → Shared Course Settings → Course Info Card**.

### Courses widget

Once Course Group Chat is enabled, the user's enrolled and authored courses surface in the dedicated [Courses widget](/docs/features/mini-widgets/) on the Mini Widgets bar, Side Panel and Mobile bar — separate from the social Spaces widget so academic chats and community spaces don't mix in one list.

Courses widget on a FluentCommunity site showing the user's courses

The Courses widget is shared with the LearnDash, LearnPress, Tutor LMS and MasterStudy LMS integrations: if your site has both FluentCommunity Courses and an LMS plugin, all courses appear in the same widget.

### Courses settings

Configure courses messaging from **WP Admin** -> **Better Messages** -> **Settings** -> **Integrations** -> **FluentCommunity**:

- **Course Group Chat** — master toggle for the FluentCommunity Courses integration. Enables the auto-managed Course Group Chats and the Courses widget entries.
- **Course Chat Button** — show the **Course Chat** button next to **Continue Course** on FluentCommunity course pages. Requires Course Group Chat enabled.
- **Message Instructor Button** — show the **Message Instructor** button under the course creator card. Hidden automatically when the current user is the course creator.

### Shared course settings

Three toggles under **Better Messages → Settings → Integrations → LMS → Shared Course Settings** apply to every LMS course conversation across LearnDash, LearnPress, Tutor LMS, MasterStudy LMS and FluentCommunity Courses:

- **Course Info Card** *(on by default)* — show the title, image and instructor name banner above each course conversation, including the private DM opened by **Message Instructor**. Turn off to hide the banner everywhere.
- **Email Notifications** *(on by default)* — send the standard "new message" email to participants when activity happens in a course chat. Turn off if your students do not rely on email or you want to reduce traffic.
- **Push Notifications** *(off by default)* — send browser and mobile push notifications for new course messages. Requires a WebSocket license.

Changing any of these toggles propagates across all four LMS integrations.

### Per-Course settings

Each Course has its own messaging toggle. Course creators can enable or disable group messaging from the Course settings page within FluentCommunity, in the same way Spaces have a per-Space toggle.

## Frequently asked questions

### Does it replace Fluent Messaging?

Yes — Fluent Messaging should be deactivated when Better Messages is installed. Better Messages takes over the portal's Messages surfaces.

### Will Space chats persist if the Space is deleted?

The paired chat thread remains in the database for record-keeping. Members lose access via the Space, but Better Messages preserves the history.

### Can I have a Space chat without enabling messaging globally?

No — Space group messaging is a global toggle. Once enabled globally, individual Spaces can opt in or out.

### Does it work alongside other LMS plugins?

Yes — FluentCommunity Courses, LearnDash, LearnPress, Tutor LMS, and MasterStudy LMS share the Courses widget and shared course settings (Info Card, Email, Push).

### Can FluentCommunity members message each other 1-on-1?

Yes — every FluentCommunity profile gets a Private Message button. With the WebSocket version, Audio Call and Video Call buttons can be enabled.

## See also

- [FluentCommunity chat plugin](/blog/fluentcommunity-chat-plugin/) — full feature write-up
- [WordPress community chat plugin](/blog/wordpress-community-chat-plugin/) — comparing community platforms
- [WordPress LMS chat plugin](/blog/wordpress-lms-chat-plugin/) — comparing every LMS integration
- [BuddyPress integration](/docs/integrations/buddypress/)
- [BuddyBoss integration](/docs/integrations/buddyboss/)
- [Group conversations](/docs/features/group-conversations/) — underlying group chat feature

---

## Better Messages for GamiPress: Charge Points to Message or Call


The **GamiPress integration** allows charging users for messaging and private calls using GamiPress point types — per-message, per-new-thread, per-call, per-role, and per-conversation-type. The user's balance can be displayed inline in the messenger with a configurable URL where they can manage or top up points. Supported through a unified Points System with provider abstraction, shared with MyCred.

Better Messages Points Systems settings — GamiPress provider with per-role New Message Pricing grid

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install GamiPress

**[Download GamiPress](https://www.wordplus.org/gamipress)** from official website and install following standard WordPress installation process.

### How to install Better Messages with GamiPress
1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress.
3. Use the **Better Messages** → **Settings** → **Integrations** → **Points Systems** menu to configure the integration.

## Configuration

### Point Type

Select which GamiPress point type to use for charging.

### Charge Types

- **New message** — charge when a user sends a message
- **New thread** — charge when a user creates a new conversation

### Charge Categories

Different rates can be configured for each conversation type:

- **Private threads** — one-on-one conversations
- **Groups** — group conversations
- **Chat rooms** — chat room messages

### Per-Role Pricing

Different charge amounts can be set per WordPress user role for messages, new threads, and calls. Voice and video calls bill **per call minute** (first minute charged at start; calls end gracefully if the balance drops below one more minute mid-call).

Private Call Pricing settings — per-role per-minute rates for voice and video calls

### AI Usage Charging

Points can be charged for AI bot responses. This is configured per-bot in the AI Bots settings.

### Balance Display

The user's point balance can be shown in multiple locations:

- Chat header
- Threads list (top)
- Threads list (bottom)
- User menu
- User menu popup
- Reply form area

### Balance URL

A configurable external URL can be set where users can manage or purchase points. The balance pill in the messenger links to this URL — typically a WooCommerce points-top-up product or a custom checkout.

Messenger UI showing the GamiPress balance pill in the user menu and inside the reply form area

## See also

- [Pay-to-Message with MyCred and GamiPress](/docs/features/mycred-gamipress/) — canonical feature reference (shared across both providers)
- [GamiPress pay-to-message](/blog/gamipress-pay-to-message/) — full feature write-up
- [Build a monetized DM platform](/blog/wordpress-monetized-messaging-platform/) — vertical walk-through with per-message + per-call billing
- [MyCred integration](/docs/integrations/mycred/) — same feature on the MyCred points engine
- [AI Chat Bots](/docs/features/ai-chat-bots/) — for charging points per AI bot response
- [Role-based access](/docs/features/role-based-access/) — for per-role pricing setup

---

## Better Messages for GeoDirectory: Chat with Listing Owners


The **GeoDirectory integration** for Better Messages adds a Send Message button on every GeoDirectory listing page. Conversations started from a listing show the listing's image, title, address, and price as a context card. GeoDirectory author profile links are used throughout the messenger. Works on both the free and WebSocket versions.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install GeoDirectory

**[Download GeoDirectory](https://www.wordplus.org/geodirectory)** from the WordPress.org plugin directory and follow the standard WordPress installation process.

### How to install Better Messages with GeoDirectory

1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress.
3. Use the **Better Messages** -> **Settings** menu to configure the plugin.
4. Go to **Integrations -> Directories** and enable the **Enable GeoDirectory Integration** toggle in the **GeoDirectory Integration** section.

Settings

## Supported features

#### Send Message button on the listing page

Renders next to GeoDirectory's author actions on single listing pages. The button is hidden when the listing is not published or when the visitor is also the listing's author.

Listing page

If your theme positions the button awkwardly, or you want it inside a sidebar widget or a custom layout, see [Shortcodes for custom placement](#shortcodes-for-custom-placement) below.

#### Listing info card inside the conversation

Conversations started from a GeoDirectory listing show the listing's image, title, address, and price inside the messages UI. Clicking the author's name or avatar in a conversation opens their GeoDirectory author profile page rather than the default WordPress author archive.

Thread info

## Shortcodes for custom placement

If the auto-injected button doesn't land where you want it (custom theme, sidebar, page builder, etc.), drop the shortcode wherever you need.

:::info
Disable **Listing Page Button** in the integration settings before placing the shortcode, otherwise the button will be rendered twice — once auto-injected and once by the shortcode.
:::

### `[better_messages_geodirectory_listing_button]`

Renders the **Send Message** button for the current GeoDirectory listing. Falls back to the queried/current post if used inside a sidebar on a single listing page.

| Attribute | Default | Notes |
|---|---|---|
| `listing_id` | current post | Override the listing the button targets |
| `user_id` | listing author | Override the message recipient |
| `class` | GeoDirectory primary button classes | Override CSS classes |
| `text` | `Send Message` | Override the button label |

Examples:

```text
[better_messages_geodirectory_listing_button]
[better_messages_geodirectory_listing_button listing_id="123"]
[better_messages_geodirectory_listing_button text="Contact owner" class="btn btn-secondary"]
```

## Frequently asked questions

### Does it work with GeoDirectory's paid add-ons?

Yes — the integration uses GeoDirectory's core listing hooks, which paid add-ons extend rather than replace.

### Can visitors message without an account?

Optional — enable Guest Chat in **Better Messages → Settings → Guest Chat**.

### What happens when a listing is unpublished?

The Send Message button is hidden when the listing is not published; existing threads remain readable.

### Will it work with custom GeoDirectory theme layouts?

The button auto-renders on standard layouts. For custom themes, use the shortcode inside any page builder.

### Does the listing owner get notified by email?

Yes — Better Messages' smart-batched email notifications apply.

## See also

- [GeoDirectory chat](/blog/geodirectory-listing-chat/) — full feature write-up
- [Directorist integration](/docs/integrations/directorist/)
- [HivePress integration](/docs/integrations/hivepress/)
- [Classified Listing integration](/docs/integrations/classified-listing/)
- [Motors integration](/docs/integrations/motors/) — for automotive sites
- [UsersWP integration](/docs/integrations/userswp/) — common pairing with GeoDirectory

---

## GIPHY Integration for Better Messages — Animated GIF Picker

# GIPHY

The GIPHY integration lets users browse and send animated GIFs directly from inside the message input area. The picker calls the GIPHY API on demand — no GIFs are stored on your server.

## Setup

1. [Create a GIPHY developer account](https://developers.giphy.com/) and request an **SDK key**
2. Open **WP Admin → Better Messages → Settings → Integrations → GIPHY**
3. Paste your GIPHY API key and save

The GIF button appears in the messenger reply form once the key is configured.

## Production requirements

When you move to a GIPHY production key, GIPHY requires you to display the **"Powered By GIPHY"** attribution badge on every preview. Add the CSS below to your site (via **Appearance → Customize → Additional CSS** or the `better_messages_css_customizations` filter):

```css
.bpbm-gif:before {
    position: absolute;
    content: "";
    width: 54px;
    height: 24px;
    bottom: 5px;
    right: 5px;
    background-color: black;
    background-color: rgb(0 0 0 / 50%);
    background-image: url(https://cdn.better-messages.com/images/giphy.png);
    background-repeat: no-repeat;
    background-position: center;
    background-size: 50px 18px;
    padding: 0;
    color: white;
    border-radius:3px;
    opacity: 1;
    font-size: 10px;
    line-height: 17px;
    z-index: 10;
}

.bpbm-gifs-selector-gif-container:before{
    position: absolute;
    content: '';
    bottom: 5px;
    left: 5px;
    width: 54px;
    height: 24px;
    background-color: black;
    background-color: rgb(0 0 0 / 50%);
    background-image: url(https://cdn.better-messages.com/images/giphy.png);
    background-repeat: no-repeat;
    background-position: center;
    background-size: 50px 18px;
    padding: 0;
    color: white;
    border-radius:3px;
    opacity: 1;
    font-size: 10px;
    line-height: 17px;
    z-index: 10;
}
```

## See also

- [GIPHY integration feature page](/docs/features/giphy-integration/) — full reference
- [Stickers](/docs/features/stickers/) — built-in pre-made sticker packs
- [Emoji selector](/docs/features/emoji-selector/) — unicode emoji picker

---

## Better Messages for HivePress: Listings, Bookings, and Vendor Chat


The **HivePress integration** for Better Messages adds Send Message buttons on every listing item in archive lists, every listing page, every booking list and booking page (HivePress Bookings add-on), and every vendor list and vendor page. Vendor avatars and shop-profile links use HivePress data throughout. If you are using HivePress's own Messages add-on, deactivate it after installing Better Messages to avoid a double-messenger conflict. Works on both the free and WebSocket versions.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

### Video demonstration



## Installation

### How to install HivePress

**[Download HivePress](https://www.wordplus.org/hivepress)** from official website and install following standard WordPress installation process

### How to install Better Messages with HivePress
1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress
3. Use the **Better Messages** -> **Settings** menu to configure the plugin
4. Go to **Integrations -> Directories** and **Enable Live Chat for Vendors** in **HivePress Integration** section Settings

### Supported features

When you install HivePress plugin with Better Messages, the Better Messages plugin doing the same as native HivePress Messages plugin, but providing much more features and functionality.

#### Adds Send Message button to the HivePress listing item in HivePress lists
Listing item

#### Adds Send Message button to the HivePress listing page
Listing page

#### Adds Send Message button to the HivePress booking lists and booking page
Booking list
Booking page

#### Adds Send Message button to the HivePress vendors lists and vendors page
Vendor list
Vendor page

## Frequently asked questions

### Does it work with HivePress Bookings?

Yes — Send Message buttons appear on both booking lists and individual booking pages.

### Does it work with HivePress Marketplace?

Yes — vendor pages get the Send Message button, listing pages get it, and conversations show the listing's image / title / price inside the thread context card.

### Can listings be messaged anonymously?

Optional — enable Guest Chat in **Better Messages → Settings → Guest Chat**.

### Will it work with custom HivePress themes?

Most HivePress themes use the standard template hooks, so the buttons auto-render. For heavily customized themes, place buttons manually via shortcode.

### Should I deactivate HivePress Messages?

Yes if you want a single messenger experience — running both side by side leads to confusing UX.

## See also

- [HivePress listing chat](/blog/hivepress-listing-chat/) — full feature write-up
- [WordPress real estate chat](/blog/wordpress-real-estate-chat/) — real-estate use case
- [WordPress booking platform chat](/blog/wordpress-booking-platform-chat/) — booking platform use case
- [Directorist integration](/docs/integrations/directorist/) — for Directorist sites
- [GeoDirectory integration](/docs/integrations/geodirectory/) — for GeoDirectory sites
- [Classified Listing integration](/docs/integrations/classified-listing/)

---

## Houzez Messaging: Buyer ↔ Agent Live Chat for Listings

# Better Messages for Houzez: Buyer ↔ Agent Live Chat for Real Estate Listings

The **Houzez integration** for Better Messages adds a Live Chat button on the single property page (next to native Call / Email / WhatsApp), a Live Chat button on property listing cards, a Live Chat row on agent and agency profile cards, and a Messages tab inside the Houzez user dashboard at `/dashboard-live-chat/`. Buyers reach the listing's agent — or the agency owner when no agent is set — in one click, with the property image, price and address pinned to the top of the conversation. Theme accent colors (the value configured in **Houzez Options → Styling Options → Primary Color**) are inherited automatically. Works on both the free and WebSocket versions.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install Houzez

The **[Houzez – Real Estate WordPress Theme](https://www.wordplus.org/houzez)** is a commercial theme from Favethemes. Purchase, download and activate it from **Appearance → Themes**, then install the required Houzez plugin pack (Houzez Login Register, Houzez Theme Functionality, Houzez API) and the recommended Elementor + Houzez Studio combo for page building. Once Houzez is active you'll get the property post type, agent / agency CPTs, the user dashboard at `/user-dashboard/` and the property submission flow out of the box.

### How to install Better Messages with Houzez

1. Install Better Messages through the WordPress plugins screen or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress.
3. Use the **Better Messages → Settings** menu to configure the plugin.
4. Go to **Settings → Integrations → Directories** and enable the **Enable Houzez Integration** toggle. Each placement below has its own toggle so you can enable only the ones you want.

Houzez integration settings

## Setting the Houzez dashboard as the messages location

Better Messages → **Settings → General** has a **Messages Location** dropdown that controls which page hosts the user inbox. Selecting **Show in Houzez Dashboard** routes every "open inbox" link in the plugin (notification emails, on-site links, push notifications, the floating bubble, etc.) into the **Messages** tab inside the Houzez dashboard at `/dashboard-live-chat/`. The dashboard tab is force-enabled and locked while this option is selected — change the Messages Location away from Houzez to unlock it again.

When this option is active the messenger runs full-screen inside the dashboard frame — same Houzez sidebar and topbar, edge-to-edge messenger surface, no rounded card border.

Messages Location

## Supported features

#### Live Chat button on the single property page

Renders inside the agent / agency contact panel on the single-property page, alongside Houzez's native **Call**, **Email** and **WhatsApp** actions. The button is hidden when the property is unpublished or when the visitor is also the listing's author. Colors match whatever you have configured in **Houzez Options → Styling Options → Primary Color**.

Property page

#### Live Chat button on property cards

Adds a fourth equal-width button to the action row already present on Houzez v7 property cards (grid and list views), matching the styling of the native Call / Email / WhatsApp icons exactly — same outline style, same accent color, same hover state. Hidden for cards owned by the current visitor.

Listing grid

Listing list

#### Live Chat button on agent profile pages

Adds a **Live Chat** row to the contact actions on the agent profile page, below the native **Send Email** and **Call** buttons. The button targets the WordPress user linked to the agent through Houzez's **Author Information → User** mapping, so agents see incoming conversations in their own dashboard inbox without any extra wiring.

Agent profile

#### Live Chat button on agency profile pages

Same treatment for agency profile pages — the button targets the WordPress user that owns the agency CPT, which is typically the brokerage owner. Hidden when the agency has no published agents or when the agency owner is viewing their own profile.

Agency profile

#### Messages tab inside the Houzez dashboard

Adds a **Messages** tab to the Houzez dashboard sidebar at `/user-dashboard/`, alongside the native **Properties / Favorites / Saved Searches / Invoices / Messages**. The tab loads the full Better Messages inbox inline at `/dashboard-live-chat/` so buyers and agents can read and reply without leaving their dashboard. The Houzez chrome (sidebar, topbar, account header) stays in place; only the main content panel is replaced with the messenger.

The integration **does not replace** Houzez's built-in **Messages** panel — both can coexist. If you want the native one gone, enable **Hide native Messages tab** in the Houzez integration settings; the native panel is removed from the dashboard sidebar so users only see the Better Messages tab.

Houzez dashboard with messenger

#### Unread badge on the Messages tab

The Messages entry in the Houzez dashboard sidebar carries a live unread badge — a small blue circle showing the total unread count across all of the user's conversations. The badge appears anywhere in the Houzez dashboard (Dashboard, Properties, Invoices, etc.), updates in real time as new messages arrive — instantly over WebSocket, ~5 s over AJAX polling — and clears the moment the user opens an unread thread. The count caps at `99+` for large inboxes.

Houzez dashboard sidebar with a "1" unread badge on the Messages tab

#### Listing info card inside the conversation

Conversations started from a property page or listing card show the property's image, title, price, basic specs (beds / baths / sq ft) and address pinned to the top of the messenger. Clicking the property opens the listing in a new tab.

Thread context card

#### Agent / agency persona inside every thread

Buyers always see the agent or agency CPT identity as the other side of the conversation — never the underlying WordPress account. The thread sidebar, conversation header, message sender chips, info panel, mini chat widget and call screen all show the **agent's full name and headshot** (or **agency name and logo**) from the Houzez CPT, with a clickable link straight to the agent / agency profile page.

Buyer-side view of multiple Houzez chats. Same WordPress fallback user is shown as "Mike Moore" in one thread, "Dave Harris" in another, "Jason Carter" in the third — each with their own agent CPT photo and profile link

This works **even when the agent or agency CPT has no linked WordPress user** — the chat is silently routed to the property's `post_author` (or the agency owner), but the buyer still sees the persona's name, photo and profile URL. A single fallback account can route inquiries for several different agents at once and the buyer sees each conversation as a chat with a distinct agent.

On the routed receiver's side, the messenger keeps their **real WordPress identity** in the bottom-left profile widget (no leakage into self-view) and shows a yellow **"Chatting as [Agent name]"** banner above the property card, so they always know which persona the buyer thinks they are talking to:

Agent-side view: yellow "Chatting as Mike Moore" banner above the property card, real WP identity preserved in the bottom-left profile widget

This is a reusable Better Messages mechanism — see the developer guide on [per-thread "fake users"](/docs/development/guides/per-thread-fake-users/) for how the same pattern is built into Better Messages and how to reuse it in your own integrations.

## Shortcodes for custom placement

If the auto-injected buttons don't land where you want them (custom Elementor template, sidebar widget, theme override, etc.), drop the matching shortcode wherever you need.

:::info
Disable the corresponding toggle (**Property Page Button** / **Card Button** / **Agent / Agency Button**) before placing the shortcode, otherwise the button will be rendered twice — once auto-injected and once by the shortcode.
:::

### `[better_messages_houzez_property_button]`

Renders the **Live Chat** button targeted at the property's owning agent (or agency owner when the property has no agent). Uses the current property when no `property_id` is supplied.

| Attribute | Default | Notes |
|---|---|---|
| `property_id` | current property | Override the property the button targets |
| `text` | `Live Chat` | Override the button label |

```text
[better_messages_houzez_property_button]
[better_messages_houzez_property_button property_id="1208"]
[better_messages_houzez_property_button text="Contact agent"]
```

### `[better_messages_houzez_property_card_button]`

Renders the smaller card-style **Live Chat** button used inside listing cards. Useful if you build a custom property archive template and want the same compact pill style.

| Attribute | Default | Notes |
|---|---|---|
| `property_id` | current property | Override the property the button targets |
| `text` | `Live Chat` | Override the button label |

```text
[better_messages_houzez_property_card_button]
[better_messages_houzez_property_card_button property_id="1208"]
```

### `[better_messages_houzez_agent_button]`

Renders the **Live Chat** button targeted at the WordPress user linked to a Houzez agent CPT. Uses the current agent profile when placed on a `houzez_agent` archive / single template.

| Attribute | Default | Notes |
|---|---|---|
| `agent_id` | current agent | Override the agent post the button targets |
| `text` | `Live Chat` | Override the button label |

```text
[better_messages_houzez_agent_button]
[better_messages_houzez_agent_button agent_id="42"]
[better_messages_houzez_agent_button text="Chat with this agent"]
```

### `[better_messages_houzez_agency_button]`

Renders the **Live Chat** button targeted at the WordPress user that owns a Houzez agency CPT.

| Attribute | Default | Notes |
|---|---|---|
| `agency_id` | current agency | Override the agency post the button targets |
| `text` | `Live Chat` | Override the button label |

```text
[better_messages_houzez_agency_button]
[better_messages_houzez_agency_button agency_id="9"]
[better_messages_houzez_agency_button text="Chat with this agency"]
```

## Theme color inheritance

The Live Chat buttons read **Houzez Options → Styling Options → Primary Color** and use it for the button background, the property-card outline accent, the price label inside the thread context card, and the dashboard sidebar highlight. Change the Houzez primary color and every Better Messages surface updates on the next page load — no extra configuration needed.

## Frequently asked questions

### Does it work with all Houzez Studio Elementor templates?

Buttons on the **single property page**, **agent profile**, **agency profile** and **dashboard** are auto-injected via theme hooks and work with every Houzez Studio layout. For property cards rendered through Houzez Studio's own grid widgets (rather than the v7 grid / list templates), use the `[better_messages_houzez_property_card_button]` shortcode inside the Elementor template if the auto-injection doesn't catch the custom widget.

### Should I disable the native Houzez Messages panel?

It's optional. The two messengers can coexist — the Houzez native panel stays at `/dashboard-messages/`, Better Messages lives at `/dashboard-live-chat/`. If you want a single inbox, enable **Hide native Messages tab** in the integration settings; the native panel is removed from the dashboard sidebar.

### Can buyers chat without registering?

Yes — if Guest Chat is enabled in **Better Messages → Settings → General → Guest Chat**, anonymous visitors can use the Live Chat buttons without logging in. The Houzez user dashboard at `/dashboard-live-chat/` requires login, so the Guest Chat row also exposes a **Guest Messages Page** picker — set it to a regular public WordPress page (or one-click create one) and guests reach the messenger there from every chat trigger and email link. See [Guest access → Guest Messages Page](/docs/features/guest-access/#guest-messages-page).

### What happens when a property is unpublished?

The Live Chat button is hidden when the property is not published. Existing threads remain readable.

### Can I move the Live Chat button to a different position on property cards?

The button is appended to the action row that already contains Call / Email / WhatsApp. To move it elsewhere on the card, disable **Card Button** in the integration settings and drop `[better_messages_houzez_property_card_button]` into a custom card template.

### Does it work on agent or agency CPTs that don't have a WordPress user owner?

Yes. When the agent or agency CPT has no linked WordPress user, the chat is silently routed to the property's `post_author` (or the agency owner). The buyer still sees the agent's name, headshot and profile URL in the conversation — the routed receiver sees a yellow **"Chatting as [Agent name]"** banner above the property card so they know which persona the buyer is contacting. The same fallback account can host inquiries for several different agent CPTs and every thread still shows its own distinct persona to the buyer. See the [agent / agency persona section](#agent--agency-persona-inside-every-thread) above for screenshots.

## See also

- [Houzez real estate chat](/blog/houzez-real-estate-chat/) — full feature write-up
- [Per-thread "fake users"](/docs/development/guides/per-thread-fake-users/) — how the agent / agency persona display works under the hood, with the recipe for reusing the same pattern in your own integrations
- [WordPress real estate chat](/blog/wordpress-real-estate-chat/) — adjacent real-estate use case
- [HivePress integration](/docs/integrations/hivepress/) — for HivePress-based listing sites
- [Directorist integration](/docs/integrations/directorist/) — for general directory sites
- [GeoDirectory integration](/docs/integrations/geodirectory/)
- [Motors integration](/docs/integrations/motors/) — Stylemix Motors classifieds

---

## Better Messages for Crocoblock JetEngine: Profile Builder Messaging


The **JetEngine Profile Builder integration** for Better Messages makes private-message shortcodes resolve to the correct user inside JetEngine Profile Builder templates and uses JetEngine Profile Builder avatars throughout the messenger interface when enabled. Bridges JetEngine's dynamic-content user context to Better Messages' user-id resolution layer. Works on both the free and WebSocket versions.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install Crocoblock JetEngine

**[Get JetEngine](https://www.wordplus.org/jetengine)** from official website and install following standard WordPress installation process

### How to install Better Messages with JetEngine Profile Builder
1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress
3. Use the **Better Messages** -> **Settings** menu to configure the plugin
4. Go to **Integrations** -> **Other plugins** and configure integration in **JetEngine** section

Settings

### Supported features

When you install JetEngine Profile Builder plugin with Better Messages:

- Private message shortcodes will correctly point to user when put to JetEngine Profile Builder user profiles
- All avatars in Better Messages interface automatically displayed from JetEngine Profile Builder user profiles if enabled

## See also

- [JetEngine Profile Builder messaging](/blog/jetengine-profile-builder-messaging/) — full feature write-up
- [Ultimate Member integration](/docs/integrations/ultimate-member/) — for sites running both UM and JetEngine
- [ProfileGrid integration](/docs/integrations/profile-grid/)
- [Shortcodes documentation](/docs/category/shortcodes/)

---

## Better Messages for LearnDash: Student & Instructor Messaging


The **LearnDash integration** for Better Messages adds a Message Instructor button to every LearnDash course page, an auto-managed Course Group Chat that mirrors course enrollment, a LearnDash Group cohort chat for paid Group-Leader workflows, a Send Message button on the LearnDash Instructor Role public profile, and the dedicated Courses widget on the Mini Widgets bar. The integration works on both the free and WebSocket versions of Better Messages.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install LearnDash

**[Download LearnDash](https://www.wordplus.org/learndash)** from learndash.com and install it through the standard WordPress plugin installation process.

### How to install Better Messages with LearnDash

1. Install Better Messages through the WordPress plugins screen, or upload the plugin files to `/wp-content/plugins/bp-better-messages`.
2. Activate the plugin through the **Plugins** screen.
3. Go to **Better Messages → Settings → Integrations → LMS** to enable the integrations you want.

LearnDash integration settings

## Supported features

### Message Instructor button on course page

Adds a **Message Instructor** button to every LearnDash course page. Students can open a private conversation with the course instructor with a single click.

Message Instructor button on the LearnDash course page

The button targets the user listed as the course author and is hidden for the instructor on their own course.

Enable in **Better Messages → Settings → Integrations → LMS → LearnDash Integration → Message Instructor Button**.

### Course Group Chat

When a course is opened, Better Messages automatically creates a group conversation that the course author and every enrolled student can join. Students are added on enrollment and removed when their access is revoked.

The conversation header shows the course thumbnail, title, and instructor name, so students always know which course the discussion belongs to.

LearnDash course group thread with the course info card

LearnDash exposes enrollment changes through `learndash_update_course_access`, which Better Messages listens to for both adds and removes — including the ones LearnDash performs automatically when a student is enrolled into a course via a group.

Enable in **Better Messages → Settings → Integrations → LMS → LearnDash Integration → Course Group Chat**.

The course / group info card pictured above is rendered automatically above the conversation, including on the LearnDash Group Chat below and on private DMs opened through the **Message Instructor** button. To hide it on every LMS course conversation, turn off **Better Messages → Settings → Integrations → LMS → Shared Course Settings → Course Info Card**.

### LearnDash Group Chat

LearnDash Groups (`/groups//`) are cohorts of students sharing access to one or more courses, managed by users with the **Group Leader** role. Better Messages mirrors that organisation by creating a dedicated chat for each LearnDash Group.

LearnDash Group cohort chat with group info card

Group members are kept in sync via `ld_added_group_access` and `ld_removed_group_access`, and every Group Leader assigned to the cohort is auto-joined as an instructor of the chat.

Enable in **Better Messages → Settings → Integrations → LMS → LearnDash Integration → LearnDash Group Chat**.

### Send Message button on Instructor profile

If you run the [LearnDash Instructor Role](https://www.learndash.com/instructor-role/) add-on, every instructor gets a public profile at `/instructor//`. With this toggle on, Better Messages adds a **Send Message** button to that profile, positioned right under the instructor's name.

Send Message button on the LearnDash Instructor Role profile

Clicking the button opens a private conversation with that instructor — the same flow as the **Message Instructor** button on a course page, but available from anywhere on the site that links to the instructor's profile.

:::info
This toggle is only available when the **LearnDash Instructor Role** add-on is active. It is a separate, paid LearnDash add-on and is not bundled with Better Messages.
:::

Enable in **Better Messages → Settings → Integrations → LMS → LearnDash Integration → Send Message Button on Instructor Profile**.

### Courses widget

Once Course Group Chat or LearnDash Group Chat is enabled, the user's courses and LearnDash Group cohorts surface in the dedicated [Courses widget](/docs/features/mini-widgets/) on the Mini Widgets bar, Side Panel, and Mobile bar — separate from the social Groups widget so academic chats and friend cohorts don't mix in one list.

Courses widget on a LearnDash site showing courses and a LearnDash Group cohort

Configure the icon, role restrictions and "Hide Tab When Empty" behaviour under **Better Messages → Settings → Mini Widgets → Courses**.

### Shared course settings

Three toggles under **Better Messages → Settings → Integrations → LMS → Shared Course Settings** apply to every LMS course conversation across LearnDash, LearnPress, Tutor LMS, MasterStudy LMS and FluentCommunity Courses:

- **Course Info Card** *(on by default)* — show the title, image and instructor name banner above each course conversation, including the private DM opened by **Message Instructor**. Turn off to hide the banner everywhere.
- **Email Notifications** *(on by default)* — send the standard "new message" email to participants when activity happens in a course chat. Turn off if your students do not rely on email or you want to reduce traffic.
- **Push Notifications** *(off by default)* — send browser and mobile push notifications for new course messages. Requires a WebSocket license.

Changing any of these toggles propagates across all four LMS integrations.

## Shortcodes for custom placement

If the auto-injected buttons don't land where you want them (custom layout, sidebar widget, page builder, etc.), drop the matching shortcode wherever you need.

:::info
Disable the corresponding toggle (**Message Instructor Button** / **Send Message Button on Instructor Profile**) before placing the shortcode, otherwise the button will be rendered twice — once auto-injected and once by the shortcode.
:::

### `[better_messages_learndash_course_button]`

Renders the **Message Instructor** button for a LearnDash course. Falls back to the current course post when no `course_id` is supplied.

| Attribute | Default | Notes |
|---|---|---|
| `course_id` | current post | Override the course the button targets |
| `user_id` | course author | Override the message recipient (instructor) |
| `class` | LearnDash button classes | Override CSS classes |
| `text` | `Message Instructor` | Override the button label |

```text
[better_messages_learndash_course_button]
[better_messages_learndash_course_button course_id="123"]
[better_messages_learndash_course_button text="Ask the instructor"]
```

### `[better_messages_learndash_instructor_button]`

Renders a **Send Message** button targeted at a LearnDash instructor. Resolves the instructor from the LearnDash Instructor Role profile (`/instructor//`) by default, or from the standard WordPress author archive.

| Attribute | Default | Notes |
|---|---|---|
| `user_id` | profile owner | Override the message recipient |
| `class` | LearnDash button classes | Override CSS classes |
| `text` | `Send Message` | Override the button label |

```text
[better_messages_learndash_instructor_button]
[better_messages_learndash_instructor_button user_id="42"]
```

## Frequently asked questions

### Will students from different courses end up in the same chat?

No — each LearnDash course has its own Course Group Chat. Students enrolled in multiple courses see one thread per course, surfaced together in the Courses widget.

### What happens when a student's enrollment is revoked?

LearnDash fires `learndash_update_course_access` on revoke; Better Messages removes the student from the Course Group Chat immediately. Previous messages stay readable in the thread history.

### Does it work with LearnDash Groups (cohort feature)?

Yes — each LearnDash Group gets its own paired chat, separate from the per-course chat. Group Leaders are auto-joined as instructors of the chat.

### Does the Send Message button require the LearnDash Instructor Role add-on?

Yes — the **Send Message Button on Instructor Profile** option is only available when the paid LearnDash Instructor Role add-on is active. Other LearnDash integrations (Message Instructor button, Course Group Chat) work without it.

### Will the AI Chat Bot work in a LearnDash course chat?

Yes — add an AI bot as a participant in the course chat. The bot answers when mentioned with `@botname`. Useful for handling FAQ-style student questions automatically.

## See also

- [LearnDash student messaging plugin](/blog/learndash-student-messaging/) — full feature write-up with screenshots
- [WordPress LMS chat plugin](/blog/wordpress-lms-chat-plugin/) — comparing LearnDash, LearnPress, Tutor LMS, MasterStudy LMS, FluentCommunity Courses
- [LearnPress integration](/docs/integrations/learnpress/) — for LearnPress sites
- [Tutor LMS integration](/docs/integrations/tutor-lms/) — for Tutor LMS sites
- [MasterStudy LMS integration](/docs/integrations/masterstudy-lms/) — for MasterStudy sites
- [Group conversations](/docs/features/group-conversations/) — underlying group chat feature
- [Mini widgets](/docs/features/mini-widgets/) — Courses widget configuration
- [AI Chat Bots](/docs/features/ai-chat-bots/) — adding bots to course threads

---

## Better Messages for LearnPress: Student & Instructor Messaging


The **LearnPress integration** for Better Messages adds a Message Instructor button on every course page, an auto-managed Course Group Chat tied to enrollment, a Send Message button on the LearnPress instructor profile, a Messages tab inside the LearnPress profile, and a Courses widget on the Mini Widgets bar. Works on both the free and WebSocket versions of Better Messages.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install LearnPress

**[Download LearnPress](https://www.wordplus.org/learnpress)** from the WordPress plugin directory and install it through the standard WordPress installation process.

### How to install Better Messages with LearnPress

1. Install Better Messages through the WordPress plugins screen, or upload the plugin files to `/wp-content/plugins/bp-better-messages`.
2. Activate the plugin through the **Plugins** screen.
3. Go to **Better Messages → Settings → Integrations → LMS** to enable the integrations you want.

LearnPress LMS integration settings

## Supported features

### Message Instructor button on course page

Adds a **Message Instructor** button to every course page. Students can open a private conversation with the course instructor with a single click.

Message Instructor button on the course page

The button is styled to match the native LearnPress course buttons and is hidden for the instructor on their own course.

Enable in **Better Messages → Settings → Integrations → LMS → Message Instructor Button**.

### Send Message button on instructor profile

Adds a **Send Message** button to the LearnPress instructor archive (`/instructor//`) so visitors can reach the instructor directly from their profile.

Send Message button on the instructor profile page

Enable in **Better Messages → Settings → Integrations → LMS → Send Message Button on Instructor Profile**.

### Course Group Chat

When a course is opened, Better Messages automatically creates a group conversation that the instructor and every enrolled student can join. Students are added on enrollment and removed when their enrollment ends.

The conversation header shows the course thumbnail, title, and instructor name, so students always know which course the discussion belongs to.

Course group thread with the course info card

Enable in **Better Messages → Settings → Integrations → LMS → Course Group Chat**.

The course info card pictured above is rendered automatically above the conversation. It also appears on private DMs opened through the **Message Instructor** button so the recipient knows which course you are asking about. To hide it on every LMS course conversation, turn off **Better Messages → Settings → Integrations → LMS → Shared Course Settings → Course Info Card**.

### Courses widget

Once Course Group Chat is enabled, the user's enrolled and authored courses surface in the dedicated [Courses widget](/docs/features/mini-widgets/) on the Mini Widgets bar, Side Panel, and Mobile bar — separate from the social Groups widget so academic chats and friend cohorts don't mix in one list.

Courses widget on a LearnPress site showing the student's enrolled courses

Configure the icon, role restrictions and "Hide Tab When Empty" behaviour under **Better Messages → Settings → Mini Widgets → Courses**.

### Shared course settings

Three toggles under **Better Messages → Settings → Integrations → LMS → Shared Course Settings** apply to every LMS course conversation across LearnDash, LearnPress, Tutor LMS, MasterStudy LMS and FluentCommunity Courses:

- **Course Info Card** *(on by default)* — show the title, image and instructor name banner above each course conversation, including the private DM opened by **Message Instructor**. Turn off to hide the banner everywhere.
- **Email Notifications** *(on by default)* — send the standard "new message" email to participants when activity happens in a course chat. Turn off if your students do not rely on email or you want to reduce traffic.
- **Push Notifications** *(off by default)* — send browser and mobile push notifications for new course messages. Requires a WebSocket license.

Changing any of these toggles propagates across all four LMS integrations.

### Messages Profile Tab

Adds a **Messages** tab to the LearnPress user profile (`/lp-profile//messages/`). The tab embeds the full Better Messages inbox so students can read and reply to conversations without leaving their profile.

Messages tab inside the LearnPress profile

Enable in **Better Messages → Settings → Integrations → LMS → Messages Profile Tab**.

### Use the LearnPress profile as the primary messages location

Open **Better Messages → Settings → General → Messages Location** and choose **Show in LearnPress Profile** to redirect every internal Messages link (notifications, the **All messages** link in mini-chats, etc.) to the LearnPress profile Messages tab.

Messages Location dropdown set to Show in LearnPress Profile

When this option is selected, the **Messages Profile Tab** toggle is enabled and locked automatically — without it the redirect would have no destination.

## Shortcodes for custom placement

If the auto-injected buttons don't land where you want them (custom layout, sidebar widget, page builder, etc.), drop the matching shortcode wherever you need.

:::info
Disable the corresponding toggle (**Message Instructor Button** / **Send Message Button on Instructor Profile**) before placing the shortcode, otherwise the button will be rendered twice — once auto-injected and once by the shortcode.
:::

### `[better_messages_learnpress_course_button]`

Renders the **Message Instructor** button for a LearnPress course. Falls back to the current course post when no `course_id` is supplied.

| Attribute | Default | Notes |
|---|---|---|
| `course_id` | current post | Override the course the button targets |
| `user_id` | course instructor | Override the message recipient |
| `class` | LearnPress button classes | Override CSS classes |
| `text` | `Message Instructor` | Override the button label |

```text
[better_messages_learnpress_course_button]
[better_messages_learnpress_course_button course_id="123"]
[better_messages_learnpress_course_button text="Ask the instructor"]
```

### `[better_messages_learnpress_instructor_button]`

Renders the **Send Message** button on a LearnPress instructor profile. Resolves the instructor from the queried author archive when no `user_id` is supplied.

| Attribute | Default | Notes |
|---|---|---|
| `user_id` | profile owner | Override the message recipient |
| `class` | LearnPress button classes | Override CSS classes |
| `text` | `Send Message` | Override the button label |

```text
[better_messages_learnpress_instructor_button]
[better_messages_learnpress_instructor_button user_id="42"]
```

## Frequently asked questions

### Does it work with LearnPress's WooCommerce-based payments?

Yes — Better Messages reads LearnPress's enrollment state, set by the same hooks regardless of payment method.

### What happens when a student's course access expires?

LearnPress fires standard enrollment-end hooks; Better Messages removes the student from the Course Group Chat. Their previous messages stay in history.

### Can the Messages tab be the primary inbox location for LearnPress members?

Yes — set **Messages Location** to **Show in LearnPress Profile** and every internal Messages link routes to the LearnPress profile tab.

### Will it work alongside other LMS plugins?

Yes — sites running LearnPress alongside LearnDash, Tutor LMS, or MasterStudy LMS see all course chats together in the shared Courses widget.

### Will the Messages tab respect LearnPress's profile tab order?

Yes — registered through LearnPress's standard profile-tab API.

## See also

- [LearnPress student messaging plugin](/blog/learnpress-student-messaging/) — full feature write-up with screenshots
- [WordPress LMS chat plugin](/blog/wordpress-lms-chat-plugin/) — comparing every LMS integration
- [LearnDash integration](/docs/integrations/learndash/) — for LearnDash sites
- [Tutor LMS integration](/docs/integrations/tutor-lms/) — for Tutor LMS sites
- [MasterStudy LMS integration](/docs/integrations/masterstudy-lms/) — for MasterStudy sites
- [Group conversations](/docs/features/group-conversations/) — underlying group chat feature

---

## Better Messages for MasterStudy LMS: Student & Instructor Messaging


The **MasterStudy LMS integration** for Better Messages adds a Message Instructor button on every course page, a Send Message button on the public instructor and student profiles, an auto-managed Course Group Chat tied to enrollment, and a Messages tab inside the MasterStudy account sidebar that embeds the full messenger. An optional toggle hides MasterStudy's native chat so members see only Better Messages. Works on both the free and WebSocket versions of Better Messages.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install MasterStudy LMS

**[Download MasterStudy LMS](https://www.wordplus.org/masterstudy-lms)** from the WordPress plugin directory and install it through the standard WordPress installation process.

### How to install Better Messages with MasterStudy LMS

1. Install Better Messages through the WordPress plugins screen, or upload the plugin files to `/wp-content/plugins/bp-better-messages`.
2. Activate the plugin through the **Plugins** screen.
3. Go to **Better Messages → Settings → Integrations → LMS** to enable the integrations you want.

MasterStudy LMS integration settings

## Supported features

### Message Instructor button on course page

Adds a **Message Instructor** button to every MasterStudy course page next to the enrol/buy button. Students can open a private conversation with the course instructor with a single click.

Message Instructor button on the course page

The button is hidden for the instructor on their own course.

Enable in **Better Messages → Settings → Integrations → LMS → MasterStudy LMS Integration → Message Instructor Button**.

### Send Message button on instructor profile

Adds a **Send Message** button to the MasterStudy public instructor profile so visitors can reach the instructor directly from their profile page.

Send Message button on the instructor profile page

The button is rendered with the same MasterStudy button styling so it sits naturally inside the actions area next to the native MasterStudy "Send message" action. With **Disable MasterStudy Messages** turned on the native button is hidden and only the Better Messages one remains.

Enable in **Better Messages → Settings → Integrations → LMS → MasterStudy LMS Integration → Send Message Button on Instructor Profile**.

### Send Message button on student profile

Adds a **Send Message** button to the MasterStudy public student profile so other learners can reach the student directly from their profile page.

The button uses the same styling and behaviour as the instructor profile button, and is also hidden by **Disable MasterStudy Messages** when that toggle is on.

Enable in **Better Messages → Settings → Integrations → LMS → MasterStudy LMS Integration → Send Message Button on Student Profile**.

### Course Group Chat

When a course is opened, Better Messages automatically creates a group conversation that the instructor and every enrolled student can join. Students are added on enrollment and removed when their enrollment is deleted.

The conversation header shows the course thumbnail, title, and instructor name, so students always know which course the discussion belongs to.

Course group thread with the course info card

Enable in **Better Messages → Settings → Integrations → LMS → MasterStudy LMS Integration → Course Group Chat**.

The course info card pictured above is rendered automatically above the conversation. It also appears on private DMs opened through the **Message Instructor** button so the recipient knows which course you are asking about. To hide it on every LMS course conversation, turn off **Better Messages → Settings → Integrations → LMS → Shared Course Settings → Course Info Card**.

### Courses widget

Once Course Group Chat is enabled, the user's enrolled courses surface in the dedicated [Courses widget](/docs/features/mini-widgets/) on the Mini Widgets bar, Side Panel, and Mobile bar — separate from the social Groups widget so academic chats and friend cohorts don't mix in one list.

Courses widget on a MasterStudy site showing the student's enrolled courses

Configure the icon, role restrictions and "Hide Tab When Empty" behaviour under **Better Messages → Settings → Mini Widgets → Courses**.

### Shared course settings

Three toggles under **Better Messages → Settings → Integrations → LMS → Shared Course Settings** apply to every LMS course conversation across LearnDash, LearnPress, Tutor LMS, MasterStudy LMS and FluentCommunity Courses:

- **Course Info Card** *(on by default)* — show the title, image and instructor name banner above each course conversation, including the private DM opened by **Message Instructor**. Turn off to hide the banner everywhere.
- **Email Notifications** *(on by default)* — send the standard "new message" email to participants when activity happens in a course chat. Turn off if your students do not rely on email or you want to reduce traffic.
- **Push Notifications** *(off by default)* — send browser and mobile push notifications for new course messages. Requires a WebSocket license.

Changing any of these toggles propagates across all five LMS integrations.

### Messages Account Tab

Adds a **Messages** tab to the MasterStudy LMS user account sidebar (at `/account/messages/`). The tab embeds the full Better Messages inbox so users can read and reply to conversations without leaving the MasterStudy account.

Messages tab inside the MasterStudy account

Enable in **Better Messages → Settings → Integrations → LMS → MasterStudy LMS Integration → Messages Account Tab**.

### Disable MasterStudy Messages

MasterStudy ships its own internal chat: a **Messages** entry in the user account sidebar plus **Send message** buttons on the public instructor and student profiles. With Better Messages installed you can keep both systems side by side, or hide MasterStudy's so visitors only see Better Messages.

Both Messages tabs visible by default

Open **Better Messages → Settings → Integrations → LMS → MasterStudy LMS Integration → Disable MasterStudy Messages** to remove the native Messages tab from the account sidebar and hide the native **Send message** buttons on the instructor and student public profiles.

Single Better Messages tab after enabling Disable MasterStudy Messages

The native Messages page is still reachable at `/account/chat/` if you have it bookmarked, but nothing in the UI links to it any more. To redirect every internal Messages link to your Better Messages tab as well, see the next section.

### Use the MasterStudy account as the primary messages location

Open **Better Messages → Settings → General → Messages Location** and choose **Show in MasterStudy LMS Account** to redirect every internal Messages link (notifications, the **All messages** link in mini-chats, etc.) to the Better Messages tab inside the MasterStudy account.

Messages Location dropdown set to Show in MasterStudy LMS Account

When this option is selected, the **Messages Account Tab** toggle is enabled and locked automatically — without it the redirect would have no destination.

Messages Account Tab locked on when Messages Location uses the account

## Shortcodes for custom placement

If the auto-injected buttons don't land where you want them (custom layout, sidebar widget, page builder, etc.), drop the matching shortcode wherever you need.

:::info
Disable the corresponding toggle (**Message Instructor Button** / **Send Message Button on Instructor Profile** / **Send Message Button on Student Profile**) before placing the shortcode, otherwise the button will be rendered twice — once auto-injected and once by the shortcode.
:::

### `[better_messages_masterstudy_course_button]`

Renders the **Message Instructor** button for a MasterStudy course. Falls back to the current course post when no `course_id` is supplied.

| Attribute | Default | Notes |
|---|---|---|
| `course_id` | current post | Override the course the button targets |
| `user_id` | course author | Override the message recipient (instructor) |
| `class` | MasterStudy button classes | Override CSS classes |
| `text` | `Message Instructor` | Override the button label |

```text
[better_messages_masterstudy_course_button]
[better_messages_masterstudy_course_button course_id="123"]
[better_messages_masterstudy_course_button text="Ask the instructor"]
```

### `[better_messages_masterstudy_instructor_button]`

Renders the **Send Message** button on a MasterStudy instructor public profile.

| Attribute | Default | Notes |
|---|---|---|
| `user_id` | profile owner | Override the message recipient |
| `class` | MasterStudy button classes | Override CSS classes |
| `text` | `Send Message` | Override the button label |

```text
[better_messages_masterstudy_instructor_button]
[better_messages_masterstudy_instructor_button user_id="42"]
```

### `[better_messages_masterstudy_student_button]`

Renders the **Send Message** button on a MasterStudy student public profile.

| Attribute | Default | Notes |
|---|---|---|
| `user_id` | profile owner | Override the message recipient |
| `class` | MasterStudy button classes | Override CSS classes |
| `text` | `Send Message` | Override the button label |

```text
[better_messages_masterstudy_student_button]
[better_messages_masterstudy_student_button user_id="42"]
```

## Frequently asked questions

### Can I keep MasterStudy Messages and Better Messages side by side?

Yes — the **Disable MasterStudy Messages** toggle is optional. Keep it off to show both, on to show only Better Messages. Most sites pick one to avoid confusing students with two Messages tabs.

### What happens when a student's MasterStudy enrollment is cancelled?

MasterStudy fires its standard enrollment hooks; Better Messages removes the student from the Course Group Chat. Previous messages stay in history.

### Does it work with MasterStudy Pro?

Yes — the integration reads MasterStudy's core hooks. WooCommerce-based enrollments, subscriptions, and certificates work alongside the messenger.

### Will it work alongside LearnDash, LearnPress, Tutor LMS?

Yes — multi-LMS sites see all course chats together in the shared Courses widget.

### Can the MasterStudy native chat history be migrated?

Not automatically — the two messengers store data differently. Run both side by side for a transition period, then enable **Disable MasterStudy Messages** when students have moved over.

## See also

- [MasterStudy LMS student messaging plugin](/blog/masterstudy-lms-student-messaging/) — full feature write-up with screenshots
- [WordPress LMS chat plugin](/blog/wordpress-lms-chat-plugin/) — comparing every LMS integration
- [LearnDash integration](/docs/integrations/learndash/)
- [LearnPress integration](/docs/integrations/learnpress/)
- [Tutor LMS integration](/docs/integrations/tutor-lms/)
- [Group conversations](/docs/features/group-conversations/) — underlying group chat feature
- [Mini widgets](/docs/features/mini-widgets/) — Courses widget configuration

---

## Better Messages for Motors: Buyer ↔ Dealer Live Chat for Car Listings


The **Motors integration** for Better Messages adds a Live Chat button on the single car listing page, a LIVE CHAT pill on inventory list cards, a Live Chat row on the dealer profile, and a MESSAGES tab inside the dealer dashboard. Supports the Motors Multi-Listing add-on for motorcycles, boats, trucks, RVs and other vehicle types. Theme accent colors are inherited automatically. Works on both the free and WebSocket versions.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install Motors

**[Download Motors – Car Dealer, Classifieds & Listing](https://www.wordplus.org/motors)** from the WordPress.org plugin directory and follow the standard WordPress installation process. The free **Motors Starter Theme** (or any of Stylemix's commercial Motors themes) is recommended for the polished out-of-the-box layout the screenshots below use.

### How to install Better Messages with Motors

1. Install Better Messages through the WordPress plugins screen or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress.
3. Use the **Better Messages → Settings** menu to configure the plugin.
4. Go to **Integrations → Directories** and enable the **Enable Motors Integration** toggle. Each placement below has its own toggle so you can enable only the ones you want.

Settings

## Setting the Motors dealer dashboard as the messages location

Better Messages → **Settings → General** has a **Messages Location** dropdown that controls which page hosts the user inbox. Selecting **Show in Motors Dealer Dashboard** routes every "open inbox" link in the plugin (notification emails, on-site links, push notifications, the floating bubble, etc.) into the **MESSAGES** tab on the dealer's own dashboard at `/author//?page=better-messages`. The dashboard tab is force-enabled and locked while this option is selected — change the Messages Location away from Motors to unlock it again.

Messages Location

## Supported features

#### Live Chat button on the single listing page

Renders inside the dealer card on the single-listing page, alongside Motors' **Message Us** and **Make an Offer Price** buttons. The button is hidden when the listing is unpublished or when the visitor is also the listing's author.

Listing page

#### Live Chat pill on inventory list cards

Adds a small **LIVE CHAT** pill to each card in the inventory list view, inline with the native **Schedule Test Drive / Add to Compare / Quote by Phone / Trade-In / Share This** actions. Hidden for cards owned by the current visitor.

Inventory list

#### Live Chat button on the dealer profile page

Adds a **Live Chat** row to the **Contact Info** card on the dealer / private-seller profile page. Hidden when the dealer has no published listings or when the dealer is viewing their own profile.

Dealer profile

#### Messages tab inside the dealer dashboard

Adds a **MESSAGES** tab to the dealer dashboard sidebar at `/author//`, alongside **MY LISTINGS / MY FAVORITES / PROFILE SETTINGS**. The tab loads the full Better Messages inbox inline so dealers can read and reply without leaving their dashboard.

Dashboard tab

#### Listing info card inside the conversation

Conversations started from a Motors listing show the car's image, title and price inside the messenger's thread-info card. Clicking the dealer's name or avatar in a conversation opens their Motors author profile page rather than the default WordPress author archive.

Thread info

The buttons inherit the Motors theme's accent and text colors automatically — if you customize the theme palette through Motors' settings, the Live Chat buttons pick up the new colors with no extra configuration.

## Shortcodes for custom placement

If the auto-injected buttons don't land where you want them (custom Elementor template, sidebar widget, theme override, etc.), drop the matching shortcode wherever you need.

:::info
Disable the corresponding toggle (**Listing Page Button** / **Inventory Card Button** / **Dealer Profile Button**) before placing the shortcode, otherwise the button will be rendered twice — once auto-injected and once by the shortcode.
:::

### `[better_messages_motors_listing_button]`

Renders the **Live Chat** button targeted at the listing's author. Uses the current car listing when no `listing_id` is supplied.

| Attribute | Default | Notes |
|---|---|---|
| `listing_id` | current listing | Override the listing the button targets |
| `text` | `Live Chat` | Override the button label |

```text
[better_messages_motors_listing_button]
[better_messages_motors_listing_button listing_id="2530"]
[better_messages_motors_listing_button text="Contact seller"]
```

### `[better_messages_motors_dealer_button]`

Renders the **Live Chat** button targeted at a specific dealer or private seller. Uses the current author when placed on a dealer profile page, or accepts an explicit `user_id` attribute when used elsewhere.

| Attribute | Default | Notes |
|---|---|---|
| `user_id` | profile author | Override the message recipient |
| `text` | `Live Chat` | Override the button label |

```text
[better_messages_motors_dealer_button]
[better_messages_motors_dealer_button user_id="2"]
[better_messages_motors_dealer_button text="Chat with this dealer"]
```

## Multi-listing support

If you also use the Motors Multi-Listing add-on with extra vehicle types (motorcycles, boats, trucks, etc.), every placement above works for those listings automatically — no extra configuration needed.

## Frequently asked questions

### Does it work with all Motors theme variants?

Yes — Better Messages works with the standard Motors plugin regardless of which Stylemix theme you use. Theme accent colors are inherited automatically.

### Does it work with the Motors Multi-Listing add-on?

Yes — every placement works for motorcycles, boats, trucks, RVs, and any custom vehicle type the Multi-Listing add-on registers.

### Can buyers chat without registering?

Optional — enable Guest Chat in **Better Messages → Settings → Guest Chat**.

### What happens when a car listing is unpublished?

The Live Chat button is hidden when the listing is not published. Existing threads remain readable.

### Can I move the LIVE CHAT pill to a different position on inventory cards?

The pill renders inline with Motors' standard inventory-card action row. A custom hook priority can reorder if needed.

## See also

- [Motors car dealer chat](/blog/motors-car-dealer-chat/) — full feature write-up
- [WordPress real estate chat](/blog/wordpress-real-estate-chat/) — adjacent real-estate use case
- [Classified Listing integration](/docs/integrations/classified-listing/) — for general classifieds sites
- [HivePress integration](/docs/integrations/hivepress/)
- [Directorist integration](/docs/integrations/directorist/)

---

## Better Messages for MultiVendorX: Live Chat for WC Marketplace Vendors


The **MultiVendorX integration** for Better Messages adds a **Messages** entry to the MultiVendorX Vendor Dashboard sidebar, a **Live Chat** button on every vendor product page, and a **Live Chat** button on each vendor's storefront. Supports both **MultiVendorX 4.x** and the **5.0+** rebuild, auto-detecting which branch is active. Vendor names and avatars in the messenger come straight from the MultiVendorX shop profile. Works on both the free and WebSocket versions.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

### Video demonstration



## Installation

### How to install MultiVendorX

**[Download MultiVendorX](https://www.wordplus.org/multivendorx)** from the official website and install it through the standard WordPress plugin flow.

### How to install Better Messages with MultiVendorX
1. Install Better Messages from the WordPress plugins screen, or upload the plugin files to `/wp-content/plugins/bp-better-messages`.
2. Activate the plugin through **Plugins** in WordPress.
3. Open **Better Messages → Settings → Integrations → WooCommerce**.
4. Scroll to the **MultiVendorX Integration** section and toggle **Vendor Live Chat** on.

Settings

The MultiVendorX section is sorted to the top of the WooCommerce sub-tab whenever the plugin is active, so you do not have to scroll past inactive marketplace integrations.

#### Optional: hide Messages tab when a vendor disables live chat

Right below the **Vendor Live Chat** toggle is **Hide Messages tab when vendor disables live chat**. Off by default — the Messages tab stays visible to every vendor with the `create_stores` capability regardless of their personal live chat preference. Turn it on if you want the tab to disappear for vendors who have switched live chat off in their store settings.

### Supported features

When you install Better Messages alongside MultiVendorX:

- Vendors get a per-store **Live Chat** toggle in their dashboard settings.
- A **Messages** entry appears in the MultiVendorX dashboard sidebar — vendors stay inside their dashboard to reply.
- All vendor avatars in the messenger come from the MultiVendorX shop profile, not the raw WordPress user.
- All vendor profile links in the messenger point to the MultiVendorX storefront.

#### Messages tab in the Vendor Dashboard
Dashboard

#### Live Chat button on vendor product pages
If you use a custom page builder or the button does not appear for theme-specific reasons, drop this shortcode wherever it belongs: `[better_messages_multivendorx_product_button]`
Product Page

#### Live Chat button on the vendor storefront
For custom storefront layouts: `[better_messages_multivendorx_store_button]`
Shop Page

## Frequently asked questions

### Does it work with both MultiVendorX 4.x and 5.0+?

Yes — separate integrations ship for both branches, auto-detected. Migrating between branches keeps the chat history.

### Can customers chat without an account?

Optional — enable Guest Chat in **Better Messages → Settings → Guest Chat**.

### Can vendors disable Live Chat for their own shop?

Yes — the per-vendor toggle in the dashboard settings is independent of the global setting. By default, disabling it just hides the customer-facing **Live Chat** buttons; the Messages tab stays in the vendor's sidebar. Admins who want the tab to disappear too can enable the **Hide Messages tab when vendor disables live chat** option in WP Admin.

### What if my theme overrides the product template?

Use the manual shortcode `[better_messages_multivendorx_product_button]` placed wherever the Live Chat button should appear.

### Does it work alongside Dokan / WCFM?

Yes — Better Messages supports multiple marketplace plugins active simultaneously.

## See also

- [MultiVendorX vendor chat](/blog/multivendorx-vendor-chat/) — full feature write-up
- [WordPress marketplace chat](/blog/wordpress-marketplace-chat/) — comparing every marketplace integration
- [Dokan integration](/docs/integrations/dokan/)
- [WCFM integration](/docs/integrations/wcfm/)
- [WC Vendors integration](/docs/integrations/wc-vendors/)

---

## Better Messages for MyCred: Charge Points to Message or Call


The **MyCred integration** allows charging users for messaging and private calls using MyCred points — per-message, per-new-thread, per-call, per-role, and per-conversation-type. The user's balance can be displayed inline in the messenger with a configurable URL where they can top up points. Supported through a unified Points System with provider abstraction, shared with GamiPress.

Better Messages Points Systems settings — MyCred provider with per-role New Message Pricing grid and MyCred-specific log entry tags

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install MyCred

**[Download MyCred](https://www.wordplus.org/mc)** from official website and install following standard WordPress installation process.

### How to install Better Messages with MyCred
1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress.
3. Use the **Better Messages** → **Settings** → **Integrations** → **Points Systems** menu to configure the integration.

## Configuration

### Point Type

Select which MyCred point type to use for charging.

### Charge Types

- **New message** — charge when a user sends a message
- **New thread** — charge when a user creates a new conversation

### Charge Categories

Different rates can be configured for each conversation type:

- **Private threads** — one-on-one conversations
- **Groups** — group conversations
- **Chat rooms** — chat room messages

### Per-Role Pricing

Different charge amounts can be set per WordPress user role for messages, new threads, and calls. Voice and video calls bill **per call minute** (first minute charged at start; calls end gracefully if the balance drops below one more minute mid-call).

Private Call Pricing settings — per-role per-minute rates for voice and video calls

### AI Usage Charging

Points can be charged for AI bot responses. This is configured per-bot in the AI Bots settings.

### Balance Display

The user's point balance can be shown in multiple locations:

- Chat header
- Threads list (top)
- Threads list (bottom)
- User menu
- User menu popup
- Reply form area

### Balance URL

A configurable external URL can be set where users can manage or purchase points. The balance pill in the messenger links to this URL — typically a WooCommerce points-top-up product or a custom checkout.

Messenger UI showing the MyCred balance pill in the user menu and inside the reply form area

## See also

- [Pay-to-Message with MyCred and GamiPress](/docs/features/mycred-gamipress/) — canonical feature reference (shared across both providers)
- [MyCred pay-to-message](/blog/mycred-pay-to-message/) — full feature write-up
- [Build a monetized DM platform](/blog/wordpress-monetized-messaging-platform/) — vertical walk-through with per-message + per-call billing
- [GamiPress integration](/docs/integrations/gamipress/) — same feature on the GamiPress points engine
- [AI Chat Bots](/docs/features/ai-chat-bots/) — for charging points per AI bot response
- [Role-based access](/docs/features/role-based-access/) — for per-role pricing setup

---

## OneSignal Integration: Web Push for Private Messages


![OneSignal logo](https://ps.w.org/onesignal-free-web-push-notifications/assets/banner-1544x500.png)

:::info WebSocket Version Guide

<>This functionality available only with WebSocket Version

:::

:::info Compatibility

<>This { (props.type ? props.type : 'guide') } compatible with Better Messages {props.version} or higher

:::

[OneSignal](https://onesignal.com/) is one of the most popular web push notification services for WordPress sites — it handles browser-side subscription, segmentation, and delivery to Chrome, Edge, Firefox, Safari, and Opera. The Better Messages integration plugs OneSignal into the messenger so that **every new private message sent in Better Messages can trigger a web push notification** to the offline recipient. The recipient sees the notification on the desktop (or their mobile lock screen, if installed as a PWA), clicks it, and lands directly in the conversation.

## What the integration adds

- **External User ID mapping** — Better Messages automatically associates the WordPress `user_id` of every logged-in visitor with their OneSignal subscription as an **External User ID**. Without this, OneSignal can only send push to anonymous subscriptions; with it, push can be targeted per recipient.
- **Push per new message** — when a new message arrives in a conversation, the integration triggers OneSignal to deliver a notification to all offline recipients of that thread (recipients who have an active subscription and are not currently looking at the thread).
- **Per-thread silencing** — recipients who have muted a conversation in Better Messages do not receive push for that thread.
- **No extra config** — once the OneSignal plugin is configured and Better Messages is installed, the integration is automatic; no shortcodes, no admin toggles to forget.

## Why use OneSignal vs. the built-in web push

Better Messages ships its own **Web Push** add-on on the WebSocket version (no third-party needed). The OneSignal integration is for sites that already use OneSignal for marketing/transactional pushes and want to consolidate everything — chat included — through the same provider, the same opt-in prompt, and the same OneSignal dashboard for delivery analytics.

If you do not already use OneSignal, the built-in Web Push add-on covers the same use case without adding a vendor.

## Installation

1. **[Download OneSignal](https://www.wordplus.org/onesignal)** from the official site and install following the standard WordPress installation process.
2. Configure the OneSignal plugin following the **[official setup guide](https://documentation.onesignal.com/docs/wordpress)** — site URL, App ID, REST API Key.
3. Install Better Messages (any version with WebSocket).
4. That's it — the External User ID mapping starts automatically as soon as users are logged in. Push notifications for new messages start firing right away.

## Frequently asked questions

### Do I need both OneSignal and the Better Messages Web Push add-on?

No — pick one. Use OneSignal if you already have it for other notifications. Use the built-in Web Push add-on if you don't want to depend on a third-party provider.

### Does this work on Safari / iOS?

Yes. Safari supports web push notifications (macOS Safari 16+ and iOS 16.4+ once installed as a PWA). OneSignal handles the protocol differences.

### Does the integration require WebSocket?

Yes — the integration is tied to the WebSocket version because that's what powers real-time event triggering. On the free (AJAX) version, OneSignal can still be installed for general site notifications, but the chat won't trigger pushes per message.

### What happens if a user uninstalls OneSignal opt-in mid-conversation?

OneSignal handles the lifecycle — once a user revokes the browser-level push permission, no further notifications are sent. Better Messages does not need to be reconfigured.

## See also

- [OneSignal push notifications for Better Messages](/blog/onesignal-push-notifications-better-messages/) — full feature write-up
- [Progressify integration](/docs/integrations/progressify/) — for PWA-based push notifications on iOS
- [Web Push add-on](/docs/websocket/web-push/) — Better Messages' built-in web push (no third party)
- [Real-time messaging](/docs/features/realtime-messaging/) — what the WebSocket version unlocks

---

## Better Messages for PeepSo: Real-Time Chat for PeepSo Communities


The **PeepSo integration** for Better Messages takes over every PeepSo surface — the header notification dock, every profile (with optional Audio Call / Video Call buttons on the WebSocket version), the members directory, the friends list, and PeepSo Groups. PeepSo VIP verified badges and Block Theme dark mode are mirrored automatically. Works on both the free and WebSocket versions of Better Messages.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

Better Messages replaces the legacy PeepSo Core: Chat plugin with a full real-time messaging experience that hooks into every PeepSo surface — the header navigation, user profiles, the members directory, the friends list, and PeepSo groups.

## Installation

### How to install PeepSo

**[Download PeepSo](https://www.wordplus.org/peepso)** from the official website and install it through the standard WordPress plugin flow.

### How to install Better Messages with PeepSo

1. Install Better Messages from **Plugins → Add New** or by uploading the plugin zip
2. Activate Better Messages
3. Create the WordPress page where the messages page will live
4. Open **Better Messages → Settings** and set **Messages Location** to the page you just created
5. If **PeepSo Core: Chat** is still active, **deactivate it** — it conflicts with Better Messages
6. Open **Better Messages → Settings → Integrations → PeepSo** to fine-tune the integration

## What gets integrated automatically

When PeepSo is detected, Better Messages turns on every PeepSo-specific touch-point with no manual setup:

- A **Messages** entry is added to the PeepSo header / profile navigation, with a live unread counter that updates in real time
- The **Send Message** button on every user profile, members directory row, and friends list row points to Better Messages
- The PeepSo **user hovercard** gets a Send Message button (plus optional Audio / Video Call cells when those toggles are enabled)
- All avatars and profile links in the Better Messages interface use PeepSo's data — so users land on the PeepSo profile, not the WordPress one
- **PeepSo Friends** drives Better Messages' Friends widget (mini, mobile, and combined variants) and the recipient search inside the New Conversation popup
- **PeepSo Groups** drives Better Messages' Groups widget; group chats can be created automatically from a PeepSo group, with members joining and leaving in sync
- **PeepSo VIP** verified-icon badges next to user names are carried into the Better Messages interface
- **PeepSo Block Theme** dark mode is mirrored automatically — Better Messages flips into dark mode whenever PeepSo does

#### Messages entry in the PeepSo navigation

The Messages icon is inserted into PeepSo's notification dock. Its unread counter is wired to Better Messages' real-time pipeline, so the badge updates as new messages arrive without a page reload.

PeepSo notification dock with the Better Messages icon and unread badge

Clicking the icon opens the PeepSo-styled Messages page. If **PeepSo Header** is enabled in settings, the Messages page is wrapped in PeepSo's navbar so it looks like a native PeepSo subpage.

#### User profile — Send Message + optional call buttons

Each PeepSo user profile gets a **Send Message** button next to the existing Follow / Friend actions. The button is added automatically; no shortcode or manual placement is needed.

With the **WebSocket** version, two extra one-click buttons can be enabled on the profile: **Audio Call** and **Video Call**. Each is an independent toggle.

PeepSo user profile with Send Message, Audio Call and Video Call buttons

#### User hovercard

Hovering over any user name or avatar across PeepSo opens the native PeepSo hovercard. Better Messages slots its action buttons into the hovercard footer, styled as full-width cells alongside the existing "Visit profile" link:

- **Send Message** — opens a one-to-one conversation (or a mini chat window when **Advanced Mini Chats** is enabled)
- **Audio Call** — only shown when the **Audio Call Button** toggle is on
- **Video Call** — only shown when the **Video Call Button** toggle is on

The hovercard automatically hides the buttons on your own card, and respects PeepSo Block Users and the **Only Friends Mode** setting — non-friends or blocked users will not see the Send Message cell. The buttons inherit PeepSo styling, including dark mode.

PeepSo user hovercard with Send Message, Audio Call, Video Call, and Visit profile cells

The hovercard buttons can be turned off via **Settings → Integrations → PeepSo → Hovercard Buttons**.

#### Members directory & friends list

Every row in the PeepSo members directory and the PeepSo Friends list gets a **Send Message** icon — clicking it opens a one-to-one conversation (or a mini chat window, if **Advanced Mini Chats** is enabled).

#### PeepSo Friends + PeepSo Groups widgets

When **PeepSo Friends** is active, the Better Messages Friends widget is populated from the user's PeepSo friends list — no separate friends model. The "Only Friends Mode" setting can additionally restrict messaging to friends only and hide non-friends from search.

When **PeepSo Groups** is active, the Better Messages Groups widget lists every PeepSo group the user belongs to. Each group can optionally have a Better Messages group chat attached:

- The group chat is created the first time the group is opened in Better Messages
- Members are added when they join the PeepSo group, removed when they leave
- File uploads, email notifications, and push notifications can be toggled per integration
- Group owners can disable the chat at any time

Better Messages widget with the Groups tab open, showing PeepSo groups

## Settings reference

All PeepSo-specific options live at **Better Messages → Settings → Integrations → PeepSo**.

PeepSo settings tab in the Better Messages admin

| Setting | What it does |
|---|---|
| **PeepSo Header** | Wraps the Better Messages page in PeepSo's navbar and styling |
| **Hovercard Buttons** | Adds Send Message and (when enabled) Audio / Video Call cells to the PeepSo user hovercard |
| **Advanced Mini Chats** | Opens a mini chat window instead of redirecting to the Messages page when a Private Message button is clicked. Requires the WebSocket version |
| **Video Call Button** | Adds a Video Call button to PeepSo user profiles (WebSocket) |
| **Audio Call Button** | Adds an Audio Call button to PeepSo user profiles (WebSocket) |
| **Only Friends Mode** | Restricts messaging to friends only; hides non-friends from search. Requires **PeepSo Friends** |
| **Group Messages** | Enables group chats for PeepSo Groups. Requires **PeepSo Groups** |
| **File Uploading** | Allows file uploads in PeepSo group chats |
| **Email Notifications** | Sends email notifications for new messages in PeepSo group chats |
| **Push Notifications** | Sends push notifications for new messages in PeepSo group chats (WebSocket) |

## Frequently asked questions

### Does Better Messages replace PeepSo Core: Chat?

Yes. PeepSo Core: Chat should be deactivated when Better Messages is installed — the two messengers conflict. PeepSo's underlying message data is preserved.

### Will the PeepSo header icon still work?

Yes — the icon stays in the same PeepSo notification dock, with the same styling, but now opens the Better Messages inbox.

### Can I keep the PeepSo dark mode look on the messenger?

Yes — Better Messages mirrors PeepSo Block Theme dark mode automatically.

### Does it work with PeepSo VIP?

Yes — Verified badges from PeepSo VIP carry into the messenger interface.

### Can I restrict messaging to friends only?

Yes — toggle **Only Friends Mode** in **Settings → Integrations → PeepSo**.

## See also

- [PeepSo messaging plugin](/blog/peepso-messaging-plugin/) — full feature write-up
- [WordPress community chat plugin](/blog/wordpress-community-chat-plugin/) — comparing community platforms
- [BuddyPress integration](/docs/integrations/buddypress/)
- [BuddyBoss integration](/docs/integrations/buddyboss/)
- [Ultimate Member integration](/docs/integrations/ultimate-member/)
- [WordPress video call plugin](/blog/wordpress-video-call-plugin/) — audio / video calls on profiles

---

## Better Messages for ProfileGrid: Private Messaging for User Profiles


The **ProfileGrid integration** for Better Messages adds a Messages tab to the logged-in user's ProfileGrid profile, a Private Message button on every other user's profile, and uses ProfileGrid avatars and links throughout the messenger. If you are using **ProfileGrid Messages**, deactivate it after installing Better Messages to avoid a double-messenger conflict. Works on both the free and WebSocket versions.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install ProfileGrid

**[Download ProfileGrid](https://www.wordplus.org/profilegrid)** from official website and install following standard WordPress installation process

### How to install Better Messages with ProfileGrid
1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress
3. Use the **Better Messages** -> **Settings** menu to configure the plugin
4. Set **Messages Location** to **Show in ProfileGrid profile** or you can also set any WordPress page to be a messages homepage
5. If you are using **ProfileGrid Messages** - disable it as it makes no sense to use it together with **Better Messages**
### Supported features

When you install ProfileGrid plugin with Better Messages:

- All avatars in Better Messages interface automatically displayed from ProfileGrid user profiles
- All links to user profiles in Better Messages interface automatically points to ProfileGrid user profiles

#### Automatically adding messages tab in currently logged-in user profile
Profile Page

#### Automatically adding private message button in other user profiles
Other Profile Page

## Frequently asked questions

### Does it replace the ProfileGrid Messages add-on?

Yes — deactivate ProfileGrid Messages when Better Messages is installed.

### Can I restrict who can message whom?

Yes — Better Messages has role-based permissions in **Settings → Permissions**.

### Does it work with ProfileGrid Pro features?

Yes — the integration uses ProfileGrid's standard profile hooks, which Pro features extend.

### Can guests message members?

Optional — enable Guest Chat in **Better Messages → Settings → Guest Chat**.

## See also

- [ProfileGrid private messaging plugin](/blog/profile-grid-private-messaging/) — full feature write-up
- [Ultimate Member integration](/docs/integrations/ultimate-member/)
- [UsersWP integration](/docs/integrations/userswp/)
- [WP User Manager integration](/docs/integrations/wp-user-manager/)

---

## Better Messages for Progressify: PWA Push Notifications for Chat


Progressify

:::info WebSocket Version Guide

<>This functionality available only with WebSocket Version

:::

:::info Compatibility

<>This { (props.type ? props.type : 'guide') } compatible with Better Messages {props.version} or higher

:::

## Overview

[Progressify](https://www.wordplus.org/progressify) is a plugin which allows you to convert your website into PWA (Progressive Web App), including sending push notifications to your users.

Special integration is required to send messages notifications from Better Messages to your users, which is now included in Better Messages plugin.

## Installation

1. **[Get Progressify](https://www.wordplus.org/progressify)** from official website and install following standard WordPress installation process
2. Configure Progressify plugin and enable push notifications in Progressify settings

Better Messages will automatically detect Progressify plugin and enable push notifications integration, that will be displayed in Better Messages -> Settings -> Notifications.

Better Messaegs - Progressify

## Bottom menu overlap fix

If you are using Progressify's bottom navigation menu, it may overlap the Better Messages reply area on mobile devices. Add the following CSS to fix this:

```css
.bp-messages-chat-wrap.bp-messages-mobile,
.bp-messages-single-thread-wrap.bp-messages-mobile,
.bp-messages-wrap-group.bp-messages-mobile,
.bp-messages-wrap-main.bp-messages-mobile {
    bottom: 58px !important;
}
```

You can add this CSS via **WP Admin** → **Appearance** → **Customize** → **Additional CSS**, or use the `better_messages_css_customizations` filter.

## See also

- [Progressify PWA push notifications](/blog/progressify-pwa-push-notifications/) — full feature write-up
- [OneSignal integration](/docs/integrations/onesignal/) — for standard desktop web push
- [WordPress chat mobile app](/blog/wordpress-chat-mobile-app/) — native iOS / Android apps
- [Real-time messaging](/docs/features/realtime-messaging/) — what the WebSocket version unlocks

---

## RealHomes Messaging: Buyer ↔ Agent Live Chat for Listings

# Better Messages for RealHomes: Buyer ↔ Agent Live Chat for Real Estate Listings

The **RealHomes integration** for Better Messages adds a Live Chat row inside the agent contact panel on the single property page (next to Office / Mobile / Email), a Live Chat icon on property listing cards, a Live Chat contact row on agent and agency profile pages, the same row on every card in the agents and agencies listings, plus a Messages tab inside the RealHomes user dashboard at `/dashboard/?module=bm-messages`. Buyers reach the listing's agent — or the agency owner when no agent is linked — in one click, with the property image, price, beds / baths / sq ft and address pinned to the top of the conversation. Theme accent colors (the value configured in **RealHomes Theme Options → Global Styling → Primary Color**) are inherited automatically through the `--rh-global-color-primary` CSS variable. Works on both the free and WebSocket versions.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install RealHomes

The **[RealHomes – Real Estate WordPress Theme](https://www.wordplus.org/realhomes)** is a commercial theme from Inspiry Themes. Purchase, download and activate it from **Appearance → Themes**, then install the required **Easy Real Estate** plugin and (optionally) the **Slider Revolution** plugin pack that ships with it. Once RealHomes is active you'll get the `property`, `agent`, and `agency` post types, the user dashboard at `/dashboard/`, the half-map property search, and the property submission flow out of the box.

### How to install Better Messages with RealHomes

1. Install Better Messages through the WordPress plugins screen or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress.
3. Use the **Better Messages → Settings** menu to configure the plugin.
4. Go to **Settings → Integrations → Directories** and enable the **Enable RealHomes Integration** toggle. Each placement below has its own toggle so you can enable only the ones you want.

RealHomes integration settings

## Setting the RealHomes dashboard as the messages location

Better Messages → **Settings → General** has a **Messages Location** dropdown that controls which page hosts the user inbox. Selecting **Show in RealHomes Dashboard** routes every "open inbox" link in the plugin (notification emails, on-site links, push notifications, the floating bubble, etc.) into the **Messages** tab inside the RealHomes dashboard at `/dashboard/?module=bm-messages`. The dashboard tab is force-enabled and locked while this option is selected — change the Messages Location away from RealHomes to unlock it again.

When this option is active the messenger renders full-screen inside the dashboard frame — same RealHomes sidebar, same dashboard chrome, edge-to-edge messenger surface, no rounded card border. The page-head breadcrumbs are hidden so the conversation pane takes the full available height.

Messages Location dropdown with "Show in RealHomes Dashboard" selected

## Supported features

#### Live Chat row on the single property page

Renders inside each agent's contact card in the property sidebar, alongside the native Office / Mobile / WhatsApp / Fax / Email rows. Each agent linked to the property gets their own button so buyers can pick which agent to message. The button is hidden when the property is unpublished or when the visitor is also the listing's author. Colors match whatever you have configured in **RealHomes Theme Options → Global Styling → Primary Color**.

Property page

#### Live Chat icon on property cards

Adds a small circular icon button to the action row already present on RealHomes v4 property cards (grid and list views), matching the styling of the native Favorite / Compare icons exactly — same 32×32 size, same accent color, same hover transition (filled accent background with white icon). Hidden for cards owned by the current visitor. Hover tooltip uses RealHomes' own `rh-ui-tooltip` so the popup matches the native "Add to compare" / "Add to favorites" tooltips.

Listing grid

Listing list

#### Live Chat row on agent profile pages

Adds a **Live Chat** row to the contact list on the agent profile page, between the native Office / Mobile / Email rows. The button targets the WordPress user linked to the agent through the **User Agent/Agency/Owner ID** mapping in the WP user profile (the `inspiry_role_post_id` user meta). When no linked user exists, the conversation is silently routed to the property's `post_author` and the buyer still sees the agent's name and headshot — see the [persona section](#agent--agency-persona-inside-every-thread) below.

Agent profile

#### Live Chat row on agency profile pages

Same treatment for agency profile pages — the button targets the WordPress user that owns the agency CPT, which is typically the brokerage owner.

Agency profile

#### Live Chat row on agent and agency listing cards

The same contact-item layout appears on every card on the **Agents** (`/our-agents/`) and **Agencies** (`/agencies/`) listings, next to the agent's Office / Mobile / Email so buyers can start a conversation without opening the profile first.

Agents listing with Live Chat row on every card

#### Messages tab inside the RealHomes dashboard

Adds a **Messages** entry to the dashboard sidebar at `/dashboard/`, sitting between **My Saved Searches** and **My Profile**. The tab is registered through the theme's native `realhomes_dashboard_menu` filter, so it renders server-side with the same markup as every other dashboard module — same icon position, same active-state styling, same responsive collapse behaviour. Clicking the tab loads the full Better Messages inbox inline at `/dashboard/?module=bm-messages`, dropping the messenger into the dashboard content area between the existing sidebar and topbar.

The integration **does not replace** RealHomes' built-in CRM Inquiries panel — both can coexist. If you want the native one gone, enable **Hide Native Inquiries Tab** in the integration settings; the `crm/inquiries` sub-item is removed from the **Properties CRM** submenu so users only see the Better Messages tab.

RealHomes dashboard with messenger loaded inline

#### Live unread badge on the Messages tab

The Messages entry in the dashboard sidebar carries a **live unread badge** — a small circle with the total number of unread messages — so users see new inquiries from anywhere in the dashboard. It updates the instant a message arrives (WebSocket version) or within a few seconds via polling (free version), and clears as soon as the user opens the unread thread. The same badge is mirrored on the **Messages** link inside the header user-avatar dropdown, so an agent never has to land on the dashboard to know there's something new. Page title is also prefixed with `(N)` while the count is above zero.

RealHomes dashboard sidebar with a "1" unread badge on the Messages tab

#### Messages link inside the header user dropdown

A **Messages** link is also injected into the header user-avatar dropdown (the menu that appears when you click your avatar in the top bar), positioned right before **My Profile**. It links to the same `/dashboard/?module=bm-messages` URL and shows the same unread badge, so buyers and agents can jump to the inbox from any page on the site without having to open the dashboard first.

#### Listing info card inside the conversation

Conversations started from a property page or listing card show the property's image, title, price, basic specs (beds / baths / sq ft) and address pinned to the top of the messenger. Clicking the property opens the listing in a new tab.

#### Example: buyer ↔ agent conversation

A real exchange between a buyer (John Doe) and an agent (Melissa William) about the Home in Merrick Way. The property context card (For Sale badge, photo, price, beds / baths / sq ft, address) is pinned at the top — the yellow **"Chatting as Melissa William"** banner just below tells the routed receiver which agent persona this conversation is attributed to. Messages flow naturally back and forth on the same surface, no email roundtrip.

Buyer ↔ agent conversation on the RealHomes dashboard with property context card and persona banner

#### Agent / agency persona inside every thread

Buyers always see the agent or agency CPT identity as the other side of the conversation — never the underlying WordPress account. The thread sidebar, conversation header, message sender chips, info panel, mini chat widget and call screen all show the **agent's full name and headshot** (or **agency name and logo**) from the RealHomes CPT, with a clickable link straight to the agent / agency profile page.

This works **even when the agent or agency CPT has no linked WordPress user** — the chat is silently routed to the property's `post_author` (or the agency owner), but the buyer still sees the persona's name, photo and profile URL. A single fallback account can route inquiries for several different agents at once and the buyer sees each conversation as a chat with a distinct agent.

On the routed receiver's side, the messenger keeps their **real WordPress identity** in the bottom-left profile widget (no leakage into self-view) and shows a yellow **"Chatting as [Agent name]"** banner above the property card, so they always know which persona the buyer thinks they are talking to.

This is a reusable Better Messages mechanism — see the developer guide on [per-thread "fake users"](/docs/development/guides/per-thread-fake-users/) for how the same pattern is built into Better Messages and how to reuse it in your own integrations.

## Shortcodes for custom placement

If the auto-injected buttons don't land where you want them (custom Elementor template, sidebar widget, theme override, etc.), drop the matching shortcode wherever you need.

:::info
Disable the corresponding toggle (**Property Page Button** / **Agent and Agency Profile Button** / **Property Card Button** / **Agent Listing Card Button**) before placing the shortcode, otherwise the button will be rendered twice — once auto-injected and once by the shortcode.
:::

### `[better_messages_realhomes_property_button]`

Renders the **Live Chat** button targeted at one of the property's agents. Uses the current property when no `property_id` is supplied and the property's first published agent.

| Attribute | Default | Notes |
|---|---|---|
| `property_id` | current property | Override the property the button targets |
| `agent_id` | first published agent on the property | Override which agent receives the conversation |
| `text` | `Live Chat` | Override the button label |

```text
[better_messages_realhomes_property_button]
[better_messages_realhomes_property_button property_id="101"]
[better_messages_realhomes_property_button agent_id="57"]
```

### `[better_messages_realhomes_property_card_button]`

Renders the smaller card-style **Live Chat** icon button used inside listing cards.

| Attribute | Default | Notes |
|---|---|---|
| `property_id` | current property | Override the property the button targets |
| `text` | `Live Chat` | Tooltip text (the button is icon-only) |

```text
[better_messages_realhomes_property_card_button]
[better_messages_realhomes_property_card_button property_id="101"]
```

### `[better_messages_realhomes_agent_button]`

Renders the **Live Chat** button targeted at the agent's linked WordPress user. Pass `style="contact-item"` to get the small inline contact-row variant (same as the auto-injected one in the contacts list); omit it to get the full-width primary button.

| Attribute | Default | Notes |
|---|---|---|
| `agent_id` | current agent | Override the agent post the button targets |
| `style` | full-width button | Pass `contact-item` for the inline contact-row variant |
| `text` | `Live Chat` / `Send a message` | Override the visible label |

```text
[better_messages_realhomes_agent_button]
[better_messages_realhomes_agent_button agent_id="57"]
[better_messages_realhomes_agent_button style="contact-item"]
```

### `[better_messages_realhomes_agency_button]`

Renders the **Live Chat** button targeted at the agency's linked WordPress user. Same attributes as the agent shortcode.

```text
[better_messages_realhomes_agency_button]
[better_messages_realhomes_agency_button agency_id="4577"]
[better_messages_realhomes_agency_button style="contact-item"]
```

## Theme color inheritance

The Live Chat buttons read **RealHomes' own `--rh-global-color-primary` CSS variable** (set from **Theme Options → Global Styling → Primary Color**) and use it for the button background, the property-card icon accent, the price label inside the thread context card, and the dashboard sidebar highlight. Change the RealHomes primary color and every Better Messages surface updates on the next page load — no extra configuration needed, no PHP options to read, no caching to flush.

## Frequently asked questions

### Does it work with all RealHomes design variations?

Yes. The integration's DOM selectors match the `ultra`, `modern` and `classic` design variations, plus the Elementor templates RealHomes Studio ships. For property cards rendered through custom Elementor templates or page builder widgets that don't follow the v4 grid / list templates, use the `[better_messages_realhomes_property_card_button]` shortcode inside the template if the auto-injection doesn't catch the custom widget.

### Should I disable the native RealHomes CRM Inquiries panel?

It's optional. The two systems coexist — the RealHomes CRM keeps the email-inquiry workflow it always had (when buyers submit the **Send Message** form on a listing), Better Messages adds the real-time conversation channel on the same page. If you want a single inbox, enable **Hide Native Inquiries Tab** in the integration settings; the `crm/inquiries` sub-item is removed from the dashboard sidebar.

### Can buyers chat without registering?

Yes — if Guest Chat is enabled in **Better Messages → Settings → General → Guest Chat**, anonymous visitors can use the Live Chat buttons without logging in. The RealHomes user dashboard requires login, so the Guest Chat row also exposes a **Guest Messages Page** picker — set it to a regular public WordPress page (or one-click create one) and guests reach the messenger there from every chat trigger and email link. See [Guest access → Guest Messages Page](/docs/features/guest-access/#guest-messages-page).

### What happens when a property is unpublished?

The Live Chat button is hidden when the property is not published. Existing threads remain readable.

### Does it work on agent or agency CPTs that don't have a linked WordPress user?

Yes. When the agent or agency CPT has no WordPress user linked through the **User Agent/Agency/Owner ID** mapping, the chat is silently routed to the property's `post_author` (or the agency owner). The buyer still sees the agent's name, headshot and profile URL in the conversation — the routed receiver sees a yellow **"Chatting as [Agent name]"** banner above the property card so they know which persona the buyer is contacting. The same fallback account can host inquiries for several different agent CPTs and every thread still shows its own distinct persona to the buyer.

### Can I move the Live Chat link to a different position in the contact list?

The link is appended to the `.agent-contacts-list` flex container that holds the native Office / Mobile / Email rows, so it naturally fills the next column in the responsive grid. To move it elsewhere, disable the **Agent and Agency Profile Button** toggle and drop the `[better_messages_realhomes_agent_button style="contact-item"]` shortcode wherever you want it.

## See also

- [Per-thread "fake users"](/docs/development/guides/per-thread-fake-users/) — how the agent / agency persona display works under the hood, with the recipe for reusing the same pattern in your own integrations
- [WordPress real estate chat](/blog/wordpress-real-estate-chat/) — adjacent real-estate use case
- [Houzez integration](/docs/integrations/houzez/) — the sister Inspiry-family real-estate theme
- [HivePress integration](/docs/integrations/hivepress/) — for HivePress-based listing sites
- [Directorist integration](/docs/integrations/directorist/) — for general directory sites
- [GeoDirectory integration](/docs/integrations/geodirectory/)
- [Motors integration](/docs/integrations/motors/) — Stylemix Motors classifieds

---

## Better Messages for SureDash: Real-Time Chat for SureDash Portals


The **SureDash integration** for Better Messages adds a real-time messenger to SureDash portals — Messages embedded inside the portal, Private Message button on every profile, audio and video call buttons (WebSocket version), compact message icon next to post and comment authors in discussions, sidebar Messages link with live unread counter, and automatic dark / light mode mirroring. Works on both the free and WebSocket versions of Better Messages.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install SureDash

**[Download SureDash](https://www.wordplus.org/suredash)** from official website and install following standard WordPress installation process

### How to install Better Messages with SureDash
1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress
3. Use the **Better Messages** -> **Settings** menu to configure the plugin
4. Set **Show in SureDash Portal** in Better Messages location settings.
5. Go to **WP Admin** -> **Better Messages** -> **Settings** -> **Integrations** -> **SureDash** and configure integration

:::note
The **SureDash** tab in Better Messages integration settings only appears when the SureDash plugin is installed and active.
:::

### Supported features

When you install the SureDash plugin with Better Messages:

- Messages page is embedded directly into the SureDash portal
- Adds private message button to SureDash user profile pages
- Adds compact message icon next to post and comment authors in SureDash discussions
- Messages link with unread counter in SureDash sidebar navigation
- Messages link with unread counter in SureDash user profile dropdown menu
- All links to user profiles in Better Messages Interface automatically point to SureDash user profiles
- Automatic switch between dark and light modes based on SureDash settings
- Adds video and audio call buttons to user profiles

## Frequently asked questions

### Does SureDash have its own messaging that I should disable?

SureDash does not ship with a separate messenger — Better Messages adds the layer cleanly without a conflict.

### Will the dark-mode switch follow my SureDash settings exactly?

Yes — Better Messages mirrors the SureDash portal's active mode (light / dark / system).

### Can I configure messaging permissions by SureDash community / Space?

SureDash Spaces map to WordPress roles or to SureDash's own capability flags, which Better Messages reads via its permissions layer.

### Are SureDash profile call buttons hidden for non-friends?

The Audio and Video Call buttons have a **friends-only** option in **Better Messages → Settings → Calls**.

### Will the sidebar Messages link respect SureDash's sidebar customization?

Yes — registered through SureDash's standard sidebar API.

## See also

- [SureDash messaging plugin](/blog/suredash-messaging-plugin/) — full feature write-up
- [WordPress community chat plugin](/blog/wordpress-community-chat-plugin/) — comparing community platforms
- [FluentCommunity integration](/docs/integrations/fluentcommunity/) — closest peer for portal-style communities
- [WordPress video call plugin](/blog/wordpress-video-call-plugin/) — audio / video calls on profiles

---

## Better Messages for Tutor LMS: Student & Instructor Messaging


The **Tutor LMS integration** for Better Messages adds a Message Instructor button on every course page, a Messages tab inside the Tutor LMS dashboard for both students and instructors, an auto-managed Course Group Chat tied to enrollment, and Send Message buttons on both the public instructor and student profiles. Works on both the free and WebSocket versions of Better Messages.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install Tutor LMS

**[Download Tutor LMS](https://www.wordplus.org/tutorlms)** from the WordPress plugin directory and install it through the standard WordPress installation process.

### How to install Better Messages with Tutor LMS

1. Install Better Messages through the WordPress plugins screen, or upload the plugin files to `/wp-content/plugins/bp-better-messages`.
2. Activate the plugin through the **Plugins** screen.
3. Go to **Better Messages → Settings → Integrations → LMS** to enable the integrations you want.

Tutor LMS integration settings

## Supported features

### Message Instructor button on course page

Adds a **Message Instructor** button to every Tutor LMS course page. Students can open a private conversation with the course instructor with a single click.

Message Instructor button on the course page

The button is styled to match the native Tutor LMS course buttons and is hidden for the instructor on their own course.

Enable in **Better Messages → Settings → Integrations → LMS → Tutor LMS Integration → Message Instructor Button**.

### Send Message button on instructor profile

Adds a **Send Message** button to the Tutor LMS public instructor profile (`/profile//?view=instructor`) so visitors can reach the instructor directly from their profile.

Send Message button on the instructor profile page

Enable in **Better Messages → Settings → Integrations → LMS → Tutor LMS Integration → Send Message Button on Instructor Profile**.

### Send Message button on student profile

Adds a **Send Message** button to the Tutor LMS public student profile (`/profile//?view=student`) so other learners can reach the student from their public profile page.

Send Message button on the student profile page

Enable in **Better Messages → Settings → Integrations → LMS → Tutor LMS Integration → Send Message Button on Student Profile**.

### Course Group Chat

When a course is opened, Better Messages automatically creates a group conversation that the instructor — including any co-instructors — and every enrolled student can join. Students are added on enrollment and removed when their enrollment ends or is cancelled.

The conversation header shows the course thumbnail, title, and instructor name, so students always know which course the discussion belongs to.

Course group thread with the course info card

Enable in **Better Messages → Settings → Integrations → LMS → Tutor LMS Integration → Course Group Chat**.

The course info card pictured above is rendered automatically above the conversation. It also appears on private DMs opened through the **Message Instructor** button so the recipient knows which course you are asking about. To hide it on every LMS course conversation, turn off **Better Messages → Settings → Integrations → LMS → Shared Course Settings → Course Info Card**.

### Courses widget

Once Course Group Chat is enabled, the user's enrolled courses surface in the dedicated [Courses widget](/docs/features/mini-widgets/) on the Mini Widgets bar, Side Panel, and Mobile bar — separate from the social Groups widget so academic chats and friend cohorts don't mix in one list.

Courses widget on a Tutor LMS site showing the student's enrolled courses

Configure the icon, role restrictions and "Hide Tab When Empty" behaviour under **Better Messages → Settings → Mini Widgets → Courses**.

### Shared course settings

Three toggles under **Better Messages → Settings → Integrations → LMS → Shared Course Settings** apply to every LMS course conversation across LearnDash, LearnPress, Tutor LMS, MasterStudy LMS and FluentCommunity Courses:

- **Course Info Card** *(on by default)* — show the title, image and instructor name banner above each course conversation, including the private DM opened by **Message Instructor**. Turn off to hide the banner everywhere.
- **Email Notifications** *(on by default)* — send the standard "new message" email to participants when activity happens in a course chat. Turn off if your students do not rely on email or you want to reduce traffic.
- **Push Notifications** *(off by default)* — send browser and mobile push notifications for new course messages. Requires a WebSocket license.

Changing any of these toggles propagates across all four LMS integrations.

### Messages Dashboard Tab

Adds a **Messages** tab to the Tutor LMS dashboard for both students and instructors (`/dashboard/messages/`). The tab embeds the full Better Messages inbox so users can read and reply to conversations without leaving the dashboard.

Messages tab inside the Tutor LMS dashboard

Enable in **Better Messages → Settings → Integrations → LMS → Tutor LMS Integration → Messages Dashboard Tab**.

### Use the Tutor LMS dashboard as the primary messages location

Open **Better Messages → Settings → General → Messages Location** and choose **Show in Tutor LMS Dashboard** to redirect every internal Messages link (notifications, the **All messages** link in mini-chats, etc.) to the Tutor LMS dashboard Messages tab.

Messages Location dropdown set to Show in Tutor LMS Dashboard

When this option is selected, the **Messages Dashboard Tab** toggle is enabled and locked automatically — without it the redirect would have no destination.

Messages Dashboard Tab locked on when Messages Location uses the dashboard

## Shortcodes for custom placement

If the auto-injected buttons don't land where you want them (custom layout, sidebar widget, page builder, etc.), drop the matching shortcode wherever you need.

:::info
Disable the corresponding toggle (**Message Instructor Button** / **Send Message Button on Instructor Profile** / **Send Message Button on Student Profile**) before placing the shortcode, otherwise the button will be rendered twice — once auto-injected and once by the shortcode.
:::

### `[better_messages_tutorlms_course_button]`

Renders the **Message Instructor** button for a Tutor LMS course. Falls back to the current course post when no `course_id` is supplied.

| Attribute | Default | Notes |
|---|---|---|
| `course_id` | current post | Override the course the button targets |
| `user_id` | course author | Override the message recipient (instructor) |
| `class` | Tutor LMS button classes | Override CSS classes |
| `text` | `Message Instructor` | Override the button label |

```text
[better_messages_tutorlms_course_button]
[better_messages_tutorlms_course_button course_id="123"]
[better_messages_tutorlms_course_button text="Ask the instructor"]
```

### `[better_messages_tutorlms_instructor_button]`

Renders the **Send Message** button on a Tutor LMS instructor public profile. Resolves the instructor from the `tutor_profile_username` query var by default.

| Attribute | Default | Notes |
|---|---|---|
| `user_id` | profile owner | Override the message recipient |
| `class` | Tutor LMS button classes | Override CSS classes |
| `text` | `Send Message` | Override the button label |

```text
[better_messages_tutorlms_instructor_button]
[better_messages_tutorlms_instructor_button user_id="42"]
```

### `[better_messages_tutorlms_student_button]`

Renders the **Send Message** button on a Tutor LMS student public profile. Resolves the student from the `tutor_profile_username` query var by default.

| Attribute | Default | Notes |
|---|---|---|
| `user_id` | profile owner | Override the message recipient |
| `class` | Tutor LMS button classes | Override CSS classes |
| `text` | `Send Message` | Override the button label |

```text
[better_messages_tutorlms_student_button]
[better_messages_tutorlms_student_button user_id="42"]
```

## Frequently asked questions

### Will students from different courses end up in the same chat?

No — each Tutor LMS course has its own Course Group Chat with the relevant students and instructor.

### What happens when a student's enrollment ends?

Tutor LMS fires its standard enrollment hooks; Better Messages removes the student from the Course Group Chat. Their previous messages stay in history.

### Does it work with Tutor LMS Pro features?

Yes — the integration listens to Tutor LMS core hooks. WooCommerce-based payments, subscriptions, and certificates work alongside the messenger.

### Can co-instructors be added to the course chat?

Yes — co-instructors marked on the Tutor LMS course are auto-joined as instructors of the matching course chat.

### Does it work alongside LearnDash / LearnPress / MasterStudy LMS?

Yes — multi-LMS sites see all course chats together in the shared Courses widget.

## See also

- [Tutor LMS student messaging plugin](/blog/tutor-lms-student-messaging/) — full feature write-up with screenshots
- [WordPress LMS chat plugin](/blog/wordpress-lms-chat-plugin/) — comparing every LMS integration
- [LearnDash integration](/docs/integrations/learndash/) — for LearnDash sites
- [LearnPress integration](/docs/integrations/learnpress/) — for LearnPress sites
- [MasterStudy LMS integration](/docs/integrations/masterstudy-lms/) — for MasterStudy sites
- [Group conversations](/docs/features/group-conversations/) — underlying group chat feature
- [Mini widgets](/docs/features/mini-widgets/) — Courses widget configuration

---

## Better Messages for Ultimate Member: Real-Time Private Messaging


The **Ultimate Member integration** for Better Messages hooks into every Ultimate Member surface — the profile **Messages** tab, the **Private Message** button on user profiles and members directory, and integration with the UM Friends, UM Followers, and UM Groups extensions. If you are using the **Ultimate Member Messages** add-on, deactivate it after installing Better Messages to avoid a double-messenger conflict.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install Ultimate Member

**[Download Ultimate Member](https://www.wordplus.org/ultimate-member)** from the official WordPress.org repository and install it through the standard plugin flow.

### How to install Better Messages with Ultimate Member

1. Install Better Messages from **Plugins → Add New** or by uploading the plugin zip
2. Activate Better Messages
3. Create the WordPress page where the Better Messages page will live (or reuse an existing one)
4. Open **Better Messages → Settings** and set **Messages Location** to the page you just created — or set it to **Show in Ultimate Member profile** to embed Better Messages inside the UM profile **Messages** tab instead of using a separate page
5. If the **Ultimate Member Messages** add-on is still active, **deactivate it** — it conflicts with Better Messages
6. Open **Better Messages → Settings → Integrations → Ultimate Member** to fine-tune the integration

## What gets integrated automatically

When Ultimate Member is detected, Better Messages turns on every UM-specific touch-point with no manual setup:

- A **Messages** tab is added to the Ultimate Member profile for the currently logged-in user; the tab embeds the full Better Messages interface so users never leave their UM profile
- A live **unread counter** badge appears on the **Messages** tab whenever there are new messages, updating in real time
- A **Private Message** button is added to every user profile (configurable) and to every members directory row (configurable)
- All avatars and profile links in the Better Messages interface use Ultimate Member's data — so users land on the UM profile, not the WordPress one
- **UM Friends** drives Better Messages' Friends widget (mini, mobile, and combined variants) and the recipient search inside the New Conversation popup
- **UM Followers** can be used to restrict messaging — only users who follow each other are allowed to start a conversation
- **UM Groups** drives Better Messages' Groups widget; group chats can be created automatically from a UM group, with members joining and leaving in sync

#### Messages tab in the Ultimate Member profile

When the logged-in user opens their own UM profile, a new **Messages** tab is added next to the default tabs (About, Posts, Comments, etc.). Clicking it embeds the full Better Messages interface inside the profile — conversations list, message thread, composer — without leaving the UM layout.

The tab also carries a real-time unread badge: as new messages arrive, a numbered counter appears on the **Messages** tab label and disappears once everything is read. The badge uses the same live pipeline as the rest of Better Messages, so it updates without a page reload.

#### Private Message button on user profiles

Every Ultimate Member user profile gets a **Private Message** button rendered in the profile's action area (next to Follow / Friend / Settings). Clicking it opens a new conversation with that user — or, if **Advanced Mini Chats** is enabled, opens a mini chat window without leaving the page.

Ultimate Member profile with the Private Message button rendered next to the avatar

#### Private Message button in the members directory

Every row in the Ultimate Member members directory gets a **Private Message** button (or a mini-chat trigger, depending on the **Advanced Mini Chats** setting). The button is injected through Ultimate Member's own AJAX rendering pipeline, so it appears the same way native UM action buttons do — and pagination / search work unchanged.

#### UM Friends, UM Followers, UM Groups

Better Messages auto-detects each of the official Ultimate Member extensions and wires them into the messaging layer:

- **UM Friends** — the Better Messages Friends widget is populated from the user's UM friends list. Enable **Only Friends Mode** to additionally restrict messaging to friends only, and hide non-friends from the recipient search.
- **UM Followers** — enable **Only Followers Mode** to restrict messaging to users who follow each other. Non-followers cannot start a thread and cannot reply to existing ones.
- **UM Groups** — the Better Messages Groups widget lists every UM group the user belongs to. Each group can optionally have a Better Messages group chat attached: the chat is created the first time the group is opened in Better Messages, and members are added when they join the UM group and removed when they leave. File uploads, email notifications, and push notifications can be toggled per integration.

## Settings reference

All Ultimate Member-specific options live at **Better Messages → Settings → Integrations → Ultimate Member**.

| Setting | What it does |
|---|---|
| **Advanced Mini Chats** | Opens a mini chat window instead of redirecting to the Messages page when a Private Message button is clicked. Requires the WebSocket version |
| **Profile Message Button** | Show a Private Message button on Ultimate Member user profiles |
| **Members List Message Button** | Show a Private Message button in the Ultimate Member members directory |
| **Only Friends Mode** | Restricts messaging to friends only; hides non-friends from search. Requires **UM Friends** |
| **Only Followers Mode** | Restricts messaging to users who follow each other. Requires **UM Followers** |
| **Group Messages** | Enables group chats for Ultimate Member Groups. Requires **UM Groups** |
| **File Uploading** | Allows file uploads in Ultimate Member group chats |
| **Email Notifications** | Sends email notifications for new messages in UM group chats |
| **Push Notifications** | Sends push notifications for new messages in UM group chats (WebSocket) |

## Frequently asked questions

### Does Better Messages replace the Ultimate Member Messages add-on?

Yes. Deactivate the UM Messages add-on when Better Messages is installed — they conflict. Better Messages takes over the same URLs and surfaces.

### Will the profile Messages tab work if I host Better Messages on a separate page?

Yes — embed Better Messages inside the UM profile Messages tab, or set Messages Location to a regular WordPress page and have the tab link to it.

### Can guests message UM members?

Guest Chat is supported when Better Messages is hosted on a public page. Configure under **Settings → Guest Chat**.

### Does it work with custom roles defined in Ultimate Member?

Yes — Better Messages respects WordPress roles, including custom ones UM defines.

### Can I add the Private Message button somewhere custom on the profile?

Yes — the position is configurable in Settings, and the button can be placed manually via shortcode for custom forms or tabs.

## See also

- [Ultimate Member private messaging plugin](/blog/ultimate-member-private-messaging/) — full feature write-up
- [WordPress community chat plugin](/blog/wordpress-community-chat-plugin/) — comparing community platforms
- [BuddyPress integration](/docs/integrations/buddypress/)
- [BuddyBoss integration](/docs/integrations/buddyboss/)
- [PeepSo integration](/docs/integrations/peepso/)
- [Real-time messaging](/docs/features/realtime-messaging/) — what changes with the WebSocket version

---

## Better Messages for Uncanny Automator: Send Automated Private Messages


The **Uncanny Automator integration** for Better Messages registers a new action — **Send a private message to the user** — that any Uncanny Automator recipe can use. Trigger by any Uncanny Automator event (LearnDash completion, WooCommerce subscription renewal, form submission, payment, etc.) and send a private Better Messages DM with token support for dynamic content. Works on both the free and WebSocket versions.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install Uncanny Automator

**[Download Uncanny Automator](https://www.wordplus.org/uncanny)** from official website and install following standard WordPress installation process

### How to install Better Messages with Uncanny Automator
1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress
3. Use the **Better Messages** -> **Settings** menu to configure the plugin
4. Set **Messages Location** to **Show in BuddyPress profile** or you can also set any WordPress page to be a messages homepage

### Supported actions

#### Send a private message to the user



## See also

- [Uncanny Automator send private message](/blog/uncanny-automator-send-private-message/) — full feature write-up with use cases
- [AutomatorWP integration](/docs/integrations/automatorwp/) — same feature on AutomatorWP
- [AI Chat Bots](/docs/features/ai-chat-bots/) — for automated bot-driven replies
- [LearnDash integration](/docs/integrations/learndash/) — common pairing for course-completion automations

---

## Better Messages for UsersWP: Private Messaging on UsersWP Profiles


The **UsersWP integration** for Better Messages adds a Messages tab to the logged-in user's UsersWP profile, a Private Message button on every other user's profile, and uses UsersWP avatars and links throughout the messenger. Commonly paired with GeoDirectory for combined listing + profile messaging. Works on both the free and WebSocket versions.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install UsersWP

**[Download UsersWP](https://www.wordplus.org/userswp)** from official website and install following standard WordPress installation process

### How to install Better Messages with UsersWP
1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress
3. Use the **Better Messages** -> **Settings** menu to configure the plugin
4. Set **Messages Location** to **Show in UsersWP profile** or you can also set any WordPress page to be a messages homepage

### Supported features

When you install UsersWP plugin with Better Messages:

- All avatars in Better Messages interface automatically displayed from UsersWP user profiles
- All links to user profiles in Better Messages interface automatically points to UsersWP user profiles

#### Automatically adding messages tab in currently logged-in user profile
Profile Page

#### Automatically adding private message button in other user profiles
Other Profile Page

## Frequently asked questions

### Where does the Messages tab appear on the UsersWP profile?

The Messages tab is added to the logged-in user's UsersWP profile via UsersWP's standard profile-tab API, so it inherits the existing tab styling and respects the configured tab order.

### Does it work alongside GeoDirectory?

Yes — UsersWP and GeoDirectory share the same team. The two integrations coexist (listing chat on GeoDirectory listings + profile chat on UsersWP profiles).

### Can I restrict messaging by UsersWP user role?

Yes — Better Messages reads WordPress roles; configure in **Settings → Permissions**.

### Can guests message UsersWP members?

Optional — enable Guest Chat in **Better Messages → Settings → Guest Chat**.

### Will the Messages tab respect UsersWP's profile tab order?

Yes — registered through UsersWP's standard profile-tab API.

## See also

- [UsersWP private messaging](/blog/userswp-private-messaging/) — full feature write-up
- [GeoDirectory integration](/docs/integrations/geodirectory/) — common pairing
- [ProfileGrid integration](/docs/integrations/profile-grid/)
- [WP User Manager integration](/docs/integrations/wp-user-manager/)
- [Ultimate Member integration](/docs/integrations/ultimate-member/)

---

## Better Messages for WC Vendors: Live Chat for Marketplace Vendors


The **WC Vendors integration** for Better Messages adds a Live Chat button on every vendor product page, on the vendor store page (classic themes via template hook; block themes via shortcode), and a Messages tab inside the WC Vendors Pro Vendor Dashboard. Works on both the free WC Vendors plugin and WC Vendors Pro. Both the free and WebSocket versions of Better Messages support the integration.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install WC Vendors

**[Download WC Vendors](https://www.wcvendors.com/)** from the official website and install following the standard WordPress plugin installation process.

### How to install Better Messages with WC Vendors
1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress
3. Use the **Better Messages** -> **Settings** menu to configure the plugin
4. Go to **Integrations -> WooCommerce** and **Enable Vendor Live Chat** in the **WC Vendors Integration** section Settings

### Supported features

When you install the WC Vendors plugin with Better Messages:

- Vendors get a new **Live Chats** section in their Shop Settings to enable Live Chat per store
- Vendor avatars in the Better Messages interface are automatically displayed from WC Vendors shop profiles
- Vendor links in the Better Messages interface automatically point to WC Vendors shop pages
- Conversations started from a product page show the product card (image, title, price) inside the thread

#### Adds a Live Chat button to vendor product pages
If you are using a custom page builder or the button does not show up automatically, use this shortcode on your product page: `[better_messages_wc_vendors_product_button]`
Product Page

#### Adds a Live Chat button to the vendor shop page
The button is injected automatically on classic-theme storefronts (for example, **Storefront**) via the `wcvendors_after_main_header` template hook. Block themes do not fire this hook — on those, place the button manually with the shortcode: `[better_messages_wc_vendors_store_button]`

#### Adds a Messages tab to the WC Vendors Pro Vendor Dashboard
Vendors using the **WC Vendors Pro** dashboard get a new **Messages** tab with an unread-message counter. This dashboard tab is only available with WC Vendors Pro — the free plugin does not provide a custom vendor dashboard, so the chat lives on store and product pages instead.

## Free vs WebSocket version for WC Vendors stores

| Feature | Free version | WebSocket version |
| --- | :---: | :---: |
| Live Chat button on product / store pages | yes | yes |
| Messages tab in WC Vendors Pro dashboard | yes | yes |
| Per-vendor enable / disable | yes | yes |
| Vendor avatars and links from WC Vendors shop profile | yes | yes |
| Product card context in threads | yes | yes |
| Real-time delivery | polling | instant |
| Mini-widget popup chat | — | yes |
| One-on-one voice and video calls inside the thread | — | yes |
| Group voice and video calls (vendor team) | — | yes |
| Web push notifications for new messages | — | yes |
| Read receipts | — | yes |
| End-to-end encryption (optional) | — | yes |

:::info
For WC Vendors stores on the free plugin (no vendor dashboard), the WebSocket version's mini-widget popup is the difference between losing the customer when they click Live Chat (navigated away) and keeping them on the product page where they were considering checkout.
:::

## Frequently asked questions

### Does it work with WC Vendors Pro Memberships?

Yes — Better Messages reads vendor capability flags set by Pro Memberships.

### Can vendors message each other?

Yes — the Better Messages inbox is a full messenger. Vendors can also be added to group conversations.

### What if my theme is a block theme?

The store-page button needs a manual shortcode placement on block themes. Product-page buttons render on both classic and block themes.

### Does it work with WC Vendors Stripe payment add-ons?

Yes — payment add-ons extend WC Vendors' vendor capability flags rather than replace them.

### Can guests start a thread?

Yes if **Guest Chat** is enabled in **Better Messages → Settings → Guest Chat**.

## See also

- [WC Vendors chat](/blog/wc-vendors-chat/) — full feature write-up
- [WordPress marketplace chat](/blog/wordpress-marketplace-chat/) — comparing every marketplace integration
- [Dokan integration](/docs/integrations/dokan/)
- [WCFM integration](/docs/integrations/wcfm/)
- [MultiVendorX integration](/docs/integrations/multivendorx/)

---

## Better Messages for WCFM: Live Chat for WCFM Marketplace Vendors


The **WCFM Marketplace integration** for Better Messages adds a Live Chat button on every vendor product page, on the vendor store page, and a Messages menu inside the WCFM Vendor Dashboard with a live unread counter. Vendors enable Live Chat per store from their WCFM settings; products started from the chat show as rich product cards with image, title, and price. Works on both the free and WebSocket versions.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install WCFM Marketplace

**[Download WCFM Marketplace](https://wclovers.com/)** from the official website and install following the standard WordPress plugin installation process. The free **WCFM – WooCommerce Frontend Manager** and **WCFM Marketplace** plugins are both required.

### How to install Better Messages with WCFM Marketplace
1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress
3. Use the **Better Messages** -> **Settings** menu to configure the plugin
4. Go to **Integrations -> WooCommerce** and **Enable Vendor Live Chat** in the **WCFM Marketplace Integration** section Settings

### Supported features

When you install the WCFM Marketplace plugin with Better Messages:

- Vendors get a new **Live Chats** section in their WCFM vendor Settings to enable Live Chat per store
- A **Messages** menu item appears in the WCFM Vendor Dashboard with an unread-message counter
- Vendor avatars in the Better Messages interface are automatically displayed from WCFM store profiles
- Vendor links in the Better Messages interface automatically point to WCFM store pages
- Conversations started from a product page show the product card (image, title, price) inside the thread

#### Adds a Messages menu to the Vendor Dashboard
Vendor Dashboard

#### Adds a Live Chat button to vendor product pages
If you are using a custom page builder or the button does not show up automatically, use this shortcode on your product page: `[better_messages_wcfm_product_button]`
Product Page

#### Adds a Live Chat button to the vendor store page
If you are using a custom page builder or the button does not show up automatically, use this shortcode on your store page: `[better_messages_wcfm_store_button]`
Store Page

## Free vs WebSocket version for WCFM Marketplace stores

| Feature | Free version | WebSocket version |
| --- | :---: | :---: |
| Live Chat on product / store / dashboard | yes | yes |
| Per-vendor enable / disable in WCFM settings | yes | yes |
| Vendor avatars and links from WCFM store profile | yes | yes |
| Product card context in threads | yes | yes |
| Real-time delivery + unread counter | polling | instant |
| Mini-widget popup chat | — | yes |
| One-on-one voice and video calls inside the thread | — | yes |
| Group voice and video calls (vendor team) | — | yes |
| Web push notifications for new messages | — | yes |
| Read receipts | — | yes |
| End-to-end encryption (optional) | — | yes |

:::info
For WCFM marketplaces where vendor responsiveness drives reviews, the WebSocket version's instant delivery plus web push keeps vendors engaged even when their dashboard is closed — the mini-widget popup lets buyers chat without leaving the product page.
:::

## Frequently asked questions

### Does it work with WCFM membership levels?

Yes — Live Chat can be restricted to specific WCFM membership tiers via the role-based access controls.

### Can customers chat without a WordPress account?

Optional — enable Guest Chat in **Better Messages → Settings → Guest Chat**.

### Will the unread counter update in real time?

On the free version it polls; on the WebSocket version it updates instantly when a new message arrives.

### Does it work alongside WCFM's own internal vendor-to-admin messaging?

Yes — those are separate systems. Better Messages adds buyer ↔ vendor chat; WCFM's internal messaging stays for vendor-to-admin coordination.

### What about WCFM Bookings / WCFM Auction?

The integration works regardless of which WCFM add-ons are active.

## See also

- [WCFM Marketplace chat](/blog/wcfm-marketplace-chat/) — full feature write-up
- [WordPress marketplace chat](/blog/wordpress-marketplace-chat/) — comparing every marketplace integration
- [Dokan integration](/docs/integrations/dokan/)
- [WC Vendors integration](/docs/integrations/wc-vendors/)
- [MultiVendorX integration](/docs/integrations/multivendorx/)
- [WooCommerce integration](/docs/integrations/woocommerce/) — for stores without a marketplace layer

---

## Better Messages for WooCommerce: Pre-Sales and Order Support Chat


The **WooCommerce integration** for Better Messages adds a Contact button to **product**, **cart**, **checkout**, and **order** pages, so customers can reach your support team in one click. When a customer starts a chat from the cart or checkout, the contents of their cart are auto-posted as a rich message; when they start from an order page, the order details appear as a context card. HPOS-compatible, block-theme-compatible, and works with guest checkout. Both the free and WebSocket versions support the integration.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

The WooCommerce integration adds a contact button to **product**, **cart**, **checkout**, and **order** pages so customers can reach your support team in one click. When a customer starts a chat from the cart or checkout, the contents of their cart are automatically posted into the conversation as a rich message — your support agent immediately sees what the customer is looking at without having to ask. Plain product URLs pasted in any chat message are also expanded into rich product cards.

:::info[Free vs WebSocket]
All four buttons, the cart snapshot, the product/order context cards, the rich product URL expansion, and the embedded inbox in My Account work on both the **free** and **WebSocket** versions.

The **WebSocket version** adds a popup mini-widget UX: clicking any contact button opens the conversation as a mini chat overlay instead of navigating to the configured chat page. The free version navigates to the configured chat page on every click. When the chat page is WooCommerce My Account (login-only), point guests at a separate **Guest Messages Page** — see [Guest chat with WC My Account](#guest-chat-with-wc-my-account) below.
:::

## Installation

### How to install WooCommerce

**[Download WooCommerce](https://www.wordplus.org/woocommerce)** from the WordPress.org plugin directory and install it through the **Plugins → Add New** screen, or upload the plugin files to `/wp-content/plugins/woocommerce`.

### How to install Better Messages with WooCommerce

1. Install the Better Messages plugin through the WordPress plugins screen, or upload the plugin files to `/wp-content/plugins/bp-better-messages`.
2. Activate the plugin through the **Plugins** screen.
3. Go to **Better Messages → Settings → Integrations → WooCommerce** and enable the integration.

## Settings

All WooCommerce integration settings live in **Better Messages → Settings → Integrations → WooCommerce**.

Settings

Each button is independent — you can enable any combination, choose where it appears, and pick a different recipient for each.

### Enable WooCommerce Integration

The master toggle for the entire integration. When off, none of the buttons appear and none of the WooCommerce-specific message features run.

:::note
Each button (Product / Order / Pre-purchase) requires a **Recipient** to be selected before it renders on the front end. Without a recipient the button is silently hidden. Product and Order buttons are enabled by default; the Pre-purchase button is off by default and must be enabled explicitly.
:::

### Product Page Button

Adds a "Contact us about this product" button on single product pages. When a customer clicks it, a conversation opens with the recipient you've selected. The conversation thread shows the product name, image, and price as a context card so the support agent immediately knows which product the customer is asking about.

#### Automatic Placement

Pick where the button appears on the product page:

- **Above product summary** — directly above the short description
- **Above Add to Cart** — between the short description and the add-to-cart form
- **Below Add to Cart** *(default)* — directly below the add-to-cart form
- **Below product summary** — at the bottom of the entire product summary block
- **Disabled** — the button is not auto-rendered. Use the shortcode below to place it manually

The placements work in both classic themes and modern block themes.

#### Recipient

The user who receives messages from the product button. You can override this on a per-product basis from the product edit screen — useful when different products are handled by different support agents.

#### Per-product override

On the product edit screen, the **Better Messages Contact** sidebar metabox lets you override the global recipient for that specific product. Leave it on "Use default" to fall back to the global setting.

#### Shortcode

If you'd rather place the button manually (custom template, page builder, custom location), use:

```text
[better_messages_woocommerce_product_button]
```

When placed on a single product page, the shortcode auto-detects the current product. You can also pass an explicit `product_id` attribute.

Product page button

### Order Page Button

Adds a "Contact us about this order" button on the order detail page in **My Account → View order**. Only the customer who placed the order can see and use this button — the conversation thread is tagged with the order, and the support agent sees order details (number, status, total, items) as a context card.

#### Automatic Placement

- **Before order table** — above the order items table
- **After order table** *(default)* — directly below the order items table
- **After customer details** — at the bottom of the View Order page
- **Disabled** — manual placement only

#### Recipient

The user who receives messages from the order button. Typically a dedicated order/billing support team.

#### View order link

The thread sidebar shows a "View order" link. The link is **role-aware** — it routes admins and shop managers to the wp-admin order edit screen, and customers to their My Account → View Order page. Same URL, different destinations.

#### Shortcode

```text
[better_messages_woocommerce_order_button]
```

Auto-detects the current order on the View Order endpoint. You can also pass `order_id="123"` explicitly.

Order page button

### Pre-purchase Help Button

Adds a "Need help? Chat with us" button on the **cart** and **checkout** pages so customers can ask questions before completing their purchase. When the customer opens the chat, the contents of their cart are automatically posted as the first message — your support agent sees exactly what the customer is buying without having to ask.

The cart snapshot is **content-aware**: if the customer changes their cart and reopens the chat, a new snapshot is posted. If the cart hasn't changed since the last snapshot, no duplicate message is sent.

#### Cart Page Automatic Placement

- **Below cart items** *(default)* — under the cart items table
- **Top of cart page** — above everything
- **Near cart totals** — alongside the totals/coupon area
- **Next to "Proceed to checkout"** — right beside the proceed button
- **Bottom of cart page** — at the very bottom
- **Disabled** — manual placement only

Cart page button

#### Checkout Page Automatic Placement

- **After order summary** *(default)* — directly under the entire Order summary card
- **Top of checkout page** — above the checkout form
- **Above order summary** — between the form and the order summary
- **Bottom of checkout page** — below everything
- **Disabled** — manual placement only

Checkout page button

#### Recipient

The user who receives pre-purchase questions. Typically your front-line sales support.

#### Shortcode

```text
[better_messages_woocommerce_pre_purchase_button]
```

Place the shortcode anywhere on cart, checkout, or any other page where you'd like a pre-sales contact button.

#### Cart snapshot in the chat

Once the customer opens the chat from the cart or checkout page, the cart contents appear in the thread as a rich message:

Chat with cart info

Each item is clickable and links back to its product page so the support agent can quickly inspect what the customer is looking at.

### Messages link in My Account

Adds a "Messages" item to the WooCommerce My Account menu that links to the Better Messages inbox. When this is enabled and your **Messages Location** (in the General tab) is set to a regular WordPress page, customers can quickly access their conversations from My Account without leaving the WooCommerce navigation.

This toggle is automatically disabled (and forced on) when your Messages Location is set to **"Show in WooCommerce My Account"** — see the next section.

## Embedding the inbox inside WooCommerce My Account

If you'd rather render the **entire** Better Messages inbox as a tab inside WooCommerce My Account (instead of a link to a separate page), go to **Better Messages → Settings → General → Messages Location** and pick **"Show in WooCommerce My Account"** from the dropdown.

Messages location

You can also customize the URL slug for the My Account messages tab — the default is `messages`, producing a URL like `/my-account/messages/`.

When this mode is selected:

- The Better Messages inbox is rendered inside the WooCommerce My Account layout
- Notifications (email, push, on-site) link to the WooCommerce My Account messages URL
- The "Messages link in My Account" toggle in the WooCommerce integration tab becomes redundant (the link is added automatically)

Embedded inbox in My Account

### Guest chat with WC My Account

If you've enabled **Guest Chat** in **Better Messages → Settings → General** *and* set your Messages Location to **WooCommerce My Account**, there's an important UX consideration: the WooCommerce My Account page requires login, so guests can't actually open the inbox there.

The Guest Chat row in **Settings → General** then exposes a **Guest Messages Page** picker. Pick (or one-click create) a regular public WordPress page — guests reach that page from every chat trigger and notification link. Logged-in customers continue to use the embedded inbox inside My Account, and visiting the Guest Messages Page also renders the messenger for them, so the same page works for both audiences. This works on the **free** and **WebSocket** versions.

:::info[WebSocket adds an inline option]
On the **WebSocket version** with mini widgets enabled, Better Messages also renders the mini-chat popup for guests on product / cart / order pages — guests can chat without ever leaving the page. The mini widget and the Guest Messages Page complement each other: the mini handles in-page conversations, the page handles email / push notification links. See [Guest access → Guest Messages Page](/docs/features/guest-access/#guest-messages-page).
:::

## Rich product cards in chat

When anyone pastes a link to one of your WooCommerce products into a chat message, the link is automatically expanded into a rich card showing the product image, title, and price. This works in any conversation — between customers and support, between customers and other users, anywhere.

Chat with cart info and product

The detection works on links that point to your site (matching the configured `home_url`) and resolve to a `product` post type. Cross-site product links are left as plain links.

## Supported features summary

When you install Better Messages with WooCommerce:

- Adds a **Contact us about this product** button on single product pages with 4 placement options + manual mode
- Per-product recipient override from the product edit screen
- Adds a **Need help? Chat with us** button on cart and checkout pages with 5 cart and 4 checkout placement options
- Auto-posts the customer's current cart contents as a rich message when they start a chat from cart or checkout
- Adds a **Contact us about this order** button on the order detail page in My Account
- Order, product, and pre-purchase chats each have their own configurable recipient
- Universal "View order" link in the thread sidebar — routes admins to wp-admin and customers to My Account
- Optional Messages link in the WooCommerce My Account menu
- Optional embedding of the entire inbox as a My Account tab
- Plain WooCommerce product URLs pasted in any chat message are auto-expanded into rich product cards
- HPOS (High-Performance Order Storage) compatible
- Block themes and classic themes both supported
- Modern WooCommerce Cart and Checkout blocks supported alongside the legacy `[woocommerce_cart]` / `[woocommerce_checkout]` shortcodes
- Guest checkout supported when guest chat is enabled

### WebSocket-only enhancements

The following behaviors require the [WebSocket version](https://www.wordplus.org/bp-better-messages):

- **Mini widget popup** — clicking any of the four buttons opens the conversation as an inline popup overlay rather than navigating away. The cart, checkout, product, and order pages stay visible while the customer chats.
- **Real-time replies** — the customer sees the agent's reply appear in the popup the instant it's sent, without polling.
- **Automatic guest fallback to mini widget** when Messages Location is WooCommerce My Account (a logged-in-only page). Without this fallback the guest is redirected to wp-login on the post-auth navigation.
- **Voice / video calls** initiated from the chat sidebar (when Calls are enabled).
- **End-to-end encryption** of message content (opt-in per thread).

## Frequently asked questions

### Can different products go to different support agents?

Yes — set a global recipient in WooCommerce settings, then override per product from the product edit screen's **Better Messages Contact** sidebar metabox.

### Does it work with HPOS?

Yes — High-Performance Order Storage is supported. Orders are read through WooCommerce's CRUD layer.

### Does it work with the modern Cart and Checkout blocks?

Yes — both the legacy `[woocommerce_cart]` / `[woocommerce_checkout]` shortcodes and the modern WooCommerce Cart and Checkout blocks are supported.

### Can guests use the pre-sales chat?

Yes — enable Guest Chat in **Better Messages → Settings → Guest Chat**. Guests enter a name and email, then chat with support.

### Does it work alongside Dokan / WCFM / MultiVendorX / WC Vendors?

Yes — the WooCommerce integration handles store-level support chat; the multi-vendor integration handles buyer ↔ vendor chat. They coexist.

## See also

- [WooCommerce customer chat](/blog/woocommerce-customer-chat/) — full feature write-up
- [WordPress marketplace chat](/blog/wordpress-marketplace-chat/) — comparing Dokan, WCFM, WC Vendors, MultiVendorX
- [Dokan integration](/docs/integrations/dokan/)
- [WCFM integration](/docs/integrations/wcfm/)
- [WC Vendors integration](/docs/integrations/wc-vendors/)
- [MultiVendorX integration](/docs/integrations/multivendorx/)
- [WordPress guest chat](/blog/wordpress-guest-chat-without-login/) — guest pre-sales chat

---

## Better Messages for WP Job Manager: Candidate ↔ Employer Chat


The **WP Job Manager integration** for Better Messages adds a Send Message button on every active job listing — candidates start a private thread with the employer directly on the site. The integration automatically gates new messages when the job is filled or expired so closed listings stop receiving inquiries. Works on both the free and WebSocket versions.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install WP Job Manager

**[Download WP Job Manager](https://www.wordplus.org/wpjobmanager)** from official website and install following standard WordPress installation process

### How to install Better Messages with WP Job Manager
1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress
3. Use the **Better Messages** -> **Settings** menu to configure the plugin
4. Go to **Integrations -> Directories** and **Enable Live Chat for Job Listings** in **WP Job Manager Integration** section Settings

After the option is activated, all active job listings that are not filled or expired will have "Send Messages" button after job listing description.
Job Listing

After pressing the Send Message button, user will be directed to private conversation screen, where he can contact job listing author:
Job Messages

If after the conversation is created, the job listing item is filled or expired, the user will not be able to send messages anymore and will see the following messages:
Job Filled
Job Expired

## Frequently asked questions

### Can candidates see other candidates' applications?

No — every thread is private between the candidate who started it and the employer who posted the listing.

### Will the chat history be visible after the role is filled?

Yes — messages stay readable on both sides. The integration only blocks new outgoing messages on filled and expired listings.

### Can employers initiate the conversation?

Yes — employers can DM candidates directly once a thread exists, or start a thread from their own dashboard.

### Does it work with paid-listings extensions like WC Paid Listings?

Yes — the integration listens to WP Job Manager's listing-status hooks, which paid-listings extensions use to mark listings active / filled / expired.

### Can I move the button to a different position on the listing page?

Yes — the button is auto-rendered after the job description by default; position can be overridden via custom hook priority or manual shortcode placement.

## See also

- [WP Job Manager candidate-employer chat](/blog/wp-job-manager-candidate-employer-chat/) — full feature write-up
- [WP User Manager integration](/docs/integrations/wp-user-manager/) — common pairing for candidate profiles
- [Role-based access](/docs/features/role-based-access/) — candidate / employer role gating
- [WordPress video call plugin](/blog/wordpress-video-call-plugin/) — for inline interview calls

---

## WP User Manager (WPUM) Messaging: Profile-Driven Chat

# Better Messages for WP User Manager (WPUM): Profile-Driven Private Messaging

The **WP User Manager integration** for Better Messages adds a Messages tab to the logged-in user's WPUM profile, a Private Message button on every other user's profile, and uses WPUM avatars and links throughout the messenger. Commonly paired with WP Job Manager (same author) for combined job-listing + profile messaging. Works on both the free and WebSocket versions.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install WP User Manager

**[Download WP User Manager](https://www.wordplus.org/wp-user-manager)** from official website and install following standard WordPress installation process

### How to install Better Messages with WP User Manager
1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress
3. Use the **Better Messages** -> **Settings** menu to configure the plugin
4. Set **Messages Location** to **Show in WP User Manager profile** or you can also set any WordPress page to be a messages homepage

### Supported features

When you install WP User Manager plugin with Better Messages:

- All avatars in Better Messages interface automatically displayed from WP User Manager user profiles
- All links to user profiles in Better Messages interface automatically points to WP User Manager user profiles

#### Automatically adding messages tab in currently logged-in user profile
Profile Page

#### Automatically adding private message button in other user profiles
Other Profile Page

## Frequently asked questions

### Does it work alongside WP Job Manager?

Yes — same author. Sites running both get layered messaging: job-listing chat on every published job, profile chat on every WPUM profile.

### Can I restrict messaging by WPUM user group?

WPUM user groups map to WordPress roles, which Better Messages reads via **Settings → Permissions**.

### Can guests message WPUM members?

Optional — enable Guest Chat in **Better Messages → Settings → Guest Chat**.

### Will the Messages tab integrate with WPUM's profile tab system?

Yes — registered through WPUM's standard profile-tab API.

## See also

- [WP User Manager private messaging](/blog/wp-user-manager-private-messaging/) — full feature write-up
- [WP Job Manager integration](/docs/integrations/wp-job-manager/) — common pairing
- [ProfileGrid integration](/docs/integrations/profile-grid/)
- [UsersWP integration](/docs/integrations/userswp/)
- [Ultimate Member integration](/docs/integrations/ultimate-member/)

---

## Better Messages for wpForo: Private Messaging for Forum Users


The **wpForo integration** for Better Messages adds a Private Message button on every wpForo user profile and uses wpForo avatars and profile links throughout the messenger. Forum users take threads private out of public view without leaving the site. Works on both the free and WebSocket versions.

:::info REQUIREMENTS

To install the plugin ensure that your website running:

- **WordPress 5.9 or newer**
- **PHP 7.4 or newer**

:::

## Installation

### How to install wpForo

**[Download wpForo](https://www.wordplus.org/wpforo)** from official website and install following standard WordPress installation process

### How to install Better Messages with wpForo
1. Install the plugin through the WordPress plugins screen directly or upload the plugin files to the `/wp-content/plugins/bp-better-messages` directory.
2. Activate the plugin through the **Plugins** screen in WordPress
3. Use the **Better Messages** -> **Settings** menu to configure the plugin
4. Create WordPress page where the messages will be located
5. Set **Messages Location** to created WordPress page

### Supported features

When you install wpForo plugin with Better Messages:

- All avatars in Better Messages interface automatically displayed from wpForo user profiles
- All links to user profiles in Better Messages interface automatically points to wpForo user profiles

#### Automatically adding private message button in other user profiles
Other Profile Page

## Frequently asked questions

### Does it replace wpForo's built-in Private Messages?

It takes over the same Private Message button URLs, so members never see the old PM component. The native PM can be left active or disabled.

### Will existing wpForo PM threads survive?

The data stays in the database. wpForo's PM reads its own tables; Better Messages reads its own. They do not interfere.

### Does it integrate with wpForo's forum-level moderation?

Better Messages has its own moderation layer (pre-moderation, bad-words filter, user reports) that works on every messenger surface.

### Can forum members message each other in groups?

Yes — Better Messages supports group conversations. Combine with BuddyPress / BuddyBoss Groups for paired group chats.

### Does it work with wpForo Pro Memberships?

Yes — Pro maps subscription tiers to WordPress roles, which Better Messages reads.

## See also

- [wpForo private messages](/blog/wpforo-private-messages/) — full feature write-up
- [BuddyPress integration](/docs/integrations/buddypress/) — for forums + community on BuddyPress
- [BuddyBoss integration](/docs/integrations/buddyboss/) — for forums + community on BuddyBoss
- [Group conversations](/docs/features/group-conversations/) — for forum-style group chats

---

## Native Android Messenger App for WordPress

:::info WebSocket Version Guide

<>This functionality available only with WebSocket Version

:::
:::info Compatibility

<>This { (props.type ? props.type : 'guide') } compatible with Better Messages {props.version} or higher

:::

Android application feature allows you to generate native Android messenger application for your website, which allows you to send push and call notifications and can be published to the Google Play Market.

## Requirements

- ### Firebase Project
   To be able to generate and publish Android application, you need to have [Firebase Project](https://console.firebase.google.com/) with enabled Firebase Cloud Messaging (FCM).

- ### Play Market Developer Account (Production Only)
   To be able to publish Android application to the Google Play Market, you need to have [Google Play Developer Account](https://play.google.com/console/about/) (25 USD one-time fee).

- ### Android Device
   To be able to install and test an Android application, you need to have Android device.

## Create Firebase Project

For building Android application, you need to create Firebase Project and enable Firebase Cloud Messaging (FCM) for it.

Follow these steps to create Firebase Project:

1. Go to [Firebase Console](https://console.firebase.google.com/) and login with your Google Account.

2. Click on **Create a Firebase Project** button to create a new Firebase Project.

    Firebase Create Project
3. Enter your project name (for example `yourwebsite-messenger`) and click on **Continue** button.

    Firebase Project Name

    Press continue until you reach the **Project Overview** page.

4. Click on the **Add app** button and select **Android**.

    Firebase Add Android App

5. Enter your Android package name (for example `com.yourdomain.messenger`), app nickname and SHA-1 certificate fingerprint are optional and not required to be filled and click on **Register app** button.

    Firebase Register Android App
    > The Android package name must be unique and should follow the reverse domain name notation (e.g., `com.yourdomain.messenger`).

    > For development and production applications, you can use the same package name, but it is recommended to use different package names for development and production applications to avoid conflicts.

    > You can add one more Android package name for development purpose to the same Firebase Project or create a separated Firebase Project if you want to have a separate Firebase configuration for development and production applications.

6. Download the `google-services.json` file and save it to your computer. You will need it later to configure the Android application build.

    Firebase Download Google Services JSON

7. Click on **Next** button and then on **Continue to console** button to finish the Firebase Project creation.

8. In the Firebase Console, go to **Project Settings** → **Cloud Messaging** tab.

    Firebase Cloud Messaging Settings

9. Ensure that **Firebase Cloud Messaging API (V1)** is **enabled**.

    If it is not enabled, click on the 3 dots menu and enable it in Google Cloud Console.

    Firebase Cloud Messaging API Enable

10. Go to **Project Settings** → **Service accounts** tab and click on the **Generate new private key** button to download the service account key.

    Firebase Service Account Key

    Save the downloaded JSON file to your computer, you will need it later to configure the Android application build in Better Messages settings.

## Development & Production Builds

To generate Better Messages Android App Builds, it is required to configure for each type of build separately by uploading the `google-services.json` and `Firebase Admin SDK Private Key` files, which was downloaded from Firebase to **WP Admin** -> **Better Messages** -> **Mobile App** -> **Settings** -> **Android** page.

    Android Settings

1. Set application name
2. Upload `google-services.json` file to Firebase SDK Configuration file field and select appropriate app id after upload.
3. Upload `Firebase Admin SDK Private Key` file to Firebase Admin SDK File field.

After thats done it should look similar to this:

    Android Settings Completed

The image above shows the configuration for the development build, the configuration for the production build configuration is the same.

To build the production build, you also need an Android Keystore file, which is used to sign the application before publishing it to the Google Play Market.

You can generate the Android Keystore file using Android Studio at the same page or upload the existing one if you already have it.

    Android Keystore

After you have generated or uploaded the Android Keystore file, you will be able to build the production build of the Android application.

## Development Build

Development build is used for testing purposes and can be installed only to Android devices or Emulators.

You can install the development build to your Android device or Emulator by scanning QR code with camera and downloading the APK file or by downloading the APK file directly by url.

## Production Build

Production build is only possible to upload to Google Play Store with AAB file, for that you need to have Google Developer Account, which is required to publish the application to the Google Play Market.

You can register for a Google Developer Account [here](https://play.google.com/console/about/).

---

## Native iOS Messenger App for WordPress

:::info WebSocket Version Guide

<>This functionality available only with WebSocket Version

:::
:::info Compatibility

<>This { (props.type ? props.type : 'guide') } compatible with Better Messages {props.version} or higher

:::

iOS application feature allows you to generate native iOS messenger application for your website, which allows you to send push and call notifications and can be published to the Apple App Store.

Example of such application here:
https://apps.apple.com/us/app/wordplus-messenger/id1598803821?platform=iphone

## Requirements

- ### Apple Developer Program Account
   To be able to generate and publish iOS application, you need to have paid (99 USD /year) [Apple Developer Program Account](https://developer.apple.com/support/compare-memberships/).

- ### iOS Device
   To be able to build an iOS application, you need to have at least one active iOS device added to [Apple Developer Devices List](https://developer.apple.com/account/resources/devices/list).

## Connection to Apple Developer Account

After you have Apple Developer Program Account, to be able to generate Better Messages iOS app, you need to connect Better Messages to your App Store Connect API.

1. Go to [App Store Connect](https://appstoreconnect.apple.com/) and login with your Apple Developer Account.
2. Go to [**App Store Connect API** section](https://appstoreconnect.apple.com/access/integrations/api).
3. Under the **Team Keys** section, click on **+** button to create new key.

   App Store Connect API Add New Key
4. Generate API Key with the **Admin access**, like at the screenshot:

   App Store Connect Generate API Key
5. After you generate the key, you will see the **Key ID**, **Issuer ID** and **Download API Key** button. Click on the **Download API Key** button to download the key.
   It is only possible to download the key once, so make sure to store it in a safe place.

   App Store Connect Generated API Key
   You will need these values to connect Better Messages to your App Store Connect API.
6. Navigate to your website WP Admin → Better Messages → Mobile App → Settings → iOS and fill the **Key ID**, **Issuer ID** and **API Key** fields with the values you got from the App Store Connect API and press **Connect** button.

    Better Messages iOS Connect
7. If everything is done correctly, you will see the green message bar confirming the connection is successful and you will be able to continue with the iOS app configuration.

    bm-ios-connected.png

## Configure Apple Development Team ID

1. Go to [Apple Developer Account](https://developer.apple.com/account) and login with your Apple Developer Account.
2. Scroll down to the **Membership details** section and copy the **Team ID**.

   app-store-team-id.png

3. Navigate to your website WP Admin → Better Messages → Mobile App → Settings → iOS and fill the **Team ID** under a general section.

   bm-ios-team-id.png

## Development & Production Builds

To generate Better Messages iOS App Build, its required to configure for each type of build separately:
   - Application Name
   - Application Identifier
   - Notification Service Identifier

ios-development.png

### Application Name

This name will be used as primary mobile application name. Application name is limited to 30 characters, but only 12 characters will show under the icon at the mobile device applications list.

### Application Identifier

Application Identifier is unique identifier for your application.

It must be unique and match the application identifier in the Apple Developer Account.

It is recommended to use the reverse domain name notation e.g.:

Development build Application Identifier - **com.yoursitename.messenger.dev**

#### Registering Application Identifiers

1. Go to [Apple Developer Account](https://developer.apple.com/account/resources/identifiers/list) and login with your Apple Developer Account.
2. Go to **Identifiers** section and click on **+** button to create a new identifier.

   app-store-create-identifier-1.png
3. Select **App IDs** and press **Continue**.

   app-store-create-identifier-2.png
4. Select **App** when asked for the type of identifier and press **Continue**.

   app-store-create-identifier-3.png

5. Fill the **Description** field with your application name and fill the **Bundle ID** field with your application identifier (e.g. com.yoursitename.messenger).

   app-store-create-identifier-4.png
6. The following capabilities must be enabled:
   - **Associated Domains**
   - **Push Notifications**
   - **Communication Notifications**
   - **Time Sensitive Notifications**
7. Press **Register** button to create the identifier.
8. After the identifier is created, you will need to go to Better Messages settings and press refresh list button to get the new identifier list, then select the identifier which is applicable for your development build.

   app-store-create-identifier-5.png

### Notification Service Identifier

Please repeat all the steps for [Application Identifier](#application-identifier) but add the suffix to the Bundle ID with **.notifications**.

For example, if your main application bundle ID is **com.yoursitename.messenger.dev**, then the Notification Service Identifier should be **com.yoursitename.messenger.dev.notifications**.

The notification service does not require any capacities to be enabled.

## Application Builds

After you have configured the iOS application settings, you can go to Builds tab and create the iOS application build.

app-builds.png

## Development Build

Development build is used for testing purposes and can be installed only to iOS devices, which were added to your Apple Developer Account Devices List.

You can install the development build to your iOS device by scanning QR code with camera.

## Production Build

Production build is only possible to upload to App Store Test Flight.

There you will be able to test by users which are added to your Test Flight testers list or submit the application to the App Store for review.

---

## Better Messages Pricing — Free, WebSocket, and Self-Hosted Plans

getProductSchema,
  getFaqSchema,
} from '@site/src/helpers/seo-schema';



export const pricingFaqs = [
  {
    question: "Is there a free version of Better Messages?",
    answer: "Yes. The free version is published on WordPress.org under the slug bp-better-messages. It uses AJAX polling for real-time delivery and includes core messaging, chat rooms, file sharing, group conversations, AI chat bots (with your own provider API key), and 34+ integrations. No license required, unlimited sites.",
  },
  {
    question: "Why is the WebSocket version paid?",
    answer: "The WebSocket version includes hosted relay infrastructure (servers in multiple regions, TURN relays for voice and video calls, monitoring, scaling) plus access to Better Messages Cloud AI services (moderation, translation, transcription). The subscription pays for that infrastructure and ongoing development.",
  },
  {
    question: "Are Better Messages prices per-site?",
    answer: "Yes. Every paid plan is sold as a single-site license. If you have multiple sites, you need multiple licenses. Contact support if you need a larger custom plan.",
  },
  {
    question: "Do you provide staging licenses for Better Messages?",
    answer: "Yes — staging licenses are available on annual plans only. They let you activate the same WebSocket license on a separate staging or development site alongside your production site, so you can test plugin updates and configuration changes without buying a second license. Monthly billing does not include a staging license.",
  },
  {
    question: "Can I switch between monthly and annual billing?",
    answer: "Yes. Freemius lets you switch billing cycles from your account dashboard at any time.",
  },
  {
    question: "What happens if I cancel the WebSocket subscription?",
    answer: "Your license expires and the plugin reverts to AJAX behavior. Messages, threads, history, files, integration data, and AI chat bots stay intact, but WebSocket push, voice and video calls, Better Messages Cloud AI, the mobile apps, and the other WebSocket-only features stop working. You can reactivate at any time.",
  },
  {
    question: "Is there a refund policy?",
    answer: "Yes — a 7-day money-back guarantee on first purchase. Refund requests are processed directly through the Freemius account dashboard.",
  },
  {
    question: "Does Better Messages pricing scale with user count?",
    answer: "No. WebSocket version pricing is flat per site, regardless of how many users, messages, or concurrent connections you have. A site with 100,000 active users pays the same as one with 100.",
  },
  {
    question: "How does Better Messages compare to other realtime chat-as-a-service platforms?",
    answer: "Most chat-as-a-service platforms (Pusher, Ably, PubNub, Stream Chat, Sendbird, GetStream) charge per concurrent connection, per monthly active user, or per delivered message — bills scale linearly or worse with growth. Better Messages WebSocket is flat-rate per site: $14.99/mo monthly or $11.99/mo billed annually. 100 concurrent users or 100,000 — same bill, same features. The plan also includes voice and video call infrastructure, group calls, Better Messages Cloud AI (moderation, translation, transcription), and web/mobile push, which those services typically bill separately.",
  },
  {
    question: "Will the WebSocket version reduce my WordPress server load?",
    answer: "Yes — significantly. The free AJAX version uses polling: every active user fires a request to your WordPress REST API every few seconds. The WebSocket version routes all messaging traffic to the Better Messages cloud relay instead — your WordPress server only handles initial page loads and the database write when a message is sent. For sites on shared hosting, entry-level VPS, or with hundreds of concurrent users, the load reduction often pays back the subscription cost in hosting savings alone.",
  },
  {
    question: "Do I need the WebSocket Self-Hosted plan?",
    answer: "Only if you have strict data-sovereignty requirements: GDPR Article 9 (special-category personal data), HIPAA-adjacent workloads, internal corporate policy forbidding third-party relays, or jurisdictional requirements about which servers user data may pass through. The standard cloud WebSocket relay is blind to message content and is GDPR-compatible by default. Self-hosted also requires you to provide your own dedicated VPS or cloud instance, billed separately by your hosting provider.",
  },
  {
    question: "What payment methods does Better Messages accept?",
    answer: "Credit and debit cards plus PayPal through the Freemius checkout. Wire transfer and invoicing are available for annual and self-hosted plans on request.",
  },
  {
    question: "Where do I buy Better Messages WebSocket?",
    answer: "Three options, all using the same Freemius checkout: directly on the pricing page at better-messages.com/docs/pricing/, from the better-messages.com homepage via the red WebSocket button, or from inside the WordPress admin at Better Messages → Account → Upgrade after installing the free plugin. Same prices, same 7-day money-back guarantee.",
  },
  {
    question: "Is there a lifetime license for Better Messages?",
    answer: "No. The WebSocket version isn't just code — it includes the cloud WebSocket relay, TURN servers for voice and video calls, push-notification gateways, and Better Messages Cloud AI services. Every active license keeps those servers running. Better Messages has also been actively developed since 2017, and WordPress, browsers, and the 34+ integrated plugins change constantly. A one-time payment cannot fund ongoing hosting infrastructure, development, and support indefinitely. The free AJAX version on WordPress.org has no expiration if recurring billing is a friction point.",
  },
];



# Better Messages Pricing

Better Messages is a **free WordPress plugin** — install it from [WordPress.org](https://wordpress.org/plugins/bp-better-messages/) and the AJAX version works right away. Real-time messaging via polling, chat rooms, file sharing, group chats, and 34+ integrations are all included at no cost, on any WordPress hosting.

To **upgrade to the WebSocket version** — instant push delivery, **dramatically reduced WordPress server load**, voice and video calls, Better Messages Cloud AI services (moderation, translation, transcription), end-to-end encryption, and the native iOS / Android mobile apps — buy a license. The WebSocket version is delivered as a separate plugin download from your Freemius account, and once activated it replaces the free version inside WordPress automatically. All your messages, threads, files, settings, and integrations stay intact through the swap.

## Pricing summary

| Plan | Monthly price | Annual price | Annual total | Sites |
|---|---|---|---|---|
| **AJAX (Free)** | $0 | $0 | $0 | unlimited |
| **WebSocket** | $14.99 / month | $11.99 / month | $143.88 / year | 1 site per license |
| **WebSocket Self-Hosted** | — | $25.00 / month | $299.99 / year | 1 site per license |

All paid plans are **per-site licenses**. The annual option is roughly 20 % cheaper than monthly. Self-hosted billing is annual only.



Payments are processed through **Freemius**, the same checkout used by thousands of premium WordPress plugins. Credit and debit cards plus PayPal are accepted. Each paid license includes a **7-day money-back guarantee** — see the [refund policy](/docs/websocket/refund-policy/) for full terms.

## Which plan should I pick?

- **AJAX (Free)** — start here to evaluate the plugin on a real site. Messaging, chat rooms, file sharing, group chats, AI chat bots, and 34+ integrations all work out of the box. Upgrade to the WebSocket version when you're ready to add instant delivery, **dramatically reduced WordPress server load**, voice and video calls, Better Messages Cloud AI services, end-to-end encryption, and the native mobile apps.
- **WebSocket (monthly)** — same plugin, but messages arrive instantly. Pick this if you want to try the paid version risk-free for a month, or if your site's revenue is not yet ready to commit a year in advance.
- **WebSocket (annual)** — recommended for production sites. Same features as monthly, but ~20 % cheaper, and you don't have to think about renewals each month.
- **WebSocket Self-Hosted** — only relevant if you must run the WebSocket relay on your own infrastructure (GDPR Article 9, HIPAA-adjacent, jurisdictional sovereignty, internal corporate policy). Includes everything in the WebSocket plan plus the self-hosted relay build and a one-time installation service. **Note**: you also need to provide a dedicated cloud instance or VPS to host the relay on — that infrastructure is billed by your hosting provider separately and is not part of the $25/mo plan. Most sites do **not** need this.

## What's included in each plan

### AJAX (Free) — $0 {#ajax-free}

Available on [WordPress.org](https://wordpress.org/plugins/bp-better-messages/). Uses AJAX polling for message delivery — no separate server infrastructure required. Runs on any WordPress hosting, including shared hosts.

- [Realtime chatting](/docs/features/realtime-messaging/) via AJAX polling
- [Modern, mobile-friendly design](/docs/features/modern-design/)
- [Chat rooms](/docs/features/chat-rooms/) — public or members-only
- [File sharing](/docs/features/file-sharing/) with EXIF stripping and proxy-protected URLs
- [Reworked email notifications](/docs/features/email-notifications/)
- [Emoji selector](/docs/features/emoji-selector/)
- [Stickers and GIFs](/docs/features/stickers/) (GIPHY / KLIPY)
- [Sound notifications](/docs/features/sound-notifications/)
- [On-site notifications](/docs/features/site-notifications/)
- [Embedded link previews](/docs/features/oembed-support/)
- [Multi-participant conversations](/docs/features/group-conversations/)
- [Group messages](/docs/features/group-messages/)
- [Favorited messages](/docs/features/favorite-messages/)
- [Conversation subjects](/docs/features/subjects/)
- [Threads muting](/docs/features/conversations-muting/)
- Message formatting with [markdown syntax](/docs/features/markdown-support/) (bold, italic, lists, code, blockquotes)
- [Mass messaging](/docs/features/mass-messaging/) tools for admins
- [Edit, delete, and reply to messages](/docs/features/reply-edit-forward/)
- [Message reactions](/docs/features/message-reactions/)
- [AI chat bots](/docs/features/ai-chat-bots/) — OpenAI, Anthropic Claude, and Google Gemini (via the included AI add-on, using your own provider API key)
- [White-label](/docs/features/white-label/) — no Better Messages branding shown to end users
- 34+ native [integrations](/docs/category/integrations/) (BuddyPress, BuddyBoss, PeepSo, WooCommerce, Dokan, LearnDash, and many more)
- Voice messages — via the separate [Voice Messages](/docs/addons/voice-messages/) add-on (works on both versions)
- Email, forum, and help-center support

### WebSocket — $14.99 / month, or $11.99 / month annually {#websocket}

Everything in the AJAX plan, plus an instant WebSocket relay (hosted by us as part of the license) and the WebSocket-only features below.

- **[Instant messages delivery](/docs/websocket/instant-delivery/)** — sub-100 ms WebSocket push, not polling
- **[Dramatically reduced WordPress server load](/docs/websocket/load-optimization/)** — AJAX polling fires a request from every active user to your WordPress REST API every few seconds. WebSocket offloads that traffic entirely to the Better Messages cloud relay — your WP server only handles initial page loads and database writes when messages are sent. Often the single biggest practical benefit for sites on shared hosting, entry-level VPS, or with many concurrent chatters
- **[Unlimited connections](/docs/websocket/no-limits/)** — no per-user or per-message caps
- **[HD video calls](/docs/websocket/video-calls/)** — one-on-one inside any thread
- **[HD audio calls](/docs/websocket/audio-calls/)** — one-on-one inside any thread
- **[HD group video chats](/docs/websocket/group-video-chat/)** — multi-participant
- **[HD group audio chats](/docs/websocket/group-audio-chat/)** — multi-participant
- **[Screen sharing](/docs/websocket/screen-sharing/)** during calls
- **[Web push notifications](/docs/websocket/web-push/)** — browser push for desktop and mobile web
- **[End-to-end encryption](/docs/websocket/e2e-encryption/)** — opt-in per thread, keys never leave the participant browsers
- **[Better Messages Cloud AI](/docs/websocket/cloud-ai/)** — content moderation, message translation, voice transcription (runs on our infrastructure, no third-party API key needed)
- **[Presence indicator](/docs/websocket/presence-indicator/)** — see who is online
- **Additional on-site notifications**
- **User statuses** (online, away, busy, custom)
- **[Typing indicator](/docs/websocket/typing-indicator/)**
- **[Message status](/docs/websocket/message-status/)** (sent, delivered, read)
- **[Mini chats](/docs/websocket/mini-chats/)** — popup chat from profiles and member directories
- **[Mini threads](/docs/websocket/mini-threads/)** — inline mini-threads inside posts
- **[iOS mobile app](/docs/mobile-app/ios-application/)** (alpha) — App Store TestFlight build
- **[Android mobile app](/docs/mobile-app/android-application/)** (alpha) — APK / Play Store build
- **[Your data is yours](/docs/websocket/your-data/)** — you can export and migrate at any time
- **Seamless plan change** — upgrade or switch billing without re-installing
- **[Priority support](/docs/websocket/priority-support/)**

Email, forum, and help-center support (same channels as the free plan, prioritized).

### WebSocket Self-Hosted — $25 / month billed annually {#self-hosted}

Everything in the WebSocket plan, plus the relay runs on your own infrastructure.

*Note: the self-hosted plan covers the relay build, the installation service, and the license — it does not include the server the relay runs on. You need to provide your own dedicated cloud instance or VPS (DigitalOcean, Hetzner, Linode, AWS EC2, Google Cloud, your private datacenter, etc.), billed by your hosting provider separately.*

- **All WebSocket plan features**
- **Self-hosted relay build** — the relay shipped as a deployable bundle
- **Installation service** — we set up the relay on the cloud instance or VPS you provide (one-time, included)
- **Data transmitted through your servers only** — no third-party relay, useful for GDPR Article 9 data, HIPAA-adjacent workloads, or jurisdictional rules about which servers may transit user data
- **Dedicated cloud instance / VPS required** — you supply the server, billed separately by your hosting provider (DigitalOcean, Hetzner, Linode, AWS, etc.)
- **Priority email, forum, and help-center support**

## Full feature comparison

| Feature | AJAX (Free) | WebSocket | WebSocket Self-Hosted |
|---|---|---|---|
| Price | $0 | $14.99 / mo, or $11.99 / mo annual | $25 / mo annual |
| Single-site license | unlimited installs | 1 | 1 |
| Relay infrastructure | not needed (AJAX uses your WP hosting) | **included** (we host the relay) | **you provide** a dedicated VPS / cloud instance, billed separately |
| [Realtime chatting](/docs/features/realtime-messaging/) | yes (AJAX polling) | yes (instant push) | yes (instant push) |
| [Chat rooms](/docs/features/chat-rooms/) | yes | yes | yes |
| [File sharing](/docs/features/file-sharing/) | yes | yes | yes |
| [Voice messages add-on](/docs/addons/voice-messages/) | works | works | works |
| [Email notifications](/docs/features/email-notifications/) | yes | yes | yes |
| [Emoji](/docs/features/emoji-selector/), [stickers](/docs/features/stickers/), GIFs | yes | yes | yes |
| [Sound](/docs/features/sound-notifications/) + [on-site notifications](/docs/features/site-notifications/) | yes | yes | yes |
| [Group messages](/docs/features/group-messages/) and [conversations](/docs/features/group-conversations/) | yes | yes | yes |
| [Edit, delete, reply](/docs/features/reply-edit-forward/), [react](/docs/features/message-reactions/) | yes | yes | yes |
| [Markdown message formatting](/docs/features/markdown-support/) | yes | yes | yes |
| [Mass messaging](/docs/features/mass-messaging/) | yes | yes | yes |
| 34+ [integrations](/docs/category/integrations/) | yes | yes | yes |
| [AI chat bots](/docs/features/ai-chat-bots/) (OpenAI / Anthropic / Gemini, your API key) | yes | yes | yes |
| [White-label](/docs/features/white-label/) | yes | yes | yes |
| [WordPress server load from messaging](/docs/websocket/load-optimization/) | scales with active users | minimal (relay handles it) | minimal (your relay handles it) |
| [Instant WebSocket delivery](/docs/websocket/instant-delivery/) | — | yes | yes |
| [Unlimited connections](/docs/websocket/no-limits/) | — | yes | yes |
| HD 1-on-1 [voice](/docs/websocket/audio-calls/) + [video calls](/docs/websocket/video-calls/) | — | yes | yes |
| HD group [voice](/docs/websocket/group-audio-chat/) + [video calls](/docs/websocket/group-video-chat/) | — | yes | yes |
| [Screen sharing](/docs/websocket/screen-sharing/) | — | yes | yes |
| [Web push notifications](/docs/websocket/web-push/) | — | yes | yes |
| [End-to-end encryption](/docs/websocket/e2e-encryption/) | — | yes | yes |
| [Better Messages Cloud AI](/docs/websocket/cloud-ai/) (moderation, translation, transcription) | — | yes | yes |
| [Mini chat popups](/docs/websocket/mini-chats/) | — | yes | yes |
| [Typing](/docs/websocket/typing-indicator/) + [presence](/docs/websocket/presence-indicator/) + [read status](/docs/websocket/message-status/) | — | yes | yes |
| [iOS](/docs/mobile-app/ios-application/) / [Android](/docs/mobile-app/android-application/) mobile app | — | yes (alpha) | yes (alpha) |
| [Priority support](/docs/websocket/priority-support/) | — | yes | yes |
| Self-hosted WebSocket relay | — | — | yes |
| Installation service | — | — | yes (included) |

## Add-ons

- **[Voice Messages](/docs/addons/voice-messages/)** — record and send audio messages in conversations. Works on both the AJAX (free) version and the WebSocket version.

## Frequently asked questions

### Is there a free version?

Yes. The free version is published on [WordPress.org](https://wordpress.org/plugins/bp-better-messages/) under the slug `bp-better-messages`. It uses AJAX polling for realtime delivery and includes all the core messaging, chat-room, file-sharing, and integration features. No license required.

### Why is the WebSocket version paid?

The WebSocket version includes a hosted relay infrastructure (servers in multiple regions, TURN relays for calls, monitoring, scaling) plus access to the Better Messages Cloud AI services (moderation, translation, transcription). The subscription pays for that infrastructure and ongoing development.

### Are prices per-site?

Yes. Every paid plan is sold as a **single-site license**. If you have multiple sites, you need multiple licenses. Talk to support if you need a larger custom plan.

### Do you provide staging licenses?

Yes — staging licenses are available on **annual plans only**. They let you activate the same WebSocket license on a separate staging or development site alongside your production site, so you can test plugin updates and configuration changes without buying a second license. Monthly billing does not include a staging license. Contact support after your annual purchase to enable staging activation.

### Can I switch between monthly and annual?

Yes. Freemius lets you switch billing cycles from your account dashboard.

### What happens if I cancel the WebSocket subscription?

Your license expires. The plugin reverts to AJAX behavior — messages, threads, history, files, integration data, and AI chat bots stay intact, but WebSocket push, calls, Better Messages Cloud AI, the mobile apps, and the other WebSocket-only features stop working. You can reactivate at any time.

### Is there a refund policy?

Yes — **7-day money-back guarantee** on first purchase. Refund requests are processed directly through the Freemius account dashboard. See the [full refund policy](/docs/websocket/refund-policy/) for terms and eligibility details.

### Does pricing scale with my user count?

No. WebSocket version pricing is **flat per site**, regardless of how many users, messages, or concurrent connections you have. A site with 100,000 active users pays the same as one with 100. See [no limits on connections or volume](/docs/websocket/no-limits/).

### How does this compare to other realtime / chat-as-a-service platforms?

The pricing model is fundamentally different. Most realtime / chat-as-a-service platforms — the SaaS providers that sell WebSocket pub/sub infrastructure as a building block — charge **per concurrent connection**, **per monthly active user (MAU)**, or **per delivered message**, sometimes a combination of all three. Entry tiers start cheap, but the bill scales linearly (or worse) as your community grows. A WordPress site with a few thousand concurrent chatters can easily cost **hundreds or thousands of dollars per month** on those services, and even modest active communities routinely outgrow free tiers within weeks.

Better Messages WebSocket is **flat-rate per site, regardless of size**: $14.99/mo monthly, $11.99/mo billed annually. 100 concurrent users or 100,000 — same bill, same features, same performance. We can do this because the relay is purpose-built for messaging on WordPress (not a general-purpose pub/sub channel rented by anyone for anything), and we don't bill per delivered event.

And the comparison isn't apples-to-apples — those services usually sell *only* the WebSocket relay layer. The Better Messages WebSocket plan includes a lot more on top of WebSocket messaging:

- **Voice and video call infrastructure** — relay servers for peer-to-peer connections, fallback for users behind restrictive networks, and call signaling. Standalone realtime call services typically add a separate per-minute or per-participant bill.
- **Group voice and video calls** — multi-participant calls inside any conversation, with no per-minute charge regardless of session length or attendee count.
- **Better Messages Cloud AI** — content moderation, real-time message translation, and voice transcription, all running on our infrastructure with no separate API account, per-token billing, or third-party rate limits.
- **Web push and mobile-app push delivery** — included, with no separate push-as-a-service subscription.

Compared on like-for-like infrastructure (messaging + calls + AI + push), the savings widen significantly. If your community has growth ambitions, flat-rate pricing avoids the unpleasant surprise where success suddenly becomes expensive. See [no limits on connections or volume](/docs/websocket/no-limits/) for the full breakdown.

### Will the WebSocket version reduce my WordPress server load?

Yes — significantly, and this is often the biggest practical reason production sites upgrade. The AJAX (free) version uses polling: every active user fires a request to your WordPress REST API every few seconds to check for new messages. With many concurrent chatters this adds up to meaningful CPU and database load on your WP server, and grows linearly with active user count. The WebSocket version routes all messaging traffic to the Better Messages cloud relay instead — your WordPress server only handles initial page loads and the database write when a message is sent. For sites on shared hosting, entry-level VPS, or with hundreds of concurrent users, the load reduction is dramatic and often pays back the subscription cost in hosting savings alone.

### Do I need the self-hosted plan?

Only if you have strict data-sovereignty rules — GDPR Article 9 (special-category personal data), HIPAA-adjacent workflows, internal corporate policy forbidding third-party relays, or jurisdictional requirements about which servers user data may pass through. For the vast majority of community, marketplace, LMS, and membership sites, the standard WebSocket plan is the right pick. The cloud relay is **blind to message content** and is GDPR-compatible by default.

Also keep in mind that the self-hosted plan **does not include hosting infrastructure**. You need a dedicated cloud instance or VPS (DigitalOcean, Hetzner, Linode, AWS, etc.) to run the relay on, billed separately by your hosting provider. Most teams underestimate this when comparing the $25/mo self-hosted price against the standard $11.99/mo WebSocket plan — by the time you add the hosting cost and the operational overhead of running it yourself, the standard plan is usually meaningfully cheaper unless you have a hard requirement that forces self-hosting.

### What payment methods are accepted?

Credit and debit cards and PayPal through the Freemius checkout. Wire transfer and invoicing are available for annual and self-hosted plans on request.

### Where do I buy?

You have three options, all using the same Freemius checkout:

1. **Right here on this page** — click the  { e.preventDefault(); buyWebsocket({ source: 'pricing_page_inline' }); }}>Get WebSocket Version button above. The checkout opens in a secure overlay and you stay on this page through the purchase. Toggle between monthly and annual inside the modal.
2. **From the better-messages.com homepage** — the same red button on the [homepage](/) triggers the same checkout.
3. **From the WordPress admin** — after installing the free plugin, open **Better Messages → Account → Upgrade**.

All three routes land you on the same Freemius checkout, with the same prices and the same 7-day money-back guarantee.

### Is there a lifetime license?

No, for two reasons:

**1. Hosted infrastructure costs money every day.** The WebSocket version isn't just code — it includes the cloud WebSocket relay, TURN servers for voice and video calls, push-notification gateways, and Better Messages Cloud AI services (moderation, translation, transcription). Every active license keeps those servers running.

**2. Continuous updates and support cost money every day.** Better Messages has been actively developed since 2017. WordPress evolves, browsers change, the 34+ integrated plugins ship new versions, security patches go out regularly, new features land in every release, and customer support questions need real human answers. A one-time payment can't fund ongoing development and support indefinitely.

A lifetime model can work for finished products that ship once and walk away. It can't work for a plugin that is hosted, deeply integrated with the rest of the WordPress ecosystem, actively maintained, and supported. Plenty of plugin shops have sold lifetime deals, run out of runway, and either stopped updating, stopped supporting, or shut down — leaving "lifetime" customers stranded. We'd rather charge a fair subscription and stay around than over-promise and break it later.

If recurring billing is the friction point, the **free AJAX version** on WordPress.org has no expiration and no license — it works forever, no strings attached.

## See also

- [What is Better Messages?](/docs/getting-started/about/) — features overview and how the two versions differ
- [Installation guide](/docs/getting-started/installation/) — how to install the plugin
- [No limits on connections or volume](/docs/websocket/no-limits/) — why the WebSocket plan stays flat-priced regardless of site size
- [Integrations directory](/docs/category/integrations/) — the 34+ plugins Better Messages plugs into
- [End-user license agreement](/docs/websocket/end-user-license/) — full license terms

---

## better_messages Shortcode

# better_messages

:::info

**[How to add shortcodes?](https://www.wpbeginner.com/wp-tutorials/how-to-add-a-shortcode-in-wordpress/)**

:::

The primary shortcode for **embedding the Better Messages inbox** on any WordPress page. For logged-in users it shows the full messenger (conversation list + active conversation). For non-logged-in users it shows a login form, prompting them to sign in to access their messages.

## When to use it

| Page type | Why embed `[better_messages]` |
|---|---|
| **Dedicated "Messages" page** | The primary use — a top-level Messages link in your site nav |
| Member dashboard | Show inbox alongside other account features |
| Custom-built profile pages | Embed inbox inline with profile actions |
| Theme-builder pages (Elementor / Bricks) | Drop the shortcode into a flexible page layout |

## Usage

```
[better_messages]
```

No attributes — this shortcode is intentionally simple. To configure messenger behavior, use the global settings at **WP Admin → Better Messages → Settings**.

## Default behavior

| User state | What renders |
|---|---|
| Logged in | Full messenger UI — conversation list + selected thread |
| Not logged in (guest disabled) | WordPress login form prompting sign-in |
| Not logged in (guest enabled) | Guest entry prompt or auto-join, per global guest settings |

## Frequently asked questions

### Where do I put this shortcode?
Most sites use the plugin's **Settings → General → Messages Location** option to point the messenger to a specific page. If you'd rather embed manually, create a page, drop in `[better_messages]`, and add a menu link.

### Can I have multiple "messages" pages?
Yes — the shortcode can appear on multiple pages. Each renders the same inbox. Useful if you have role-specific dashboards (e.g., one for buyers, one for sellers).

### How does this differ from the other shortcodes?
| Shortcode | Purpose |
|---|---|
| `[better_messages]` | Full inbox layout (this shortcode) |
| `[better_messages_single_conversation]` | Embed one specific thread |
| `[better_messages_user_conversation]` | Auto-create/open a conversation with a specific user |
| `[better_messages_my_messages_url]` | Just the URL (for menu items) |
| `[better_messages_live_chat_button]` | A button that starts a chat |

### Does this work with page builders?
Yes — Elementor, Beaver Builder, Bricks, Divi, and similar all support the standard WordPress shortcode. Drop a "Shortcode" widget on the page and enter `[better_messages]`.

### Will the messenger respect my theme's styling?
Yes — the messenger inherits your theme's typography and respects the configured accent color. For deeper styling, use the [Easy Customization](/docs/features/easy-customization/) settings or add custom CSS.

## See also

- [better_messages_my_messages_url](/docs/shortcodes/better_messages_my_messages_url/) — URL-only variant for menus
- [better_messages_single_conversation](/docs/shortcodes/better_messages_single_conversation/) — embed one specific thread
- [better_messages_user_conversation](/docs/shortcodes/better_messages_user_conversation/) — auto-create a thread with a user
- [better_messages_live_chat_button](/docs/shortcodes/better_messages_live_chat_button/) — chat-starting button
- [Easy customization](/docs/features/easy-customization/) — color and layout options

---

## better_messages_audio_call_button Shortcode

# better_messages_audio_call_button

:::info

**[How to add shortcodes?](https://www.wpbeginner.com/wp-tutorials/how-to-add-a-shortcode-in-wordpress/)**

:::
:::info WebSocket Version Guide

<>This functionality available only with WebSocket Version

:::

Embed a **voice call button** anywhere on your WordPress site that starts a 1-on-1 audio call with a specified user. Works on posts, pages, custom profile templates, page builders, and any theme location that accepts shortcodes.

## When to use it

| Scenario | Where you'd place the shortcode |
|---|---|
| Coaching / consulting page | On the coach's profile so clients can voice-call directly |
| Marketplace vendor profile | Quick voice contact button for buyer questions |
| Telemedicine practitioner profile | Audio-first consultation entry point |
| Custom member directory cards | Inline "Call" CTA per member |
| Author bio boxes | Below blog posts for direct author voice contact |

## Attributes

    
    
        Attribute
        What it controls
        Default
    
    
    
    
        text
        Button label text
        "Audio Call"
    
    
        user_id
        The recipient — user who will receive the call
        Post author of current WordPress post/page
    
    
        url_only
        Set to 1 to return only the URL (no button HTML)
        0
    
    
        class
        Additional CSS classes for styling
        None
    
    

## Examples

### Basic — call the post author

```
[better_messages_audio_call_button]
```

Renders a default button. Clicking starts an audio call with the current post's author.

### Custom label and explicit recipient

```
[better_messages_audio_call_button text="Call Support" user_id="42"]
```

Custom-labeled button that connects to user ID 42 (e.g., your support rep) regardless of post context.

### URL only for custom styling

```html

  Call Now

```

Returns just the URL — wrap in your own anchor with custom styling.

### Themed class

```
[better_messages_audio_call_button text="Audio Call" class="btn-primary btn-lg"]
```

Adds extra CSS classes for design integration with your theme's button styles.

## Frequently asked questions

### Does the button work for guests?
Guests see the button but clicking redirects to login (or to guest-chat flow if enabled). Active calls require a session.

### What happens if the recipient is offline?
The recipient sees a missed-call system message in the conversation when they next open the thread. No queued ringing for offline users.

### Will this work on the free version?
No — voice calls require the WebSocket version. The shortcode renders, but clicking shows an upgrade notice.

### Can I gate which roles see the button?
Use a wrapping conditional in your theme, OR use **Settings → Calls** per-role restrictions to gate who can place calls globally.

## See also

- [Video call button shortcode](/docs/shortcodes/better_messages_video_call_button/) — same pattern for video
- [Mini chat button shortcode](/docs/shortcodes/better_messages_mini_chat_button/) — open mini chat
- [Audio calls feature](/docs/websocket/audio-calls/) — full documentation
- [Group audio chat](/docs/websocket/group-audio-chat/) — multi-party voice (up to 50)

---

## better_messages_live_chat_button Shortcode

# better_messages_live_chat_button

:::info

**[How to add shortcodes?](https://www.wpbeginner.com/wp-tutorials/how-to-add-a-shortcode-in-wordpress/)**

:::

**Universal Live Chat Button.** Drop it into any post, page, custom post type, page builder, or theme template — the shortcode resolves who the chat targets, what label it shows, and which thread to open *automatically*, based on the current page.

The same shortcode works for: post-author chat, marketplace vendor chat (user stored in postmeta), site-wide support inbox, AI bot launcher. No PHP required — configure it visually in the [Shortcode Builder](#shortcode-builder) or hand-write the attributes with magic tokens like `post_author` and `{author_name}`.

This shortcode supersedes [`better_messages_pm_button`](/docs/shortcodes/better_messages_pm_button/) and [`better_messages_mini_chat_button`](/docs/shortcodes/better_messages_mini_chat_button/).

Live Chat Button — variations on a vendor page

## Quick start

The simplest use — drop it into any post body, and it targets that post's author:

```
[better_messages_live_chat_button]
```

The recommended version uses magic tokens so a single shortcode works for every post:

```
[better_messages_live_chat_button user_id="post_author" unique_tag="auto" object_id="auto" text="auto" class="bm-lc-button-styled"]
```

What this resolves to, automatically, on each post:

- `user_id="post_author"` → chats with the post's author
- `unique_tag="auto"` → one thread per post (e.g. `vendor-42`)
- `object_id="auto"` → attaches the post as a [thread information banner](#thread-information-banner)
- `text="auto"` → label becomes `Chat with {author_name}` (resolved per post)
- `class="bm-lc-button-styled"` → branded baseline styling out of the box

Paste it into a custom post type single template, a Gutenberg shortcode block, or an Elementor shortcode widget — same result.

## Shortcode Builder

The easiest way to configure the button. Open **WP Admin → Better Messages → Shortcodes** and use the visual builder.

Shortcode Builder — visual configurator with live preview

The builder lets you:

- **Pick a target post** to anchor the configuration. Author, custom field, banner image, and the test button all resolve against this post. The selected post is never written into the generated shortcode — the result works on every post of the same shape.
- **Choose how the target user is resolved**:
  - Author of the current post (most common)
  - User id stored in a postmeta field on the post (vendor / agent / owner pattern)
  - A fixed user (single site-wide support inbox)
- **Tune visual styling** (background, text color, font size, padding, margin, border radius) without writing CSS
- **Pick an icon** from the preset library or paste a custom SVG — embedded inline so no extra stylesheet is needed on the frontend
- **Preview live** in an iframe that loads inside the active theme (so the button looks *exactly* like it will on the frontend, with theme fonts, colors, and CSS)
- **Test in real chat** — opens the actual conversation in a new tab so you can send a test message before publishing
- **Copy the resulting shortcode** and paste it wherever you need it

## Attributes

### Targeting

| Attribute | Accepted values | What it does |
|---|---|---|
| `user_id` | `post_author` | Chats with the current post's author. |
| `user_id` | `postmeta:KEY` | Reads a numeric user id from the named postmeta key. Use this for marketplace vendor / agent / owner patterns. Example: `user_id="postmeta:_vendor_user_id"`. |
| `user_id` | a positive integer | Hard-coded user id. Used for site-wide support inboxes or specific staff users. |
| `user_id` | a negative integer | Targets an AI chat bot. Bot id is shown in **WP Admin → Better Messages → AI Chat Bots → edit bot → Bot User ID**. |
| `user_id` | omitted | Falls back to the current post's author (same as `post_author`). |
| `unique_tag` | `auto` | One thread per post — auto-generated as `{post_type}-{post_id}` (e.g. `vendor-42`). |
| `unique_tag` | template with `{post_id}` / `{post_type}` / `{author_id}` | Custom pattern. Example: `unique_tag="product-{post_id}"`. |
| `unique_tag` | any other string | Used as-is. The same string from different visitors opens the same thread (paired with the same target). |
| `unique_tag` | omitted | A new thread is opened each time. |
| `object_id` | `auto` | Attaches the current post as a [thread information banner](#thread-information-banner) inside the conversation. |
| `object_id` | a positive integer | Attaches a specific post id as the banner. |

### Label & subject

| Attribute | Accepted values | What it does |
|---|---|---|
| `text` | `auto` | Default label — `Chat with {author_name}` when a post is in context, otherwise `Live Chat`. |
| `text` | template with placeholders | Resolved against the current post — see [Placeholders](#placeholders). Example: `text="Ask {author_name} about {post_title}"`. |
| `text` | any string | Used as-is. |
| `text` | omitted | Renders `Live Chat`. |
| `subject` | any string (placeholders supported) | Pre-fills the conversation subject if a new thread is created. Ignored when an existing thread is reused. |

### Visual style

The shortcode emits a real `style=""` attribute composed of safe CSS values (filtered through WordPress's `safecss_filter_attr`). No additional stylesheet needed.

| Attribute | Example | Effect |
|---|---|---|
| `class` | `bm-lc-button-styled` | Extra CSS class on the button. The shipped `bm-lc-button-styled` class gives a branded baseline (background, padding, hover state) using your site's `--main-bm-color`. Add multiple classes space-separated. |
| `bg_color` | `#0073aa` / `rgb(0,115,170)` | Background color. |
| `text_color` | `#fff` | Text color. |
| `font_size` | `16px` | Font size. |
| `padding` | `10px 15px` | Padding shorthand. |
| `margin` | `0` | Margin shorthand. |
| `border_radius` | `4px` or `999px` | Border radius. Use a large value for a pill button. |
| `icon` | an `...` string | Inline SVG icon shown before the label. Sanitized at render time — scripts, event handlers, and `javascript:` URLs are stripped. |
| `type` | `link` (default) or `button` | Which HTML element to render. |
| `target` | e.g. `_blank` | HTML target attribute on the rendered link. |
| `alt` | any string | HTML `title` attribute on the rendered element. |

:::info
The `bm-lc-button-styled` class is enabled by default in the Shortcode Builder. The raw `[better_messages_live_chat_button]` shortcode (no class) renders an unstyled element — useful for sites that style the button themselves via CSS.
:::

## Placeholders

Tokens wrapped in curly braces are interpolated against the current post:

| Placeholder | Resolves to |
|---|---|
| `{post_id}` | Numeric ID of the current post. |
| `{post_title}` | Post title. |
| `{post_type}` | Post type slug. |
| `{author_id}` | Numeric ID of the post author. |
| `{author_name}` | Display name of the post author. |

Available in `text`, `subject`, and the custom-pattern form of `unique_tag`. When the shortcode runs outside of a post context (archives, sidebars, 404 pages), placeholders collapse to safe defaults — for example `text="auto"` falls back to `Live Chat` instead of producing `Chat with `.

## Thread information banner

When `object_id` is set, the chosen post becomes a banner inside the conversation — both participants see the post's title, thumbnail, and link at the top of the thread. The banner persists on every transport (REST, AJAX polling, WebSocket relays) and is written once when the thread is created (no overwrites).

Use it with `object_id="auto"` so the current post automatically becomes the context. Particularly useful for marketplace / directory / job board patterns where chats should clearly reference what they're about.

The banner is rendered with a built-in template by default. Sites that ship dedicated BM integrations (WooCommerce, WP Job Manager, Houzez) provide their own banner content via the `better_messages_rest_thread_item` filter and continue to win over the generic builder. For your own custom banner HTML, hook `better_messages_thread_info_banner_html`.

## Examples

### Post-author chat on every blog post

```
[better_messages_live_chat_button user_id="post_author" unique_tag="auto" object_id="auto" text="auto" class="bm-lc-button-styled"]
```

Drop this once into your single-post template (or use a content-injection plugin). Each post automatically gets a button that chats with its author, opens a per-post thread, and shows the post as a banner.

### Marketplace vendor button (user id stored in postmeta)

```
[better_messages_live_chat_button user_id="postmeta:_vendor_user_id" unique_tag="auto" object_id="auto" text="Chat with vendor" class="bm-lc-button-styled"]
```

Reads the vendor's WP user id from the `_vendor_user_id` postmeta key on the current listing. Works with any vendor / agent / owner postmeta field — change the key to match what your plugin or theme uses.

### Site-wide support inbox

```
[better_messages_live_chat_button user_id="1" unique_tag="support" text="Contact Support" class="bm-lc-button-styled"]
```

All visitors land in the same thread with admin user id 1. Add it to the site footer or a contact page.

### Pill-shaped orange button with custom inline styles

```
[better_messages_live_chat_button user_id="post_author" unique_tag="auto" object_id="auto" text="auto" class="bm-lc-button-styled" bg_color="#ff6b35" text_color="#ffffff" font_size="18px" padding="14px 24px" border_radius="999px"]
```

Inline style attributes override the `bm-lc-button-styled` defaults — no custom CSS required.

### Button with an inline SVG icon

```
[better_messages_live_chat_button user_id="post_author" unique_tag="auto" object_id="auto" text="auto" class="bm-lc-button-styled" icon='']
```

The icon is embedded directly in the shortcode — no separate icon font (Dashicons, Font Awesome) needed on the frontend. Use the Shortcode Builder's icon picker for a visual library, or paste any SVG.

### AI chat bot launcher

```
[better_messages_live_chat_button user_id="-3" text="Chat with our AI"]
```

Replace `-3` with the negative bot ID from **WP Admin → Better Messages → AI Chat Bots**. Clicking starts a conversation with the bot.

## PHP helper for theme templates

Theme authors can call the same handler directly without writing `do_shortcode()`:

```php
 'post_author',
    'unique_tag' => 'auto',
    'object_id'  => 'auto',
    'text'       => 'auto',
    'class'      => 'bm-lc-button-styled',
) );
?>
```

Same attributes, same behavior — just easier to embed inside a template file.

## Frequently asked questions

### How does it know which user to chat with?

By looking at `user_id`. The recommended value is `post_author` (chats with the post's author). Alternatives are `postmeta:KEY` (reads a numeric user id from the named postmeta), a hard-coded numeric id (site-wide), or a negative id (AI bot). When omitted, defaults to the current post's author.

### What is `unique_tag` for?

It groups visitors into the same thread when they target the same context. `unique_tag="auto"` produces one thread per post (good for "Chat with this vendor about this listing"). A static value like `support` produces one thread per visitor to a fixed inbox. Omitting it opens a fresh thread every time.

### Does the same shortcode work for guests and logged-in users?

Yes. Logged-in users open the chat directly. Guests see the guest authorization modal when **Guest Chat** is enabled; if it's disabled, they're redirected to the WordPress login page. The shortcode is identical either way.

### What's the thread information banner?

A header inside the conversation showing a post's title, thumbnail, and link. Set `object_id="auto"` and the current post becomes the banner — particularly useful for marketplace, directory, and job board sites where chats should clearly reference what they're about.

### Can I target an AI bot?

Yes. Set `user_id` to the bot's negative user ID (from the bot's settings page). Clicking opens a conversation with the bot.

### Can I style it like my theme's primary button?

Three options:
1. Use the Shortcode Builder's color / size / padding controls — emits inline `style="..."` attributes.
2. Pass your theme's button class via `class="btn btn-primary"`.
3. Drop the `bm-lc-button-styled` class entirely (raw `[better_messages_live_chat_button]`) and write your own CSS for `.bm-lc-button`.

### Where do I configure all this without touching shortcodes?

**WP Admin → Better Messages → Shortcodes → Shortcode Builder.** Visual form, live preview, test button. Copy the resulting shortcode.

## See also

- [better_messages_pm_button](/docs/shortcodes/better_messages_pm_button/) — legacy alternative
- [better_messages_mini_chat_button](/docs/shortcodes/better_messages_mini_chat_button/) — legacy alternative
- [better_messages_audio_call_button](/docs/shortcodes/better_messages_audio_call_button/) — voice call button
- [better_messages_video_call_button](/docs/shortcodes/better_messages_video_call_button/) — video call button
- [AI chat bots](/docs/features/ai-chat-bots/) — feature that this shortcode can launch

---

## better_messages_mini_chat_button Shortcode

# better_messages_mini_chat_button

:::info

**[How to add shortcodes?](https://www.wpbeginner.com/wp-tutorials/how-to-add-a-shortcode-in-wordpress/)**

:::
:::info WebSocket Version Guide

<>This functionality available only with WebSocket Version

:::

:::info Legacy shortcode
Prefer [`better_messages_live_chat_button`](/docs/shortcodes/better_messages_live_chat_button/) for new implementations — it auto-decides between mini chat and full page based on plugin settings, and reliably handles guest visitors.
:::

**Mini chat button shortcode**

Shows mini chat button (opens mini chat with user on click)

**This button will work only if Mini Chats option is enabled in plugin settings**

    
    
        Attribute
        Whats it for
        Default
    
    
    
    
        text
        Sets button text label
        "Private Message"
    
    
        user_id
        
            Set User ID with whom conversation will be started
        
        Post author of WordPress Post/Page
    
    
        subject
        
            Set subject for conversation
            If conversation already exists it will be ignored
        
        None
    
    
        unique_tag
        
            This will be usefully if you want to create unique conversations between buyers and seller, when they're discussing different products.
            
            For example set unique_tag to product_123 to create or open additional unique conversation between 2 members based on the tag.
        
        None
    
    
        class
        
            Sets additional class to button html element.
            Useful for additional CSS styling.
        
        None
    
    

```
[better_messages_mini_chat_button text="Private Message" subject="New conversation subject" class="extra-class"]
```

## Frequently asked questions

### Why is this marked legacy?
The newer `[better_messages_live_chat_button]` shortcode handles all the same use cases plus: guest authorization flow, automatic decision between mini-chat and full-page based on settings, and AI bot targeting via negative user IDs. Use it for new implementations.

### Will this shortcode keep working?
Yes — backwards-compatible. Existing pages using `[better_messages_mini_chat_button]` continue to work indefinitely. No need to migrate immediately.

### What's `unique_tag` for?
Creates a separate conversation per tag, even between the same two users. E.g., `unique_tag="product_123"` opens (or creates) a thread specific to "product 123". Useful for marketplace product Q&A where buyer-vendor have a per-product context.

### Does this work for guests?
No — the legacy shortcode doesn't handle guest auth flow. Use [`better_messages_live_chat_button`](/docs/shortcodes/better_messages_live_chat_button/) for guest-compatible usage.

### Does it respect the Mini Chats setting?
Yes — the button only opens a mini chat if Mini Chats is enabled in plugin settings. Otherwise, the button does nothing.

## See also

- [better_messages_live_chat_button](/docs/shortcodes/better_messages_live_chat_button/) — recommended replacement
- [better_messages_pm_button](/docs/shortcodes/better_messages_pm_button/) — other legacy alternative
- [Mini chats feature](/docs/websocket/mini-chats/) — popup chat windows (WebSocket version)
- [Mini widgets](/docs/features/mini-widgets/) — broader widget overview

---

## better_messages_my_messages_url Shortcode

# better_messages_my_messages_url

:::info

**[How to add shortcodes?](https://www.wpbeginner.com/wp-tutorials/how-to-add-a-shortcode-in-wordpress/)**

:::

A **URL-only shortcode** that returns the path to the logged-in user's inbox. Doesn't render any UI — just the URL string. Designed for use cases where you need the inbox URL as a link target (menu items, buttons, custom dashboard widgets) without embedding the full messenger.

## When to use it

| Scenario | Pattern |
|---|---|
| WordPress menu link to Messages | Use this shortcode with the [Shortcode in Menus](https://www.wordplus.org/shortcode-in-menus) plugin |
| Custom dashboard "View Inbox" button | Wrap the URL in your own anchor tag |
| Account-page link list | Add as one item in a user's account-actions list |
| Author bio "Message me" link | URL-only with custom button styling |

## Usage

```
[better_messages_my_messages_url]
```

Returns the URL of the page where the messenger lives — typically `/messages/` or wherever **WP Admin → Better Messages → Settings → General → Messages Location** points.

## In a menu (via Shortcode in Menus)

1. Install [Shortcode in Menus](https://www.wordplus.org/shortcode-in-menus)
2. **Appearance → Menus** → Add a Custom Link
3. URL: `[better_messages_my_messages_url]`
4. Label: "Messages"

When rendered, the URL placeholder is replaced with the actual inbox URL.

## In a custom anchor

```html

  View My Messages

```

The shortcode renders to the bare URL — wrap it in any element you want.

## Frequently asked questions

### What URL does this return for non-logged-in users?
An empty string. The shortcode only resolves a URL for authenticated users (logged-in WordPress users or authenticated guests). Wrap the shortcode with a login link in your template if you need to redirect anonymous visitors somewhere meaningful.

### Does this return a relative or absolute URL?
Absolute URL — full `https://yoursite.com/messages/` form. Useful for emails and external links.

### Can I include this in an email template?
Yes — though emails typically use a different anchor (each thread has its own deep-link URL). For "view all my messages" links in transactional emails, this is useful.

## See also

- [better_messages](/docs/shortcodes/better_messages/) — embed the full inbox UI
- [better_messages_unread_counter](/docs/shortcodes/better_messages_unread_counter/) — unread count for menus
- [Easy customization](/docs/features/easy-customization/) — configure where the inbox lives

---

## better_messages_pm_button Shortcode

# better_messages_pm_button

:::info

**[How to add shortcodes?](https://www.wpbeginner.com/wp-tutorials/how-to-add-a-shortcode-in-wordpress/)**

:::

:::info Legacy shortcode
Prefer [`better_messages_live_chat_button`](/docs/shortcodes/better_messages_live_chat_button/) for new implementations — it auto-decides between mini chat and full page based on plugin settings, and reliably handles guest visitors.
:::

**Private message button shortcode**

Shows private message button

    
    
        Attribute
        Whats it for
        Default
    
    
    
    
        text
        Sets button text label
        "Private Message"
    
    
        user_id
        
            Set User ID with whom conversation will be started
        
        Post author of WordPress Post/Page
    
    
        subject
        Prefill subject at the new conversation screen
        None
    
    
        message
        Prefill message at the new conversation screen
        None
    
    
        target
        
            Set _self to open in same page
            Set _blank to open in new browser tab
        
        _self
    
    
        fast_start
        
            Set 0 to force the new-conversation screen (with subject / message prefills).
            Default behaviour follows the global Fast Start setting under Better Messages → Settings → Messaging — when that setting is on, the button jumps straight into the existing thread and the subject / message attributes are ignored.
        
        1 (follow global setting)
    
    
        url_only
        
            Set 1 to not render button, but display just URL
        
        0
    
    
        class
        
            Sets additional class to button html element.
            Useful for additional CSS styling.
        
        None
    
    

[better_messages_pm_button text="Private Message" subject="Have a question to you" message="Lorem Ipsum is simply dummy text." target="_self" class="extra-class" fast_start="0" url_only="0"]
## Frequently asked questions ### Why is this marked legacy? The newer `[better_messages_live_chat_button]` shortcode handles guest authorization, auto-decides between mini-chat and full-page, and supports AI bot targeting. Use it for new implementations. ### Will this shortcode keep working? Yes — backwards-compatible. Existing pages using `[better_messages_pm_button]` continue to work indefinitely. ### What's `fast_start`? With `fast_start="1"`, clicking the button opens the conversation screen directly, skipping the new-conversation form. The `subject` and `message` prefills are ignored in fast-start mode. ### Why might I still use this over the new shortcode? `pm_button` has a `message` prefill attribute (the new shortcode doesn't, since it's geared toward universal use). If you specifically need to prefill the first message, this remains useful. ### Does this work for guests? No — the legacy shortcode doesn't include the guest authorization flow. Use [`better_messages_live_chat_button`](/docs/shortcodes/better_messages_live_chat_button/) for guest-compatible usage. ## See also - [better_messages_live_chat_button](/docs/shortcodes/better_messages_live_chat_button/) — recommended replacement - [better_messages_mini_chat_button](/docs/shortcodes/better_messages_mini_chat_button/) — other legacy alternative - [better_messages_user_conversation](/docs/shortcodes/better_messages_user_conversation/) — embed the conversation inline instead of as a button --- ## better_messages_single_conversation Shortcode # better_messages_single_conversation :::info **[How to add shortcodes?](https://www.wpbeginner.com/wp-tutorials/how-to-add-a-shortcode-in-wordpress/)** ::: :::info Compatibility <>This { (props.type ? props.type : 'guide') } compatible with Better Messages {props.version} or higher ::: Embed **one specific conversation thread** on any WordPress page using its thread ID. Unlike the main `[better_messages]` shortcode (which shows the user's full inbox), this shortcode locks the page to a single thread — useful for support ticket pages, announcement threads, or any context where you want users to interact with a specific conversation only. ## When to use it | Use case | Why a single conversation shortcode | |---|---| | Support ticket page | Each ticket is one thread; embed that thread inline | | Announcement thread | A specific "site announcements" thread shown on the homepage | | Event-day Q&A thread | A pinned thread visible during a live event | | Customer-vendor order page | The conversation tied to a specific order | | Documentation page Q&A | A specific thread for question/answer about that doc | ## Attributes | Attribute | What it does | Default | |---|---|---| | **`thread_id`** | The Better Messages thread ID to display | No default — required | ## Usage ``` [better_messages_single_conversation thread_id="55"] ``` Replace `55` with the actual thread ID. To find a thread's ID, view the conversation in WP Admin → Better Messages → Messages Viewer (when enabled) or via the REST API. ## Examples ### Site-wide announcement thread ``` [better_messages_single_conversation thread_id="1"] ``` Embed on the homepage to show every visitor the latest site-wide announcements thread. ### Per-order conversation (dynamic) ```php // In a template file: $thread_id = get_post_meta($order_id, '_bm_thread_id', true); echo do_shortcode('[better_messages_single_conversation thread_id="' . $thread_id . '"]'); ``` Embed the conversation tied to a specific WooCommerce order on the order detail page. ### Documentation Q&A thread ``` [better_messages_single_conversation thread_id="42"] ``` Drop into a documentation page to enable inline Q&A on that doc. ## Frequently asked questions ### Can users without access to the thread see it? No — standard access rules apply. If the current user isn't a participant in the thread (and the thread isn't a public chat room they have access to), they see a permission error. ### Can I show a thread to guests? Only if the thread is in a chat room with guest access enabled. Standard DMs require login. ### What happens if the thread is deleted? The shortcode renders an empty state — "This conversation is no longer available." To handle gracefully, conditionally include the shortcode based on thread existence. ### Can I show multiple threads on the same page? Yes — multiple `[better_messages_single_conversation]` shortcodes can appear on one page. Each renders independently. ### Does this work with the WebSocket version's real-time features? Yes — embedded threads get real-time updates, typing indicators, presence, and all other WebSocket-version features. ## See also - [better_messages](/docs/shortcodes/better_messages/) — full inbox layout - [better_messages_user_conversation](/docs/shortcodes/better_messages_user_conversation/) — auto-create with a specific user - [better_messages_live_chat_button](/docs/shortcodes/better_messages_live_chat_button/) — start a new conversation - [Group conversations](/docs/features/group-conversations/) — multi-user threads --- ## better_messages_unread_counter Shortcode # better_messages_unread_counter :::info **[How to add shortcodes?](https://www.wpbeginner.com/wp-tutorials/how-to-add-a-shortcode-in-wordpress/)** ::: Display the **unread messages counter badge** anywhere on your WordPress site — header, menu item, custom dashboard widget, or sidebar. Updates in real-time (instantly on the WebSocket version, on poll on the free version). The badge respects the global unread counter mode (per-message vs per-conversation). ## When to use it | Location | Why a counter badge | |---|---| | **Site header / menu** | Most common — let users see "Messages (3)" at a glance | | Member dashboard | Compact summary of pending communications | | Mobile floating button | Pair with the [floating chat button](/docs/features/enhanced-mobile/) for an icon + count | | User profile dropdown | Personal-area "you have N unread messages" indicator | | Sticky sidebar | Persistent visibility on long content pages | ## Attributes | Attribute | What it does | Default | |---|---|---| | **`hide_when_no_messages`** | If `1`, the counter is hidden when there are zero unread messages | `0` (always show) | | **`preserve_space`** | If `1` AND counter is hidden, the space is reserved invisibly — smoother animation when a new message arrives | `0` | ## Usage ### Always-visible counter ``` [better_messages_unread_counter] ``` Renders the counter regardless of unread state. Shows "0" when nothing is unread. ### Hide when zero ``` [better_messages_unread_counter hide_when_no_messages="1"] ``` Counter only appears when there are unread messages — cleaner UX for most sites. ### Hide with reserved space ``` [better_messages_unread_counter hide_when_no_messages="1" preserve_space="1"] ``` Best for menus: counter is invisible when zero but reserves the space, so new-message animations don't push other menu items around. ## Putting it in a menu The recommended pattern for adding the counter to your WordPress menu: 1. Install the [Shortcode in Menus](https://www.wordplus.org/shortcode-in-menus) plugin 2. **Appearance → Menus** → Add a Custom Link 3. URL: `[better_messages_my_messages_url]` (links to the inbox) 4. Label: `Messages [better_messages_unread_counter hide_when_no_messages="1" preserve_space="1"]` The result: a "Messages" menu item with a counter badge that appears when there are unread messages. ## Frequently asked questions ### Does the counter update in real-time? On the WebSocket version, yes — instantly as new messages arrive. On the free version, the counter updates every few seconds (matching the polling interval). ### What does the counter count — messages or conversations? Whichever you've configured in **Settings → Messaging → Unread Counter**. See [Unread filter](/docs/features/unread-filter/) for the counter mode options. ### Can I style the badge? Yes — the counter renders with stable class names (`.better-messages-unread-counter`). Override via your theme's Additional CSS. ### Does the counter appear for non-logged-in users? No — guests don't have a personal inbox, so the counter renders empty. For guest sites with guest chat, the counter reflects unread messages in their guest sessions. ### How can I hook into the counter value (for custom UI)? Listen for the `bp-better-messages-update-unread` `CustomEvent` on `document`. The new count is in `event.detail.unread`: ```js document.addEventListener('bp-better-messages-update-unread', (e) => { console.log('Unread count:', e.detail.unread); }); ``` ## See also - [better_messages_my_messages_url](/docs/shortcodes/better_messages_my_messages_url/) — pair this with the counter for menu items - [Unread filter](/docs/features/unread-filter/) — counter mode settings - [Site notifications](/docs/features/site-notifications/) — related on-site notification surface - [Enhanced mobile](/docs/features/enhanced-mobile/) — floating chat button (also has built-in counter) --- ## better_messages_user_conversation Shortcode # better_messages_user_conversation :::info **[How to add shortcodes?](https://www.wpbeginner.com/wp-tutorials/how-to-add-a-shortcode-in-wordpress/)** ::: :::info Compatibility <>This { (props.type ? props.type : 'guide') } compatible with Better Messages {props.version} or higher ::: Embed a **direct conversation between the current visitor and a specified user**. If they've never messaged before, the thread is created automatically. If a thread already exists, that thread is displayed. Perfect for author bio pages, vendor profiles, coach landing pages, and any context where a user should land directly in conversation with a specific person. ## When to use it | Use case | Pattern | |---|---| | Author bio "Message me" page | Auto-pull author from post context, embed DM thread | | Marketplace vendor storefront | "Message vendor" page with their dedicated thread | | Coaching / consulting landing page | Client lands directly in conversation with the coach | | Telemedicine practitioner profile | Patient gets direct chat with their assigned practitioner | | Support staff individual page | Direct DM with a specific support rep | ## Attributes | Attribute | What it does | Default | |---|---|---| | **`user_id`** | The user to start/show a conversation with | Author of the current WordPress post or page | ## Usage ``` [better_messages_user_conversation user_id="55"] ``` If `user_id` is omitted, the post/page author is used: ``` [better_messages_user_conversation] ``` ## Examples ### Coaching page ``` [better_messages_user_conversation user_id="12"] ``` Embed on a coach's landing page (user ID 12 = the coach). Visitors land directly in a private conversation with the coach. ### Marketplace vendor profile ```php // In a vendor profile template: $vendor_id = get_vendor_id_from_context(); echo do_shortcode('[better_messages_user_conversation user_id="' . $vendor_id . '"]'); ``` Each vendor profile gets a per-vendor DM thread auto-created for new visitors. ### Author bio (auto-detect) ``` [better_messages_user_conversation] ``` When placed on a post or page, no `user_id` needed — the post author becomes the recipient. Great for author bio boxes that consistently behave across all posts. ## Frequently asked questions ### What happens if the visitor isn't logged in? The shortcode shows a login form first. After login, the user is taken directly to the conversation with the specified user. ### Does this create a new thread every time? No — if a thread already exists between the two users, that thread is reused. New thread only when no prior conversation exists. ### Can guests use this shortcode? Only with [guest chat enabled](/docs/features/guest-access/). Guests get a transient identity for the conversation. ### What if the specified user_id doesn't exist? The shortcode shows a "user not found" notice. Always validate the user_id in dynamic shortcode usage. ### Is there a way to prepopulate a message? Not in the default UI. To pre-post a message into the thread programmatically, call `Better_Messages()->functions->new_message( [ 'sender_id' => …, 'recipients' => …, 'content' => … ] )` before rendering, or use a JS filter on the input. ## See also - [better_messages](/docs/shortcodes/better_messages/) — full inbox layout - [better_messages_single_conversation](/docs/shortcodes/better_messages_single_conversation/) — embed a specific existing thread - [better_messages_live_chat_button](/docs/shortcodes/better_messages_live_chat_button/) — button that starts a chat (lighter alternative) - [better_messages_pm_button](/docs/shortcodes/better_messages_pm_button/) — legacy "private message" button - [Group conversations](/docs/features/group-conversations/) — multi-user threads --- ## better_messages_video_call_button Shortcode # better_messages_video_call_button :::info **[How to add shortcodes?](https://www.wpbeginner.com/wp-tutorials/how-to-add-a-shortcode-in-wordpress/)** ::: :::info WebSocket Version Guide <>This functionality available only with WebSocket Version ::: Embed a **video call button** anywhere on your WordPress site that starts a one-on-one video call with a specified user. The shortcode works inside posts, pages, custom-built profile templates, page builders (Elementor / Bricks / Beaver), and any theme location that accepts shortcodes. ## When to use it | Scenario | Where you'd place the shortcode | |---|---| | Coaching / consulting profile pages | On the coach's listing page so prospects can start a call directly | | Marketplace vendor profiles | On the vendor's storefront for buyer-to-seller live demo calls | | Telemedicine / appointment booking | On the practitioner's profile after a booking is confirmed | | Custom member directory cards | In the per-member card template to expose a "Call" CTA | | Author bio boxes | Below blog posts for direct-to-author calls | ## Attributes Attribute What it controls Default text Button label text shown to the visitor "Video Call" user_id The recipient — the user who will receive the call Author of the current WordPress post or page url_only Set to 1 to return only the call URL (no button HTML). Useful for custom button styling. 0 target HTML target attribute on the rendered anchor (e.g. _blank to open in a new tab) None class Additional CSS class names on the button element for styling overrides None ## Examples ### Basic — call the post author ``` [better_messages_video_call_button] ``` Renders a button with the default "Private Message" label. Clicking it starts a video call with the author of the current post or page. Best for blog author bio boxes and CPT detail pages. ### Custom label and explicit recipient ``` [better_messages_video_call_button text="Start Video Call" user_id="42"] ``` The button label reads "Start Video Call" and connects to the user with ID 42 regardless of the current post author. Useful when the button lives outside a post context (sidebar, custom page). ### URL only — for custom-styled button ``` Talk to support live ``` Returns just the URL string. Wrap it in your own anchor element and apply any custom styling. The URL handles all the call-launching logic — clicking it opens the live video call in the Better Messages widget. ### Themed class for design integration ``` [better_messages_video_call_button text="Video Call" class="btn-primary btn-lg"] ``` Adds extra CSS classes to the rendered button — pair with Bootstrap / Tailwind / your theme's own button styles for consistent design. ## Frequently asked questions ### Does the button work for users who aren't logged in? Guests can see the button, but clicking it will redirect them to log in (or to your guest-chat flow, if guest access is enabled for video calls). The actual call requires both parties to have a session. ### What happens if the recipient is offline? The recipient sees a missed-call system message in the conversation when they next open the thread. Better Messages doesn't queue ringing for offline users. ### Will this work with the free version? No — video calls require the WebSocket version. The shortcode will still render the button, but clicking it shows a notice that the feature requires upgrading. ### Can I make the button appear only for specific user roles? The shortcode doesn't have role gating built in. Use a wrapping conditional in your theme or a shortcode-permission plugin if you need that. Alternatively, use the per-role call restrictions in **Settings → Calls** to control who can place calls at the global level. ## See also - [Audio call button shortcode](/docs/shortcodes/better_messages_audio_call_button/) — same pattern for voice-only calls - [Mini chat button shortcode](/docs/shortcodes/better_messages_mini_chat_button/) — open the mini chat widget - [Video calls feature](/docs/websocket/video-calls/) — full feature documentation - [WordPress video call plugin](/blog/wordpress-video-call-plugin/) — feature overview blog post --- ## One-on-One HD Audio Calls in WordPress Chat # HD Audio Calls The WebSocket version enables **HD 1-on-1 audio calls** directly from any conversation. Built on WebRTC for peer-to-peer audio streaming when possible (with TURN relay fallback for restrictive networks), audio quality is high and latency is low — comparable to dedicated voice apps like Zoom or Discord. :::info WebSocket version Audio calls are a WebSocket-version feature. For multi-party voice, see [group audio chat](/docs/websocket/group-audio-chat/) (up to 50 participants). ::: ## What it adds - 1-on-1 HD audio calls between any two participants - WebRTC peer-to-peer streaming — the audio doesn't transit Better Messages servers - Low latency, Opus codec for high quality at modest bandwidth (~30 kbps each direction) - Initiate from any conversation with one click - Works in all modern browsers (Chrome, Firefox, Edge, Safari, mobile equivalents) - Built-in call UI with mute, hang up, and timer ## How it works When a user clicks the **Call** button: 1. Signaling: the WebSocket relay carries SDP and ICE candidates between the two browsers 2. Peer-to-peer connection: the two browsers establish a direct WebRTC connection 3. Audio streaming: voice flows P2P between the participants 4. Fallback: if direct P2P fails (corporate firewall, symmetric NAT), a TURN relay forwards the encrypted audio | Network scenario | What happens | |---|---| | Normal home/office network | Direct peer-to-peer — minimal latency | | One participant behind strict firewall | TURN relay forwards encrypted audio | | Both behind corporate proxies | TURN relay (slight added latency) | All audio is **DTLS-SRTP encrypted** end-to-end — even when relayed through TURN, the audio bytes are encrypted between the participants. ## When 1-on-1 audio calls fit | Use case | Pattern | |---|---| | Coaching session | Coach-client 1-on-1 call inside the existing chat thread | | Customer support escalation | Voice call when chat alone is taking too long | | Marketplace negotiation | Quick voice call to close a higher-value deal | | Telemedicine consultation | Practitioner-patient 1-on-1 | | Dating community | Audio call as a step before video | ## Requirements - Website must use **HTTPS** (WebRTC requires secure context for microphone) - Each participant needs a working microphone - Modern browser with WebRTC support - WebSocket-version license ## Frequently asked questions ### Are calls recorded? No — calls are real-time and not recorded by Better Messages. To record, participants can use their own screen-recording or call-recording tools (with consent). The plugin doesn't include built-in recording. ### Can I configure per-role call permissions? Yes — restrict who can place calls via **WP Admin → Better Messages → Settings → Calls**. Useful for paid-tier-only calls. ### What if the recipient is offline? The caller sees a "user offline" notice. Better Messages doesn't queue ringing for offline users. ### Does audio quality degrade with poor networks? WebRTC adapts to bandwidth — under poor conditions, the bitrate drops automatically. Even on cellular, conversations remain intelligible. For truly bad connections, the call may drop and need to be re-initiated. ### How do group audio calls differ? [Group audio chat](/docs/websocket/group-audio-chat/) supports up to 50 participants and routes through a media server (SFU) rather than peer-to-peer. Different scaling model, similar end-user experience. ## See also - [Video calls](/docs/websocket/video-calls/) — 1-on-1 video calls - [Group audio chat](/docs/websocket/group-audio-chat/) — multi-party voice (up to 50) - [Group video chat](/docs/websocket/group-video-chat/) — multi-party video - [Screen sharing](/docs/websocket/screen-sharing/) — during any call - [Voice messages](/docs/addons/voice-messages/) — async voice (different from live calls) --- ## Encrypt Browser Chat Cache (AES-256) # Local Browser Encryption Better Messages caches recent message data in the **browser's IndexedDB** for fast loading and offline access. The WebSocket version can encrypt that cache with **AES-256** so it's protected against access by other users sharing the device — important for kiosks, shared computers, or public access scenarios. :::info WebSocket version This is a WebSocket-version feature. The free version caches less data and doesn't expose this encryption setting. ::: ## What it adds - AES-256 encryption of the local IndexedDB cache on each user's device - Protects offline message storage from unauthorized device-sharing access - Transparent to the user — no extra setup, no password prompts - The encryption key is tied to the user's session — only the authenticated user can decrypt - Important for kiosks, public-access PCs, family-shared computers, or office desktops with multiple users ## How it works When local browser encryption is enabled: 1. On login, your server provides the user's browser with a per-session encryption key 2. Before writing to IndexedDB, the browser encrypts the data with AES-256 3. Reads from IndexedDB decrypt on-the-fly 4. On logout (or session expiration), the key is wiped — the cache becomes unreadable | User action | What's protected | |---|---| | Logged in, browsing chat | Cache is encrypted in IndexedDB; transparent to the user | | Logged out | Cache is now unreadable — keys are gone | | Another user logs in on the same browser | They get their own key — can't read the previous user's cache | | Power user inspects IndexedDB via DevTools | Sees encrypted ciphertext, not plaintext messages | | Sophisticated attacker with full device access | Can extract encrypted blob but must defeat AES-256 to read content | ## When to enable | Environment | Recommendation | |---|---| | Public library / internet cafe terminals | Enable — multiple anonymous users share the device | | Kiosk-style installations | Enable — strong privacy default | | Office computers with multiple shifts | Enable — privacy between shift workers | | Healthcare environment | Enable + use [E2EE](/docs/websocket/e2e-encryption/) | | Personal-device-only audience | Optional — adds CPU overhead for limited threat | ## How to enable Enable **Browser Database Encryption** in **WP Admin → Better Messages → Settings → Messaging → Encryption**. The setting takes effect on the user's next page load. Existing un-encrypted cache entries are migrated to encrypted on read. ## Frequently asked questions ### Does this slow down the chat? The encryption / decryption happens transparently in WebAssembly or native CryptoAPI — overhead is small (sub-millisecond per operation). No perceptible difference. ### Can I export my cache as plaintext? No — the cache is intentionally inaccessible outside the authenticated user's session. To export your messages, use [WordPress's Personal Data Export](/docs/features/privacy-gdpr/) — that pulls from the server, not the cache. ### What if I want even stronger protection? Combine with [end-to-end encryption (E2EE)](/docs/websocket/e2e-encryption/) — that encrypts content end-to-end so even your WordPress server can't read it. Combine both for the strongest privacy stack. ### What happens if the user clears their browser data? The encrypted cache is deleted. The user will need to re-load message history from the server on next visit. Their data on your server is unaffected. ### Does this protect against malware on the user's device? Partially. Malware that runs in the same browser context as the chat could read the decrypted data while the user is logged in. AES-256 cache encryption protects against threats that access the disk directly (e.g., another user logging into the same OS account). ## See also - [Private (AES-256 transit)](/docs/websocket/private/) — content encryption in transit - [End-to-end encryption](/docs/websocket/e2e-encryption/) — true E2EE per-thread - [Secure (WSS / TLS)](/docs/websocket/secure/) — connection-layer security - [Your data is yours](/docs/websocket/your-data/) — data location overview --- ## How to Cancel a Better Messages WebSocket Subscription # Can I cancel my subscription after subscribing? Yes, you can cancel your WebSocket subscription at any time. Your license stays valid for the period you've already paid for — instant message delivery, voice / video calls, web push, the native mobile apps, and the rest of the WebSocket-only features continue to work until that period ends. After it expires, the plugin reverts to AJAX (free) behavior. Your messages, threads, history, files, integration data, and AI chat bots stay intact. No further charges are applied unless you resubscribe. ## How to cancel 1. Log in to your Freemius account at [https://users.freemius.com/](https://users.freemius.com/) 2. Go to **Licenses** 3. Find your Better Messages WebSocket subscription and click **Cancel subscription** You can also reactivate any time from the same dashboard. ## See also - [Refund policy](/docs/websocket/refund-policy/) — 7-day money-back guarantee terms - [Reset license](/docs/websocket/reset-license/) — moving a license to a new domain - [Pricing](/docs/pricing/) — current plans and billing options --- ## Cloud AI: Moderation, Translation, Voice Transcription # Better Messages Cloud AI Better Messages Cloud AI provides AI-powered features included with the WebSocket license at no additional cost. No third-party API keys or external accounts required. ## Features ### AI Content Moderation Automatically review messages for harmful or unwanted content using AI. - 23 content categories including extended categories (spam, scam, contact sharing, commercial promotion, and more) - Custom moderation rules in plain text - Conversation context awareness — detect patterns split across multiple messages - Text and image moderation - Two action modes: flag for review or hold until approved For full details see [AI Content Moderation](/docs/features/ai-content-moderation/). ### AI Message Translation Automatically translate incoming messages to each user's preferred language. - Currently available for 1-to-1 conversations only - 53 supported languages with automatic source language detection - HTML formatting preserved in translations - Users select their preferred language in the messaging settings panel - Translation toggle to switch between translated and original text For full details see [AI Message Translation](/docs/features/ai-message-translation/). ### Voice Message Transcription Automatically transcribe voice messages to text using AI speech recognition. - Supports 99+ languages with automatic language detection - Transcription results cached and displayed alongside voice messages - Users can view the transcription by clicking the transcribe button on any voice message #### How it works 1. A user sends a voice message in a conversation 2. Any participant clicks the transcribe button on the voice message 3. The audio is sent to Better Messages Cloud for transcription 4. The transcribed text appears below the voice message for all participants Transcription results are cached — once a voice message is transcribed, the text is stored and displayed instantly for all future views. #### Language By default, the language is automatically detected from the audio. If all users on your site speak the same language, you can set a specific language code (e.g. `en`, `ru`, `es`) in the settings for better accuracy and faster processing. ## How to enable ### Moderation Navigate to **WP Admin** → **Better Messages** → **Settings** → **Moderation**. 1. Select **Better Messages Moderation AI** as the provider 2. Enable **AI Moderation** 3. Choose the **Flagged Message Action** 4. Select **Content Categories** to detect ### Translation Navigate to **WP Admin** → **Better Messages** → **Settings** → **Translation**. 1. Enable **Message Translation** 2. Optionally restrict available languages in the **Available Languages** section 3. Users select their preferred language in the messaging settings panel inside the chat interface ### Transcription Navigate to **WP Admin** → **Better Messages** → **Settings** → **Voice Messages**. 1. Select **Better Messages Transcription AI** as the provider 2. Enable **Transcription** 3. Optionally set a **Language** code or leave empty for auto-detection :::note Requirements - WebSocket license - PHP 8.1 or higher - [Voice Messages](/docs/addons/voice-messages/) add-on (for transcription) ::: ## Callback URL Better Messages Cloud AI uses a callback URL to deliver results to your site. Some features (such as message translation) rely on this callback as the primary delivery method, so it must be reachable from the internet. If your server is behind a firewall, WAF, or a security plugin (e.g. Wordfence, Sucuri, Cloudflare Access) that blocks incoming requests from external servers, Cloud AI features may be slow or fail entirely. ### Testing the callback Each settings page that uses Cloud AI includes a **Test Callback URL** button. Click it to verify that the Better Messages Cloud server can reach your site's callback endpoint. If the test fails, you will see the exact URL that needs to be whitelisted. ### Whitelisting If the test fails, whitelist the following REST API endpoint in your firewall or security plugin: ``` https://yoursite.com/wp-json/better-messages/v1/ai/task-result ``` Replace `yoursite.com` with your actual domain. This is a POST endpoint that receives task results from the Better Messages Cloud server. ## Reliability Results are returned immediately when possible. If the response takes longer than expected, the cloud server delivers the result asynchronously via callback. In cases where the callback cannot reach your site (e.g. due to firewall restrictions), a background cron job retries periodically until the result is delivered. Processed results are cached on the cloud server for 30 minutes, making retries instant. ## Data Privacy Voice message audio and message content are sent to Better Messages Cloud for processing over HTTPS. All processing runs on private Better Messages servers — no data is shared with third parties. No user data is stored — content is processed in real time and immediately discarded. --- ## End-to-End Encryption (E2EE) for WordPress Chat # End-to-End Encryption Better Messages supports end-to-end encryption (E2EE) for private conversations, ensuring that only the participants can read the messages. The server never has access to message content — all encryption and decryption happens directly in the users' browsers. ## Requirements - **WebSocket version** — E2E encryption is only available with the WebSocket real-time mechanism (not available in AJAX mode) - **HTTPS/SSL** — the site must have SSL enabled, since the Web Crypto API requires a secure context - **Modern browser** — any browser with Web Crypto API support (all modern browsers including Chrome, Firefox, Safari, Edge) ## How it works When end-to-end encryption is enabled, each user generates a personal encryption key pair. When a conversation is created, a unique conversation key is generated and securely shared with each participant. Messages are encrypted before leaving the sender's browser and can only be decrypted by the intended recipients. The server stores only encrypted data — it relays messages between participants but cannot read their content. Even site administrators cannot access the plaintext of encrypted messages. ## Key capabilities - Messages encrypted in the browser before transmission — server never sees plaintext - AES-256-GCM encryption for message content and file attachments - ECDH P-256 key exchange for secure key distribution between participants - Password-protected key backup for multi-device access - Key recovery if the user forgets their encryption password - Automatic key distribution for new conversation participants - Key rotation when participants are removed from a conversation - Crypto operations offloaded to Web Workers for better performance - Mobile app support (iOS and Android) ## Setting up encryption ### First-time setup When a user first joins an encrypted conversation, they are prompted to create an encryption password. This password is used to protect their private key so it can be recovered on other devices or browsers. 1. User opens an encrypted conversation 2. A setup dialog appears asking them to create an encryption password 3. The system generates a personal key pair and securely backs up the private key (encrypted with the password) on the server 4. The user can now send and receive encrypted messages ### Multi-device access When accessing encrypted conversations from a new device or browser: 1. The user is prompted to enter their encryption password 2. The encrypted private key backup is downloaded from the server 3. The private key is decrypted locally using the password 4. The user can now read and send encrypted messages on the new device This works the same way on the mobile app — enter the encryption password to restore keys and access encrypted conversations. ### Password recovery If a user forgets their encryption password: 1. Click "Forgot password?" in the key restore dialog 2. Confirm the intent to reset — this generates new encryption keys 3. Enter a new encryption password 4. Other participants will automatically re-wrap the conversation key for the user's new identity key when they come online 5. Once re-wrapped, the user regains access to the conversation and can read previous messages ## How encryption works ### Identity keys Each user has a personal ECDH P-256 key pair: - **Public key** — shared with other users so they can establish secure key exchanges - **Private key** — never leaves the user's device in unencrypted form; backed up on the server encrypted with the user's password (PBKDF2 with 600,000 iterations) ### Conversation keys Each encrypted conversation has its own AES-256 symmetric key: - A random 256-bit key is generated when the conversation is created - This key is wrapped (encrypted) individually for each participant using ECDH shared secrets - Each participant unwraps the conversation key using their own private key - The conversation key is used to encrypt and decrypt all messages in that conversation ### File attachments File attachments in encrypted conversations are also encrypted: - A unique encryption key is generated for each file - The file is encrypted with AES-256-GCM before upload - The file key is wrapped with the conversation key (not directly with participant keys) - Each participant unwraps the file key using the conversation key, then decrypts the file - Decrypted files are cached locally in the browser for performance - File metadata (size, type) is visible to the server, but file content is encrypted ### Performance - All cryptographic operations (encryption, decryption, key wrapping) are offloaded to a SharedWorker or Web Worker so they don't block the UI - Conversation keys are cached in memory after first unwrap for fast encrypt/decrypt ## Group conversations End-to-end encryption works with group conversations: - All participants share the same conversation key - When a new participant is added, they are marked as "pending" until they receive the wrapped conversation key - Pending users see a notice that they need to set up encryption — they cannot send or read messages until setup is complete - Other participants can continue messaging normally while some users are pending - Key distribution happens automatically when both the pending user and a participant who holds the key are online - When a participant is removed, their wrapped key is deleted and they lose access to future messages ## Restrictions - Messages in encrypted conversations **cannot be forwarded** to other conversations - Encrypted conversations **bypass the moderation queue** — the server cannot read ciphertext, so content moderation is not possible for E2E messages - The server **rejects unencrypted messages** sent to encrypted conversations — all messages must be valid E2E ciphertext - AI chat bots are always excluded from encrypted conversations - When creating a new conversation with an AI bot as recipient, the E2E encryption toggle is automatically disabled ## Security properties ### What is encrypted end-to-end - Message text content - File attachment content ### What is NOT encrypted end-to-end - Message metadata (sender, timestamp, read status) - Conversation participant list - User presence and typing indicators - Conversation settings - File metadata (size, type) ### Server limitations - The server relays encrypted messages but cannot decrypt them - The server stores encrypted private key backups but cannot access them without the user's password - Site administrators can see conversation metadata but not message content ## Admin experience - The moderation queue shows **"Encrypted message"** as a placeholder for E2E message content - Admins can see conversation metadata (participants, timestamps, message count) but not the actual content - File attachment metadata (count and size) is visible in the admin panel, but file content is encrypted ## Mobile app support End-to-end encryption is fully supported on the iOS and Android mobile apps: - Uses native cryptographic operations - Keys are backed up and recoverable across devices using the same password-based recovery as the web version - The same encryption password works on both web and mobile ## How to enable All encryption settings are located in **WP Admin → Better Messages → Settings → Messaging → Encryption**. - **Enable End-to-End Encryption** — main toggle to activate the E2E encryption feature. Requires HTTPS to be enabled on your site. The following options become available once E2E encryption is enabled: - **Enabled by default** — the encryption toggle will be pre-checked when users create new conversations. Users can still uncheck it to create unencrypted conversations. - **Force for all conversations** — all new private conversations will be end-to-end encrypted. Users cannot disable encryption. This option requires "Enabled by default" to be checked. - **Allow guest users** — allow guest chat users to participate in end-to-end encrypted conversations. AI chat bots are always excluded regardless of this setting. --- ## Better Messages End User License Agreement (EULA) — Freemius # End User License Agreement Effective as of Nov 29, 2017 To help you understand the [EULA (End User License Agreement)](https://freemius.com/plugin/1557/bp-better-messages/legal/eula/#eula), we’ve prepared a bullet-point list that summarizes some of the main ideas (yes, including rights, obligations, liabilities, and all that legalese!) covered in there. IMPORTANT: The following bullet-point list is for convenience purposes only, in order to help you navigate (and hopefully, better understand) the [EULA](https://freemius.com/plugin/1557/bp-better-messages/legal/eula/#eula). This bullet-point list is _not_ a substitute for, or even a part of, the [EULA](https://freemius.com/plugin/1557/bp-better-messages/legal/eula/#eula), whose terms and conditions constitute a legally binding contract. It is your responsibility to fully read those terms and conditions. General ------- * The agreement is published at [https://freemius.com/plugin/1557/bp-better-messages/legal/eula/](https://freemius.com/plugin/1557/bp-better-messages/legal/eula/) * You, the customer (or the customer on whose behalf a service provider, such as an agency, is), must be of a legal age in your jurisdiction to form a binding contract, but in any event at least thirteen (13) years old to access or use the [Freemius service](https://freemius.com/). * Freemius, Inc. is an [authorized reseller of “BP Better Messages”](https://freemius.com/terms/vendor/) and is the 'merchant of record' for your purchase. * The agreement is between you and Freemius, Inc. on behalf of the Vendor behind “BP Better Messages” (the “_Vendor_”). You may not assign or transfer it without Freemius’ express prior written consent. * The agreement contains various clauses to limit and exclude Freemius’ and Vendor’s liability, and it also contains indemnity protection for Freemius and the Vendor. Support ------- * While the EULA is between You and Freemius, Inc., all support and maintenance services for the product (such as providing bug fixes, updates, upgrades, troubleshooting, etc.), if any, are the sole responsibility of the Vendor. * You can contact the Vendor’s support via [support@better-messages.com](mailto:support@better-messages.com). So if you're having trouble or have any questions, please contact [support@better-messages.com](mailto:support@better-messages.com) for assistance. * Freemius, Inc. resells and distributes “BP Better Messages” and other plugins and themes "as is" and with no implied or statutory warranties, or guarantees that they will function exactly as you would like, or that they will be compatible with all third-party components and plugins. * Support for this product is only available for those who have an active, paid license. * Product updates are granted for as long as the your license remains active. * Whilst the Vendor attempts to provide the best support possible, there's no guarantee that any particular support query can, or will, be answered to the extent, or within a timeframe, that the inquirer is completely satisfied. Security & Software Updates --------------------------- * Product security and feature updates are included for free as long as your license is active. Updates will be delivered automatically from the WordPress admin dashboard or you can manually download the latest version of the product from your dashboard: [https://users.freemius.com/login/](https://users.freemius.com/login/). Subscriptions & Automatic Renewals ---------------------------------- * The product’s license is sold as automatically recurring subscriptions that renew each month or year (depends on the subscription's billing cycle) on the anniversary of the purchase date. * All subscriptions automatically renew at the end of the monthly/annual license term unless You cancel the subscription prior to the automatic renewal date. * We cannot grant refunds on renewal payments. * For annual subscriptions, we will attempt to send you a renewal reminder email 30 days prior to your renewal date, and you may use this opportunity to cancel your subscription before the renewal payment is automatically processed. Such a reminder would only be a courtesy, and depends on your email client, potentially can end up at your spam box, so do not rely on that email - you alone are responsible for taking any action before a renewal takes effect. Just add yourself a calendar reminder :) * If a subscription renewal fails, the system will attempt to process the payment 3 more times according to our [dunning mechanism schedule](https://freemius.com/help/documentation/selling-with-freemius/dunning-failed-payments/). After the 4th failed attempt, the subscription will be canceled. * If you subscribe to the monthly or annual plans, and your license expires due to a failed renewal, subscription or license cancellation, the paid features & functionality of the product will be disabled. * You can always access your account and cancel the subscription via [https://users.freemius.com/login/](https://users.freemius.com/login/) Price Changes ------------- * Prices of “BP Better Messages” are subject to change without prior notice or consent. * As long as your subscription remains active and you don’t switch to another plan or license-level, your subscription renewals amount will not be affected by any price changes. Free Trials ----------- * If you subscribe for a trial with a payment method and cancel the trial before the 1st payment was processed, the paid features & functionality of the product will be disabled. * If you subscribe for a trial without a payment method and the trial expires, the paid features & functionality of the product will be disabled. * If you subscribe for a trial with a payment method, Freemius will attempt to send you an email reminder 2 days before the trial expiration, giving you enough time to cancel the trial. Such a reminder would only be a courtesy, and depends on your email client, potentially can end up at your spam box, so do not rely on that email - you alone are responsible for taking any action before a the trial expires. Just add yourself a calendar reminder :) * If you subscribe for a trial without a payment method, Freemius will attempt to send you an email reminder 2 days before the trial expiration, giving you the option to purchase a plan. Same like with the trial with a payment method, such a reminder would only be a courtesy, and depends on your email client, potentially can end up at your spam box. Refund Policy ------------- * If, during the first 7 days following the Purchase date, You experience a defect that makes the Product's material functions unusable, and following Your cooperation with our support team we are unable to resolve it, then following Your request we will issue a full refund of the Purchase price. For clarity, any defect or lack of use arising from a conflict or incompatibility with a third party product, is not covered by this policy, and nor are missing Product features. * There are a few very limited cases (as specified in the [EULA](https://freemius.com/plugin/1557/bp-better-messages/legal/eula/#eula)) in which Freemius will determine eligibility for refunds. Otherwise, eligibility for refunds are determined and governed exclusively by the Vendor and [Vendor's refund policy (see below)](https://freemius.com/plugin/1557/bp-better-messages/legal/eula/#refund_policy), and so your ability to get a refund therefor depends on Vendor's cooperation. In any case, no refunds are given beyond the scope of the [Vendor's refund policy](https://freemius.com/plugin/1557/bp-better-messages/legal/eula/#refund_policy), and nor are there any refunds available on renewal payments. END USER LICENSE AGREEMENT -------------------------- ### _Last Updated: July 22, 2021_ This End User License Agreement ("_Agreement_") constitutes a binding contract between you, the customer (or the customer on whose behalf a service provider, such as an agency, is) purchasing the Product (defined below) license ("_You_" and "_Your_") and Freemius, Inc. (“_Freemius_”, “_we_”, “_us_” and “_our_”). By placing Your order via the Checkout (defined below), or by otherwise accessing or using the Product, You acknowledge that You have read, understood, and agree to be bound by the following (the date of such occurrence being the "_Effective Date_"): 1. This Agreement; and 2. Other supplemental terms and policies referenced herein, which are stated to be incorporated into, and made a part of, this Agreement by reference. If You do not agree with any of the terms and conditions of this Agreement, do not place Your order and do not otherwise access or use the Product. Under this Agreement, You are purchasing a license to the Product ("_Purchase_"). Under Your Purchase, You receive a license (more on your license rights in Section 2 _(License)_ below). Your Purchase can either be a recurring subscription (e.g. 'monthly' or 'annual') license or a one-time 'lifetime' license (in each case, a "_License_", and respectively a "_Subscription License_" and a "_Lifetime License_"). Freemius is a reseller of the License, and is the 'merchant of record' for the purpose of this transaction. But the vendor from whom You are ultimately receiving access to the Product (the "_Vendor_") is otherwise responsible for the provision of the Product and all related services, and You acknowledge that Freemius is not the provider or operator of the Product. Again, more on this below. 1. DEFINITIONS AND INTERPRETATION ------------------------------ This Agreement contains a range of capitalized terms, some of which are defined in this Section, and some of which are defined elsewhere. The Section headings in this Agreement are for convenience of reading only, so do not rely upon them for interpretation. As used in this Agreement “_You_” means either you personally or, if you are entering into this Agreement on behalf of an entity (for example, if you are subscribing using an entity’s email domain), such entity, and in such case you represent that you have the authority to bind such entity to this Agreement. “_Affiliate_” means with respect to Freemius, any person, organization or entity controlling, controlled by, or under common control with, Freemius, where “control” means the possession, directly or indirectly, of the power to direct or cause the direction of the management and policies of such person, organization or entity, whether through the ownership of voting securities or by contract or otherwise. "_Checkout_" means the online checkout form which You submit(ted) for Your Purchase. Your order is subject to our Acceptance (defined below), and once Accepted the order is hereby incorporated into, and made a part of this Agreement, by reference. “_Product_” means the software product or service (such as _WordPress_ plugin or theme, or “Serviceware” plugin, or plugins and/or themes bundle) specified in the Checkout. References herein to "Product" shall also include any of its related documentation, as well as any updates and upgrades provided by the Vendor. “_Site_” means the digital property or service (such as a website, browser extension, mobile app, _etc._) owned or operated by You or Your client for which You are using the Product. In the case of a "WordPress multi-site network", each "network sub-site" shall be deemed a Site for the purposes of your order and this Agreement. "_Trial_" means a limited-in-time use of the Product on a trial basis. "_Trial Period_" means the period of the Trial, as specified in the Checkout. 2. ORDERING, REFUND POLICY AND TRIALS ---------------------------------- Your submitted order is only an offer, and is subject to our acceptance of it ("_Acceptance_"). Acceptance only occurs at such time that we have done both of the following: 1. as applicable (depending on the type of Product), provided You with license key(s); and 2. unless the order is for an Trial, received full payment (as confirmed by us or our payment service provider) of the purchase price of your order through settlement of funds via your provided credit card or other payment method. We may, without liability, reject Your order, or otherwise cancel Your order at any time and for any lawful reason prior to Acceptance (for example if we are unable to process or fulfill the order), and in such cases we will refund Your payment. Prior to Acceptance, an automatic e-mail acknowledgement of your order may be generated (but such acknowledgement does not constitute Acceptance of your order). FOLLOWING ACCEPTANCE, AN ORDER IS FINAL, NON-CANCELABLE, AND ORDER PAYMENTS ARE NON-REFUNDABLE, EXCEPT AS SPECIFIED IN THE FOLLOWING REFUND POLICY ("_Vendor Refund Policy_"), which is hereby incorporated into, and made a part of, this Agreement by reference: If, during the first 7 days following the Purchase date, You experience a defect that makes the Product's material functions unusable, and following Your cooperation with our support team we are unable to resolve it, then following Your request we will issue a full refund of the Purchase price. For clarity, any defect or lack of use arising from a conflict or incompatibility with a third party product, is not covered by this policy, and nor are missing Product features. Notwithstanding the above, if You are purchasing a bundled offering of more than one Product (a "_Bundled Offering_"), then the Purchase plan terms and refund policy that specifically govern that Bundled Offering as a whole (the "_Bundled Offering Terms_") shall apply instead of the above-mentioned Vendor Refund Policy, as well as to the extent of any other conflict or inconsistency with a provision of this Agreement. If You subscribed for a free Trial, Freemius may (but shall not be obligated to) send You an email two (2) or more days prior to the expiration of the Trial Period, giving You the opportunity to make a Purchase of the Product. If You subscribed for a Trial with a payment method (a "_Paid Trial_"), then: 1. Freemius may (but shall not be obligated to) send You an email reminder of the upcoming payment two (2) or more days prior to the expiration of the Trial Period. You acknowledge that such a reminder would only be a courtesy, and You alone are responsible for taking any action before a payment takes effect. 2. _In the case of 'monthly' or 'annual' Paid Trials:_ if (per the instructions in the reminder email) You fail to cancel the Trial prior to its expiration, the Trial shall convert to a paid Subscription License, and You will be charged the Fees (defined below) for the initial Purchase Term. 3. _In the case of a 'lifetime' Paid Trial:_ You are deemed to have purchased a Lifetime License, and, subject to the Vendor Refund Policy, You will not be charged the Fees until the expiration of the Trial Period.For the purposes of determining Refund eligibility under a Trial, the period stated in the applicable Vendor Refund Policy shall be deemed to begin on the first day of the Trial Period. 3. LICENSE AND RESTRICTIONS ------------------------ Subject to the terms and conditions of this Agreement, Freemius grants You the following License under Your Purchase. If a third party service provider (such as an agency) is entering into this Agreement on Your behalf for the purpose of operating the Product on Your behalf, the License (and any related services, such as support and maintenance) also extends to such service provider. The License is: 1. limited, non-exclusive, non-assignable, and non-sublicensable; 2. for the term of the Purchase plan (e.g. monthly, annual, lifetime, _etc._) specified in the Checkout, plus for whatever period thereafter the Product (in whole or in part) is still made available to You (the "_Purchase Term_"); 3. to access, use, and as applicable install or receive, the Product solely on or in connection with Your Site(s) (subject to the authorized number of Sites); and 4. subject to whatever volume, location, feature, and other limitations or conditions (if any) are specified in the Checkout. We recommend installing and testing the Product in a staging (or similar non-production) environment prior to installing it in the Site's production environment, and making necessary configurations, which should hopefully allow You to identify any code conflicts between the Product and other products or code of the Site, and therefore avoid disruption to Your Site. As a condition to the License, and unless You obtain the prior express written permission of the Vendor, You shall not do (or permit or encourage to be done) any of the following, in whole or in part: (a) copy, “frame” or “mirror” the Product, on any other server or wireless or Internet-based device; (b) sell, assign, transfer, lease, rent, sublicense, distribute, publicly perform, display or communicate, offer as part of a time-sharing, outsourcing or service bureau environment, or otherwise make available, the Product to any third party, or bundle or incorporate the Product into or with any other product or service; (c) modify, alter, adapt, arrange, or translate the Product; (d) decompile, disassemble, decrypt, reverse engineer, extract, or otherwise attempt to discover the source code or non-literal aspects (such as the underlying structure, sequence, organization, file formats, non-public APIs, ideas, or algorithms) of, the Product; (e) remove, alter, or conceal any copyright, trademark, or other proprietary rights notices displayed on or in the Product; (f) circumvent, disable or otherwise interfere with security-related or technical features or protocols of the Product; (g) make a derivative work of the Product, or use the Product to develop any service or product that is the same as (or substantially similar to) the Product; (h) store or transmit any robot, malware, Trojan horse, spyware, or similar malicious item intended (or that has the potential) to damage or disrupt the Product; (i) use the Product to infringe, misappropriate, or violate any third party's Intellectual Property Rights, or any applicable law (such as anti-spamming laws), or to otherwise engage in any fraudulent activity; (j) employ any hardware, software, device, or technique to pool connections or reduce the number of Sites, devices or users that directly access or use the Product (sometimes referred to as 'virtualisation', 'multiplexing' or 'pooling') in order to circumvent any restrictions on scope of the License; or (k) take any action that imposes or may impose (as determined in Freemius' reasonable discretion) an unreasonable or disproportionately large load on the servers, network, bandwidth, or other cloud infrastructure which operate or support the Product, or otherwise systematically abuse or disrupt the integrity of such servers, network, bandwidth, or infrastructure. The Product may include third party software components, as well as proprietary components (such as [Freemius' SDK](https://github.com/freemius/wordpress-sdk) component that is applied to the Product), that are subject to open source licenses and/or notices (“_Third Party Software_” and “_Third Party Software Terms_”, respectively). This Agreement is not intended, and shall not be construed, to derogate from any rights You may have under such Third Party Software Terms. Accordingly, to the extent that the Product (or any part thereof) is subject to any Third Party Software Terms or to any other licensing terms, and they conflict with the scope of the License granted to You or with any provision of this Agreement, such Third Party Software Terms or other licensing terms (as the case may be) shall prevail. Any undertakings, representations, warranties, guarantees, conditions, or other commitments made by Freemius in this Agreement concerning the Product (if any), are made by Freemius and not by any authors, licensors, or suppliers of, or contributors to, such Third Party Software. _As an example only: if the Product is subject to the GNU General Public License (GPL), then You may use the Product in accordance with the GPL, and may ignore any provision of this Agreement (such as a conflicting License restriction above or a conflicting ownership provision) which conflicts with the GPL._ 4. PAYMENT AND PRICING ------------------- 1. Fees. If or once You have purchased a paid License (including, for example, if You failed to cancel a Paid Trial before its expiry), You agree to pay all fees stated in the Checkout ("_Fees_"), and in accordance with its payment terms. Following receipt of Your order, You authorize Freemius (either directly and/or through third parties) to request and collect payment (or otherwise charge, refund or take any other billing actions) from our payment provider or Your designated banking account, and to charge Your payment method, as well make any inquiries Freemius deems necessary to validate Your designated payment account or financial information, in order to ensure prompt payment (including for the purpose of receiving updated payment details from Your payment, credit card or banking account provider – such as, updated expiry date as may be provided to us by Your credit card company). In connection with Purchase renewals (if applicable), Freemius will attempt to automatically charge You the applicable renewal Fees. In the event of failure to collect the Fees owed by You, we may (but shall not be obligated to) retry to collect at a later time, and/or suspend or terminate Your Purchase, without further notice. Where the Fees are invoiced, each invoice shall be due and payable in full by the due date specified on the invoice.Freemius shall not be responsible or liable (such as for bank fees) in the event any charge causes a negative balance in Your bank or payment account. 2. Refunds. _Except where there has been a duplicate charge to Your payment method (in which case Freemius may, but is not obligated to, determine Refund eligibility:_ You acknowledge and agree that any refunds, cancellations, and returns (collectively, "_Refunds_") for the Product are subject to the [Vendor Refund Policy](https://freemius.com/plugin/1557/bp-better-messages/legal/eula/#refund_policy) only, and that, even though Freemius may assist or otherwise be involved in administering Refunds eligibility for Refunds is determined solely by Vendor (and not Freemius), and accordingly any Refund requests must be made directly to the Vendor. Failure by Vendor to respond to a Refund request or inquiry (for example, if Vendor ceases to do business) shall not give rise to or impose any obligation or liability on Freemius. 3. Price Changes; Renewal Discounts. _In respect of Subscription Licenses only:_ Provided that Your recurring subscription is active, has not changed, and has not been terminated or cancelled: (a) any changes (increases or decreases) to the Product pricing during the Purchase Term shall not affect Your Purchase plan; and (b) You will be entitled to any renewal discounts offered by the Vendor. 4. Changing Plans. When You change Your Purchase plan, You will be deemed to have made a new Purchase, and accordingly no renewal discount will be applicable for such change. You may, however, be entitled to pro-rated Fees for the new Purchase (as further described here: [https://freemius.com/help/documentation/selling-with-freemius/proration/](https://freemius.com/help/documentation/selling-with-freemius/proration/)). 5. General. Pricing for the Product is exclusive of all applicable sales, use, consumption, VAT, GST, and other taxes, duties or governmental charges, except for taxes based upon Freemius' net income. Unless expressly stated otherwise in the Checkout, all amounts payable under this Agreement: 1. are stated, and are to be paid, in US Dollars; 2. are payable in advance (accordingly to the applicable billing cycle); and 3. are non-refundable (subject to the Vendor Refund Policy), and are without any right of set-off or cancellation. 5. PRODUCT SUPPORT AND MAINTENANCE ------------------------------- All support and maintenance services for the Product (such as providing bug fixes, updates, upgrades, troubleshooting, _etc._), if any, are the sole responsibility of the Vendor, and You agree: (a) to look to the Vendor alone for such support and maintenance; and (b) that Freemius has no obligation to provide any such (or similar) services under this Agreement. Nor does Freemius offer or give any Product warranty (see Section ‎8 _(Disclaimer of Warranties)_ for more information). Any Product support and maintenance services that are provided by the Vendor will (unless the Vendor agrees in writing with You otherwise) only be provided to You (or Your service provider, if applicable) and with respect to the applicable Site(s). Some updates and upgrades may be implemented by the Vendor automatically, and some may be implemented manually; but in either case, updates and upgrades to the Product will override any prior modifications You made to the Product. Moreover: (i) You will not be eligible for support and maintenance services in the event You modify the Product, nor following termination or cancellation of Your Purchase; and (ii) no undertaking is made by Vendor that it will support or maintain the Product (for example, if the Vendor ceases to do business or retires the Product), even if You have purchased a Lifetime License. Vendor's support contact is: [support@better-messages.com](mailto:support@better-messages.com) The only support Freemius shall be obligated to provide under this Agreement is first-tier aftersales support (which includes billing and order-related support), which will be provided to You only. 6. PRODUCT FEATURES ---------------- As with support and maintenance services, features of the Product are also the sole responsibility of the Vendor. This includes, but is not limited to, issues as to feature availability, operability, blocking, and de-activation. A new or modified feature may be accompanied by separate or additional terms and conditions. You agree: (a) to look to the Vendor alone for issues relating to features; and (b) that Freemius has no obligation to address issues relating to features. _Moreover, and in respect of Licenses that are configured by the Vendor as 'blocking' Licenses:_ following termination or cancellation of Your Purchase or Your Paid Trial, or expiration of Your free Trial without a payment method, some or all of the Product's 'paid' features may be disabled by the Vendor (and in the event Your Purchase plan is 'monthly', and depending on Your billing cycle, such 'paid' features are automatically disabled), and You acknowledge that this may have the effect of disabling or rendering unusable the entire Product itself. 7. OWNERSHIP --------- 1. Product. Freemius and/or its licensors (including without limitation the Vendor) exclusively own all Intellectual Property Rights (defined below) in and to the Product. Furthermore, Freemius and/or its licensors shall exclusively own (and are hereby assigned) all Intellectual Property Rights in and to any derivative works and/or improvements in or to the Product (regardless of inventorship or authorship); unless the Product is governed by Third Party Software Terms that permit You to make derivative works and/or improvements to the Product, in which case, as between You, Freemius and Vendor, You will exclusively own the Intellectual Property Rights in and to such derivative works and improvements. Except for the License, You are granted no other right or license in or to the Product, whether by implied license, estoppel, patent exhaustion, operation of law, or otherwise. Any rights not expressly granted herein are hereby reserved by Freemius and its licensors. You agree that Vendor shall be a third party beneficiary under this Agreement with the right to enforce provisions hereunder that relate to Vendor's Intellectual Property Rights. 2. Feedback. If You provide Freemius with any ideas, suggestions, or similar feedback about performance of the Product or for improving the Product (“_Feedback_”), You hereby grant to each of Freemius and all Freemius Affiliates a worldwide, assignable, non-exclusive, royalty-free, fully paid-up, sublicensable (through multiple tiers of sublicensees), irrevocable, and perpetual license, to access, use, reproduce, distribute, publish, broadcast, make available to the public, modify, adapt, edit, create derivative works of, publicly display, publically perform, and otherwise commercially exploit such Feedback, in any media format and through any media channels (now known or hereafter developed) (“_Feedback License_”). You hereby represent and warrant that: (A) the Feedback does not, and will not, infringe, misappropriate or violate any third party's Intellectual Property Rights, or any law; and (B) You have obtained, and will maintain during and after this Agreement, all licenses, permissions, consents, approvals, and authorizations required to grant the Feedback License. The Feedback License shall survive any termination of this Agreement. 3. Definition of IP Rights. “_Intellectual Property Rights_” means any and all rights, titles, and interests in and to inventions, works of authorship, databases, technology, designs, and other intellectual property, and includes without limitation patents, copyright and similar authorship rights, personal rights (such as moral rights, rights of privacy, and publicity rights), architectural, building and location (and similar geography-based) rights, mask work rights, trade secret and similar confidentiality rights, design rights, database rights, industrial property rights, trademark, trade name, trade dress and similar branding rights, as well as: (a) all applications, registrations, renewals, extensions, continuations, continuations-in-part, divisions or reissues of the foregoing rights; and (b) all goodwill associated with the foregoing rights. 8. TERM AND TERMINATION -------------------- 1. Purchase Term and Renewals. This Agreement commences on the Effective Date and shall, unless terminated in accordance herewith, continue in full force and effect for the duration of the Purchase Term. If the Purchase Term is 'monthly' or 'annual', it shall automatically renew for successive periods of equal length, unless you cancel the Purchase by canceling the subscription prior to such renewal in accordance with the below. If the Purchase Term is 'annual' (including multi-annual), Freemius may (but shall not be obligated to) provide You with a reminder of the upcoming renewal. You acknowledge that such a reminder would only be a courtesy, and You alone are responsible for taking any action before a renewal takes effect. 2. Cancellation by You. You may cancel Your Purchase at any time and for any reason, via the functionality offered. If You cancel the Purchase, the cancellation will take effect immediately (and will automatically stop any renewals) and the corresponding License will terminate at the end of the then-current Purchase Term. If you purchased a Lifetime License, the Purchase is not eligible for cancellation by You. For the avoidance of doubt, You will not be entitled to any refund in cases where You cancel Your Purchase. If You cancel a Trial, the Product's 'paid' features will be automatically disabled, unless the Product is designated as 'premium-only', in which case the entire Product will be disabled. If You object to any provision of this Agreement or any subsequent changes thereto, or become dissatisfied with the Product in any way, Your only recourse against Freemius is to cancel Your Trial or Purchase (as applicable) as aforementioned. 3. Termination by Freemius for Convenience. Freemius may, at any time, terminate Your Purchase (regardless of the Purchase Term) for convenience, by written notice to You (including via the functionality offered). In such cases, Freemius shall give You a pro-rated refund of any prepaid Fees, as follows: (a) in the case of a Lifetime License, depreciated on a three (3) year straight line basis from the date of installation of the Product; and (b) in the case of a Subscription License (such as 'monthly' or 'annual'), based on the remaining then-current Purchase Term. 4. Termination by Freemius for Breach. Freemius may terminate Your Purchase (regardless of the Purchase Term) in the event You breach any material provision of this Agreement (for example, if you breach the License) and fail to cure such breach, if curable, within thirty (30) days of receiving written notice from Freemius. For the avoidance of doubt, You will not be entitled to any refund in the event of such termination. 5. Effect of Purchase Termination. Upon termination or cancellation of Your Purchase: (a) the License automatically terminates, and You must immediately cease all access to and use of the Product except to the extent any features of the Product remain available to You; (b) You shall promptly pay any unpaid amounts that are outstanding as of such termination or cancellation. Termination and cancellation shall not affect any rights and obligations accrued as of the effective date thereof. 6. Survival. Any provision that is stated to survive, or that ought by its nature to survive, shall survive termination of this Agreement. The following shall also survive termination of this Agreement: Sections 7 (_Ownership_) through 14 (_Miscellaneous_) inclusive. 9. DISCLAIMER OF WARRANTIES ------------------------ THE PRODUCT, AS WELL AS ANY OTHER ITEMS OR SERVICES PROVIDED BY FREEMIUS, ARE PROVIDED AND MADE AVAILABLE TO YOU ON AN “AS IS” AND “AS AVAILABLE” BASIS, WITH ALL FAULTS, AND WITHOUT ANY REPRESENTATION, WARRANTY, GUARANTEE OR CONDITION OF ANY KIND WHATSOEVER, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, SATISFACTORY QUALITY, QUIET POSSESSION, TITLE, QUALITY OF SERVICE, NON-INFRINGEMENT, OR THAT OTHERWISE ARISE FROM A COURSE OF PERFORMANCE OR DEALING, OR USAGE OF TRADE, ALL OF WHICH ARE HEREBY DISCLAIMED BY FREEMIUS AND ITS LICENSORS AND SUPPLIERS (INCLUDING WITHOUT LIMITATION THE VENDOR). IN ADDITION, NEITHER FREEMIUS NOR ITS LICENSORS OR SUPPLIERS (INCLUDING WITHOUT LIMITATION THE VENDOR) DOES NOT MAKE ANY REPRESENTATION, WARRANTY, GUARANTEE OR CONDITION: (A) REGARDING THE EFFECTIVENESS, USEFULNESS, RELIABILITY, AVAILABILITY, TIMELINESS, ACCURACY, OR COMPLETENESS OF THE PRODUCT; (B) THAT YOUR USE OF, OR RELIANCE UPON, THE PRODUCT WILL MEET ANY REQUIREMENTS OR EXPECTATIONS; (C) THAT THE PRODUCT WILL BE UNINTERRUPTED, SECURE, ERROR-FREE OR VIRUS-FREE, OR THAT DEFECTS WILL BE CORRECTED; OR (D) REGARDING THE SATISFACTION OF, OR COMPLIANCE WITH, ANY GOVERNMENT REGULATIONS OR STANDARDS. 10. LIMITATION OF LIABILITY ----------------------- 1. IN NO EVENT SHALL FREEMIUS, ANY FREEMIUS AFFILIATE, OR ANY OF OUR LICENSORS OR SUPPLIERS (INCLUDING WITHOUT LIMITATION THE VENDOR) BE LIABLE UNDER, OR OTHERWISE IN CONNECTION WITH, THIS AGREEMENT, FOR: 1. ANY CONSEQUENTIAL, INDIRECT, SPECIAL, INCIDENTAL, OR PUNITIVE DAMAGES; 2. ANY LOSS OF PROFITS, LOSS OF BUSINESS, LOSS OF REVENUE, OR LOSS OF ANTICIPATED SAVINGS; 3. ANY LOSS OF, OR DAMAGE TO, DATA, REPUTATION, OR GOODWILL; AND/OR 4. THE COST OF PROCURING ANY SUBSTITUTE GOODS OR SERVICES. 2. THE COMBINED AGGREGATE LIABILITY OF FREEMIUS AND ALL FREEMIUS AFFILIATES, AS WELL AS THE VENDOR, UNDER, OR OTHERWISE IN CONNECTION WITH, THIS AGREEMENT SHALL NOT EXCEED THE AMOUNTS ACTUALLY PAID BY YOU TO FREEMIUS UNDER THIS AGREEMENT FOR THE APPLICABLE PRODUCT THAT GAVE RISE TO LIABILITY. 3. THE FOREGOING EXCLUSIONS AND LIMITATIONS SHALL APPLY: (A) TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW; (B) EVEN IF FREEMIUS, A FREEMIUS AFFILIATE, OR THE VENDOR HAS BEEN ADVISED, OR SHOULD HAVE BEEN AWARE, OF THE POSSIBILITY OF LOSSES, DAMAGES, OR COSTS; (C) EVEN IF ANY REMEDY IN THIS AGREEMENT FAILS OF ITS ESSENTIAL PURPOSE; AND (D) REGARDLESS OF THE THEORY OR BASIS OF LIABILITY, INCLUDING WITHOUT LIMITATION BREACH OF WARRANTY, NEGLIGENCE, MISREPRESENTATION, STRICT LIABILITY, OR OTHER CONTRACT OR TORT LIABILITY. 11. INDEMNIFICATION --------------- 1. If any third party (including, but not limited to, a regulatory or governmental authority) brings any kind of demand, claim, suit, action or proceeding against Freemius, a Freemius Affiliate, the Vendor, and/or any of our or their respective directors, officers, employees, or representatives (each, an “_Indemnitee_”), and it is based upon or arises from: 1. Your use of the Product; 2. Your breach under any contract You may have with a Vendor; and/or 3. Your breach of any provision of this Agreement (each of the foregoing, an “_Indemnity Claim_”) then, upon written request by Freemius (to be decided in our sole discretion), You agree to assume full control of the defense and settlement of the Indemnity Claim; _provided, however,_ that (c) Freemius reserves the right, at any time thereafter, to take over full or partial control of the defense and/or settlement of the Indemnity Claim, and in such cases You agree to reasonably cooperate with Freemius' defense activities at Your own cost and expense; and (d) You shall not settle any Indemnity Claim, or admit to any liability thereunder, without the express prior written consent of the Indemnitee(s). 2. In addition, and regardless of whether (or the extent to which) You controlled or participated in the defense and/or settlement of an Indemnity Claim, You agree to indemnify and hold harmless the Indemnitee(s) for and against: (e) any costs and expenses (including reasonable attorneys' fees) incurred by the Indemnitee(s) in the defense of the Indemnity Claim; and (f) any amounts awarded against, or imposed upon, the Indemnitee(s) under such Indemnity Claim, or otherwise paid in settlement of the Indemnity Claim (including without limitation any fines or penalties). 12. GOVERNING LAW ------------- This Agreement (including without limitation its validity and formation) shall be governed by, and construed in accordance with, the laws of the State of New York, USA without regard to any conflicts of laws rules or principles. The United Nations Convention on Contracts for the International Sale of Goods and the Uniform Computer Information Transaction Act shall not apply to this Agreement and are hereby disclaimed. 13. DISPUTE RESOLUTION ------------------ __Please read this Section carefully.__ 1. Mandatory, Bilateral Arbitration. YOU AND FREEMIUS AGREE THAT ANY DISPUTE, CONTROVERSY OR CLAIM ARISING UNDER, OR OTHERWISE IN CONNECTION WITH, THIS AGREEMENT (EACH, A “_Dispute_”) SHALL BE RESOLVED ONLY BY FINAL AND BINDING BILATERAL ARBITRATION, except that each party retains the right to bring an individual action in a small claims court and the right to seek injunctive or other equitable relief in a court of competent jurisdiction to prevent the actual or threatened infringement, misappropriation or violation of a party’s Intellectual Property Rights. This agreement to arbitrate is intended to be broadly interpreted. 1. ### _Arbitration Rules and Governing Law_ * Notwithstanding Your and Freemius’ agreement that New York law governs this Agreement and its validity, interpretation and application, You and Freemius hereby further agree that the Federal Arbitration Act, 9 U.S.C. § 1, et seq. (“_FAA_”) applies to this agreement to arbitrate, and governs all questions of whether a Dispute is subject to arbitration. * Unless You and Freemius expressly agree otherwise in writing in respect of a Dispute, the arbitration shall be administered by Judicial Arbitration and Mediation Services, Inc. (“_JAMS_”), pursuant to JAMS Streamlined Arbitration Rules and Procedures (“_JAMS Streamlined Rules_”), as modified by this Agreement (that is, the terms of this Section ‎17 govern if they conflict with any of the JAMS Streamlined Rules), and consistent with the _JAMS Policy on Consumer Arbitrations Pursuant to Pre-Dispute Clauses Minimum Standards of Procedural Fairness_ (“_JAMS Consumer Fairness Standards_”). The arbitrator must honor the terms and conditions of this Agreement (including without limitation all liability exclusions and limitations), and can award damages and relief, including any attorneys’ fees authorized by law. YOU AGREE THAT, BY ENTERING INTO THIS AGREEMENT, YOU AND FREEMIUS ARE HEREBY EACH IRREVOCABLY WAIVING THE RIGHT TO A TRIAL BY JURY AND THE RIGHT TO PARTICIPATE IN A CLASS ACTION (OR OTHER CLASS-WIDE PROCEEDING). * Notwithstanding JAMS Streamlined Rule 8(b), You and Freemius agree that any dispute as to the arbitrability of a Dispute brought by either You or Freemius shall be resolved by a court of competent jurisdiction. 2. ### _No Class Arbitrations_ THIS ARBITRATION AGREEMENT DOES NOT ALLOW CLASS ARBITRATIONS EVEN IF THE JAMS STREAMLINED RULES, (OR OTHER PROCEDURES OR RULES OF JAMS) WOULD. RATHER, YOU AND FREEMIUS ARE ONLY ENTITLED TO PURSUE ARBITRATION ON AN INDIVIDUAL BASIS. FURTHER, AND UNLESS YOU AND FREEMIUS EXPRESSLY AGREE OTHERWISE IN WRITING IN RESPECT OF A DISPUTE, THE ARBITRATOR MAY NOT CONSOLIDATE MORE THAN ONE INDIVIDUAL PARTY’S DISPUTE WITH ANY OTHER PARTY’S DISPUTE(S), AND MAY NOT OTHERWISE PRESIDE OVER ANY FORM OF A REPRESENTATIVE OR COLLECTIVE PROCEEDING. 3. ### _The Arbitrator's Decision_ * The arbitrator will be subject to this Agreement, and shall not make any decision or award that is in excess of, or contrary to, what this Agreement provides. The arbitrator will render an award in accordance with JAMS Streamlined Rules. The arbitrator’s decision will include the essential findings and conclusions upon which the arbitrator based the award. Judgment on the arbitration award may be entered in any court having jurisdiction thereof. In the event any litigation should arise between You and Freemius in any court of competent jurisdiction in a proceeding to vacate or enforce an arbitration award, YOU AND FREEMIUS HEREBY IRREVOCABLY WAIVE ALL RIGHTS TO A JURY TRIAL, instead electing that the proceeding be resolved by a judge. The arbitrator may award declaratory or injunctive relief only in favor of the plaintiff/claimant and only to the extent necessary to provide relief warranted by the claimant’s individual claim. If You prevail in arbitration You will be entitled to an award of attorneys' fees and expenses, to the extent provided under applicable Law. Freemius will not seek, and hereby waives all rights Freemius may have under applicable Law, to recover attorneys’ fees and expenses if Freemius prevails in arbitration, unless You assert a frivolous claim. * The arbitrator’s decision and award is final and binding, with some exceptions under the FAA. 4. ### _Location and Fees_ * Unless You and Freemius expressly agree otherwise in writing, the arbitration will take place in-person at the following locations: (a) if You are a resident of a country in North America, Central America or South America, the arbitration will take place in New York City, New York, USA; or (b) if You are a resident of any other country in the world, the arbitration will take place in Tel Aviv-Jaffa, Israel. In the event JAMS indicates that it is unable to provide, or arrange for, an arbitrator in Israel, You agree that the arbitration will be held in New York City, New York, USA. * If You initiate an arbitration for a Dispute, You will be required to pay $250 of the fee required to initiate the arbitration and Freemius will pay any remaining JAMS Case Management Fees and all professional fees for the arbitrator’s services; You will remain responsible for its respective costs relating to counsel, experts, witnesses, and travel to the arbitration. * If Freemius initiates an arbitration for a Dispute, Freemius will pay all administrative fees and costs related to the arbitration, including all professional fees for the arbitrator’s services; You will remain responsible for its costs relating to counsel, experts, witnesses, and travel to the arbitration. 5. ### _Small Claims Court_ Notwithstanding the foregoing, either party may bring an individual action in a small claims court for Disputes within the scope of such court’s jurisdiction. This agreement to arbitrate does not preclude You from bringing issues to the attention of federal, state, or local agencies. Such agencies can, if the Law allows, seek relief against Freemius on Your behalf. 2. Opting Out of this Mandatory Arbitration. You can decline this agreement to arbitrate by contacting [legal@freemius.com](mailto:legal@freemius.com) within thirty (30) days of the Effective Date and stating that You decline this arbitration agreement. Furthermore, and notwithstanding the provisions regarding modification of the Agreement, if Freemius changes this _Dispute Resolution_ Section after the Effective Date (or the date You accepted any subsequent changes to this Agreement), You may reject any such change by providing Freemius written notice of such rejection to [legal@freemius.com](mailto:legal@freemius.com) within thirty (30) days of the date such change became effective, as per the terms of this Agreement. In order to be effective, the notice must include Your full name and clearly indicate its intent to reject the change(s) to this _Dispute Resolution_ Section. By rejecting such change(s), You are agreeing that it will arbitrate any Dispute between You and Freemius in accordance with the provisions of this _Dispute Resolution_ Section as of the Effective Date (or the date You accepted any subsequent changes to this Agreement), unless You declined this arbitration agreement in the manner described above. 3. Limitation on Claims. Regardless of any law to the contrary, any claim or cause of action arising out of, or related to, this Agreement must be filed within one (1) year after such claim or cause of action arose, or else You agree that such claim or cause of action will be barred forever. 4. Confidentiality of Disputes. All aspects of the arbitration proceeding, including but not limited to the decision and award of the arbitrator and compliance therewith, shall be strictly confidential. The parties agree to maintain its confidentiality, unless (and in such cases, only the extent) otherwise required by applicable law. This paragraph shall not prevent a party from submitting to a court of competent jurisdiction any information necessary to enforce an arbitration award, or to seek equitable relief. 14. MISCELLANEOUS ------------- 1. Entire Agreement. This Agreement represents the entire agreement between You and Freemius with respect to the subject matter hereof, and supersedes and replaces any and all prior and contemporaneous oral and/or written agreements, understandings and statements between You and Freemius with respect to such subject matter. You acknowledge and agree that in entering into this Agreement You have not relied on any statement or representation (whether negligently or innocently made) not expressly set out in this Agreement, such as statements and explanations in any FAQs, summaries or explanatory guides regarding this Agreement, or other marketing material on the Freemius or Vendor websites. To the extent of any conflict or inconsistency between these terms and conditions on the one hand, and the Checkout on the other hand, the former shall prevail. The language of this Agreement is expressly agreed to be the English language. By entering into the Agreement, You hereby irrevocably waive, to the maximum extent legally permitted, any law applicable to You requiring that the Agreement be localized to meet Your language (as well as any other localization requirements), or requiring an original (non-electronic) signature or delivery or retention of non-electronic records. We may be able (but are not obligated) to provide You with copies of this Agreement on written request; _however_, please be sure to print a copy of this Agreement for Your own records. 2. Assignment. Freemius may assign this Agreement (or any of its rights and/or obligations hereunder) without Your consent, and without notice or obligation to You. This Agreement is personal to You, and, except as permitted by this Agreement, You may not assign (or in any other way transfer) this Agreement (or any of its obligations or rights hereunder) without Freemius' express prior written consent. Any prohibited assignment shall be null and void. 3. Severability. If any provision of this Agreement is held by a court of competent jurisdiction to be illegal, invalid or unenforceable, then: (a) the remaining provisions of this Agreement shall remain in full force and effect; and (b) the Parties hereto agree that the court making such determination shall have the power to limit the provision, to delete specific words or phrases, or to replace the provision with a provision that is legal, valid and enforceable and that most closely approximates the original legal intent and economic impact of such provision, and this Agreement shall be enforceable as so modified in respect of such jurisdiction. In the event such court does not exercise the power granted to it as aforesaid, then such provision will be ineffective solely as to such jurisdiction (and only to the extent and for the duration of such illegality, invalidity or unenforceability), and will be substituted (in respect of such jurisdiction) with a valid, legal and enforceable provision that most closely approximates the original legal intent and economic impact of such provision. 4. Remedies. Except as may be expressly stated otherwise in this Agreement, no right or remedy conferred upon or reserved by any party under this Agreement is intended to be, or shall be deemed, exclusive of any other right or remedy under this Agreement, at law or in equity, but shall be cumulative of such other rights and remedies. 5. Waiver. No failure or delay on the part of any party in exercising any right or remedy under this Agreement shall operate as a waiver thereof, nor shall any single or partial exercise of any such right or remedy preclude any other or further exercise thereof or the exercise of any other right or remedy. Any waiver granted hereunder must be in writing (for waivers by You, emails will be acceptable; for waivers by Freemius, the writing must be duly signed by an authorized representative of Freemius), and shall be valid only in the specific instance in which given. 6. Relationship. The relationship of the parties is solely that of independent contractors. Nothing in this Agreement shall be deemed to create any employment, fiduciary, joint venture, agency or other relationship between the parties. 7. Notices. You agree that Freemius may send You notices by email and/or by regular mail. Except as stated otherwise in this Agreement or required by law applicable to You, You agree to send all notices to Freemius, to [support@freemius.com](mailto:support@freemius.com). 8. No Third Party Beneficiaries. Except as otherwise expressly provided in this Agreement (such as Freemius Affiliates, Freemius' licensors and suppliers (including without limitation the Vendor), and Indemnitees), there shall be no third-party beneficiaries of or under this Agreement. 9. U.S. Government Rights. The Product is “commercial computer software” and the documentation is “commercial computer software documentation”, pursuant to DFAR Section 227.7202 and FAR Section 12.212, as applicable. If You are an agency, department, employee or other entity of the United States Government, then Your access to and use of the Product shall be subject solely to the terms and conditions of this Agreement. 10. Export Compliance. You represent and warrant that: (a) You are not a resident of (and You will not use the Product in) a country that the U.S. government has embargoed for use of the Product, nor are You named on the U.S. Treasury Department’s list of Specially Designated Nationals or any other applicable trade sanctioning regulations of any jurisdiction; and (b) Your country of residence and/or incorporation (as applicable) is the same as the country specified in the contact and/or billing address provided to us. In the event You breach this Section (in whole or in part), or otherwise violate any Export Control Laws (defined below) in connection with the Product, You agrees to indemnify and hold harmless Freemius, all Freemius Affiliates, and the Vendor (including ours and their respective directors, officers, and employees) for any fines and/or penalties imposed upon Freemius, a Freemius Affiliate, and/or Vendor (or such individuals) as a result of such breach or violation. “_Export Control Laws_” means all applicable export and re-export control Laws applicable to You and/or Freemius, as well as the United States' Export Administration Regulations (EAR) maintained by the US Department of Commerce, trade and economic sanctions maintained by the US Treasury Department's Office of Foreign Assets Control, and the International Traffic in Arms Regulations (ITAR) maintained by the US Department of State. 11. Force Majeure. Freemius shall not be responsible for any failure to perform any obligation or provide any service hereunder because of any (a) act of God, (b) war, riot or civil commotion, (c) governmental acts or directives, strikes, work stoppage, or equipment or facilities shortages, and/or (d) other similar cause beyond Freemius' reasonable control. For the avoidance of doubt, any problems relating to the hosting of the Service shall not be deemed within Freemius' reasonable control. --- ## Group Voice Calls in WordPress Chat # HD Group Audio Chat The WebSocket version turns any conversation, group chat, or chat room into a **multi-party voice call** supporting up to 50 simultaneous participants. The feature uses WebRTC with a dedicated media server for efficient routing — call quality stays high even with dozens on the line, while bandwidth stays modest compared to video. :::info WebSocket version Group audio chat is a WebSocket-version feature. The free version does not include voice calling. ::: ## What it adds - Up to **50 simultaneous voice participants** per call - Works in private one-on-one conversations, group chats, and chat rooms - Lower bandwidth than group video — typically 50–80 kbps per participant - Media-server routing (SFU model) for stable quality at scale - Remote mute/unmute control for the call host - Per-role restrictions: control which user roles can place or join calls - Optional **mini-chat call buttons** in members directories and on profile pages - Bandwidth-friendly fallback for users on cellular / low-quality connections ## How it works A user clicks the **Voice Call** button in a conversation. Better Messages signals the request through the WebSocket relay; the cloud server allocates a call room on the media server. All participants connect to the media server via WebRTC. Each participant uploads their own microphone stream once; the media server distributes streams to everyone else — this is dramatically more efficient than full mesh (where each participant uploads to every other participant individually). | Topology | Network upload per participant | |---|---| | Full mesh (peer-to-peer) | (N−1) × stream — quadratic, breaks past 5–6 participants | | Media server (SFU) | 1 × stream — flat, scales to 50+ | The host (the user who started the call) can remotely mute disruptive participants. Participants can also self-mute, self-unmute, and leave anytime. The call session is independent of the underlying conversation thread — when the call ends, the conversation remains exactly as it was, with a system message noting "Voice call ended" and duration. ## When to use group voice over group video | Choose group voice when… | Choose group video when… | |---|---| | 10+ participants | Visual presence matters | | Mobile/cellular users | High-bandwidth connections | | Discussion / audio-first content | Demo, screen-share, face-to-face | | Bandwidth-constrained users | Standard broadband | | Privacy preference for audio only | Trust-building, sales / coaching | ## Requirements - Site must be served over **HTTPS** (browser WebRTC requirement) - Each participant needs a working microphone - Modern browser with WebRTC support (Chrome, Firefox, Edge, Safari, mobile equivalents) - WebSocket-version license active ## Configuration Per-role restrictions and optional mini-chat call buttons apply to both audio and video group calls — see [Group Video Chat → Per-role restrictions](./group-video-chat.mdx#per-role-restrictions) for the shared admin controls. ## Frequently asked questions ### What is the maximum number of participants? 50 simultaneous voice participants. Sites that regularly need more can contact support to discuss the self-hosted plan, where the cap can be raised based on media-server capacity. ### Are group voice calls recorded? No — calls are real-time only and not recorded by default. The plugin doesn't include built-in recording. Sites that need recording typically use a screen-recording layer at the participant level or browser-based recording extensions, subject to participant consent. ### Can guests (non-logged-in users) join a group voice call? Yes — if guest chat is enabled on the chat room, guests can join voice calls placed in that room. They appear by their entered display name. ### What's the bandwidth requirement per participant? About 50–80 kbps upload + 50–80 kbps download per active speaker. A 20-person call uses about 1.5 Mbps download on each device. The codec is Opus. ### Does the media server store anything? No. The media server routes audio streams in memory only — no storage, no recording, no transcription on the audio path. Call metadata (start time, participants, duration) is logged for the host's call history. ## See also - [Group video chat](/docs/websocket/group-video-chat/) — same scaling model with video - [Audio calls](/docs/websocket/audio-calls/) — one-on-one voice calling - [Video calls](/docs/websocket/video-calls/) — one-on-one video calling - [WordPress video call plugin](/blog/wordpress-video-call-plugin/) — feature post covering the full call stack - [WordPress group chat plugin](/blog/wordpress-group-chat-plugin/) — group chat overview --- ## Group Video Calls in WordPress Chat # HD Group Video Chat The WebSocket version enables **multi-party video calls** supporting up to 32 simultaneous participants. Works in any conversation, group chat, or chat room. Uses WebRTC with a media server (SFU) for efficient routing — call quality stays high even at scale. :::info WebSocket version Group video chat is a WebSocket-version feature. For voice-only multi-party (up to 50), see [group audio chat](/docs/websocket/group-audio-chat/). ::: ## How it works Group video chat can be started in any conversation, group chat, or chat room. The feature uses WebRTC with a media server for efficient multi-party video routing. All participants can see and hear each other simultaneously, with adaptive video quality that adjusts based on network conditions and the number of participants. Screen sharing is also available during group video chats. ## Key capabilities - Up to 32 simultaneous video participants - Available in conversations, group chats, and chat rooms - Adaptive video quality based on network conditions - Screen sharing during group video calls - Media server for efficient multi-party routing - Remote mute/unmute of participant microphones by the call host - WebRTC-based for low latency - Per-role restrictions for who can start and who can join — see below - Optional group call buttons in the mini chat header — see below - Available to guest visitors and AI bot participants when they're members of the conversation ## Requirements - Website must use **HTTPS** - Users need a working webcam and microphone - Modern browser with WebRTC support This feature is automatically available with the WebSocket version. ## Per-role restrictions Site administrators can block specific WordPress roles from starting and / or joining group calls. Open **WP Admin → Better Messages → Settings → Group Calls → Group Call Restrictions**. Group Call Restrictions admin section with two role checkbox lists (Restricted from Starting and Restricted from Joining), a custom restriction message field, and a checked role auto-locked in the Starting list because it is also restricted from joining - **Restricted from Starting** — selected roles will not see the start call button. They can still join group calls started by others (unless also restricted from joining). - **Restricted from Joining** — selected roles cannot join group calls at all. This implies they cannot start them either, so the same role is automatically locked in the Starting list. - **Restriction Message** — HTML-supported message shown to users blocked by the join gate when they hit the API directly. Site administrators are always exempt. Per-conversation moderator status is also respected — the per-thread "moderators only" start permission still applies on top of the role gate. Both restrictions apply to audio and video group calls. ## Mini chat buttons The mini chat (the floating popup chat window) can show optional Group Audio and Group Video call buttons in its header — mirroring the existing 1-on-1 audio/video icons. Toggle them under **WP Admin → Better Messages → Settings → Mini Widgets → Mini Widgets & Mini Chats → Mini Chats**. Mini Chats admin section showing Audio Call Button, Video Call Button, Group Audio Call Button and Group Video Call Button toggles When enabled, clicking the group call icon in a mini chat expands the conversation to full-screen and starts the call. The buttons hide automatically for users blocked by the per-role restrictions or by the per-thread `group_call_start_permission` meta — same gating as the conversation header. :::info **WebSocket version only.** The toggles are disabled with a "Get WebSocket License" link on the AJAX version. ::: ## Frequently asked questions ### What is the maximum number of video participants? 32 simultaneous participants. Sites needing more should discuss the self-hosted plan with support — the cap can be raised based on media-server capacity. ### Are group video calls recorded? No — calls are real-time only. To record, participants use their own screen-recording tools (with consent). ### Can guests join group video calls? Yes — if guest chat is enabled on the chat room and the room allows calls, guests can join. They appear by their entered display name. ### What's the bandwidth requirement per participant? About 500 kbps–2 Mbps per stream, depending on resolution. With adaptive bitrate, the experience degrades gracefully on slower connections. ### Does the media server store anything? No. The media server forwards streams in memory only — no storage, no recording, no transcription. ## See also - [Group audio chat](/docs/websocket/group-audio-chat/) — voice-only multi-party (up to 50) - [Video calls (1-on-1)](/docs/websocket/video-calls/) — 1-on-1 video - [Audio calls (1-on-1)](/docs/websocket/audio-calls/) — 1-on-1 voice - [Screen sharing](/docs/websocket/screen-sharing/) — share screen during any call - [Mini chats](/docs/websocket/mini-chats/) — call buttons in mini chat headers - [WordPress video call plugin blog post](/blog/wordpress-video-call-plugin/) — feature overview --- ## Instant Message Delivery via WebSocket # Instant Message Delivery The WebSocket version delivers messages **instantly** to all recipients using a persistent WebSocket connection. Unlike AJAX polling (which checks every 3-10 seconds), WebSocket maintains a live connection — messages appear the moment they're sent, with sub-200 ms latency. **Up to 200x faster** than AJAX mode. :::info WebSocket version Instant delivery is the headline benefit of the WebSocket version. Other features (typing indicator, presence, web push, voice/video) all depend on the persistent connection. ::: ## What it adds - Instant message delivery — sub-200 ms latency (vs 1-10 seconds on AJAX) - Persistent WebSocket connection maintained in the background - Single shared connection across all browser tabs (via SharedWorker) - Automatic reconnection after network interruptions - Works on all modern browsers supporting WebSocket - No additional setup beyond enabling the WebSocket mechanism ## How it works When a user opens a page with the messenger, the browser establishes a single WebSocket connection to the cloud relay. SharedWorker shares this connection across multiple tabs of the same site — so a user with 5 tabs open uses just 1 connection. When someone sends a message: 1. Browser → your WordPress server: save the message (your server stores it) 2. Your server → cloud relay: push the encrypted event 3. Cloud relay → all participants' open connections: deliver the event 4. Participants' browsers: render the message immediately End-to-end latency from sender → recipient is typically **under 200 ms** even across continents — meaningfully faster than what users perceive in AJAX-polling apps. | Mode | Latency | User experience | |---|---|---| | AJAX polling, 3-second interval | 0–6 seconds | "I'll see your reply eventually" | | WebSocket | < 200 ms | "Real-time conversation" | ## When instant delivery matters most | Use case | Why instant delivery is essential | |---|---| | Live customer support | Visitors expect chat-app speed; AJAX feels broken | | Marketplace buyer-vendor messaging | Pre-purchase questions need instant answers | | Dating community | Lag breaks the flow of natural conversation | | LMS office hours | Students and instructors need real-time back-and-forth | | Public chat rooms | Many participants — polling at scale becomes server-heavy | | Mobile-app users | Battery-sensitive: polling drains battery much faster | ## How to enable 1. Purchase and activate the WebSocket version license 2. Navigate to **WP Admin → Better Messages → Settings → General** 3. Set **Mechanism** to **WebSocket** ## Frequently asked questions ### What happens during a brief network drop? The connection auto-reconnects when network returns. Messages sent during the drop are queued and delivered on reconnect. No data is lost. ### Does the SharedWorker work in all browsers? SharedWorker is supported in Chrome, Firefox, Edge, and most modern browsers. Safari supports SharedWorker too (since version 16). For older browsers without SharedWorker support, the plugin falls back to a per-tab WebSocket — slightly more connections but same functionality. ### How does delivery work for users not currently on the site? - Tab open: instant via WebSocket - Tab closed but browser open: instant via web push (if enabled) - Browser closed: web push notification appears when the OS allows - Offline entirely: email notification fires after a delay ### Does instant delivery work on mobile? Yes — the same WebSocket connection runs on mobile browsers. The [native mobile app](/docs/category/mobile-app/) also uses WebSocket for instant delivery. ### Is there a way to test the latency on my site? Send a message between two browser tabs (one logged in as each user). On the WebSocket version, you should see the message appear on the other tab within ~200 ms. On AJAX, expect 1-6 seconds depending on polling interval. ## See also - [Real-time messaging](/docs/features/realtime-messaging/) — AJAX vs WebSocket comparison - [Load optimization](/docs/websocket/load-optimization/) — why WebSocket also reduces server load - [Typing indicator](/docs/websocket/typing-indicator/) — depends on WebSocket - [Presence indicator](/docs/websocket/presence-indicator/) — also WebSocket-only - [Message status](/docs/websocket/message-status/) — sent / delivered / seen via WebSocket --- ## Reduce WordPress Server Load with WebSocket # Load Optimization The WebSocket version **dramatically reduces server load** by replacing AJAX polling with a persistent WebSocket connection. Where the free version's polling generates dozens of requests per minute per active user against your WordPress server, the WebSocket version generates **zero** request-driven load for real-time delivery. :::info WebSocket version Load reduction is one of the most underrated benefits of upgrading. Sites with 100+ concurrent users see meaningful CPU and database reduction. ::: ## What it adds - Eliminates repeated AJAX polling requests to your server - One persistent connection per user instead of continuous HTTP requests - Dramatically lower CPU and database load on your WordPress server - Faster site performance for non-chat pages (more resources available) - WebSocket relay handles connection management offsite — no extra infrastructure on your end ## Load comparison | Concurrent users | AJAX (free, 3s interval) | WebSocket version | |---|---|---| | 10 | ~200 requests/min to your server | 0 polling requests | | 100 | ~2,000 requests/min | 0 | | 1,000 | ~20,000 requests/min (often overloads shared hosting) | 0 | | 10,000 | ~200,000 requests/min (requires dedicated infrastructure) | 0 | Polling requests aren't free — each one fires WordPress's full init, processes auth, queries the database. The WebSocket version cuts ALL of that out for real-time delivery. ## How it works Once a user opens a page with the messenger loaded: 1. The browser establishes a single WebSocket connection to the cloud relay 2. Real-time events (new message, read receipt, typing indicator, presence) flow through that connection 3. Your WordPress server is only touched when the user **sends** a message or **loads history** — both rare events compared to polling | Polling pattern | WebSocket pattern | |---|---| | Browser asks "any new messages?" every 3 seconds → server checks DB → returns yes/no | Server pushes new message to all participants when it happens | | 100% wasted requests when nothing's new | 0 wasted requests | ## When the difference matters | Site profile | Impact | |---|---| | Shared hosting with 50+ active users | Free version may overwhelm hosting; WebSocket fixes it | | VPS / dedicated server | Free version works but consumes resources WebSocket would free up | | Cloudflare / caching layer | Polling requests bypass cache; WebSocket bypass-cache impact is zero | | Sites running other heavy plugins | WebSocket frees DB capacity for those plugins | ## Frequently asked questions ### Where does the WebSocket connection go? To the **Better Messages cloud relay** — a separate infrastructure included with the WebSocket-version license. The connection doesn't touch your WordPress server. ### Does this require a dedicated WordPress hosting upgrade? No — quite the opposite. Sites on shared hosting that struggle under AJAX polling often see no issues after switching to WebSocket because the polling load is eliminated. ### What about message sends — don't those still hit my server? Yes — sending a message and saving it to the database is one request to your server. But that's ONE request per message, not 20 polling requests per minute per user. Net load is much lower. ### Does WebSocket bypass my caching layer? The WebSocket connection itself talks to the cloud relay, not your origin. Caching layers (Cloudflare, Varnish) aren't involved. Your WordPress origin gets only the message-send and history-load traffic, both cacheable in different ways. ### Will my hosting provider complain? Most hosting providers prefer the WebSocket version because it reduces requests against your shared hosting. If yours objects to the WebSocket connections specifically (rare), they're not really objecting to your hosting — they're objecting to the cloud relay traffic, which doesn't impact your hosting at all. ## See also - [No limits](/docs/websocket/no-limits/) — unlimited concurrent users on the relay - [Servers location](/docs/websocket/servers-location/) — where the relay is hosted - [Real-time messaging](/docs/features/realtime-messaging/) — AJAX vs WebSocket comparison - [Instant delivery](/docs/websocket/instant-delivery/) — why messages arrive faster too --- ## Sent / Delivered / Seen Status in WordPress Chat # Message Status (Sent / Delivered / Seen) The WebSocket version shows **real-time message status indicators** on every message — the WhatsApp / iMessage pattern that confirms whether your message was sent, delivered to the recipient's device, or seen by the recipient. Status updates appear instantly thanks to WebSocket push. :::info WebSocket version Real-time status indicators require the persistent WebSocket connection. The free version doesn't show delivery / seen states. ::: ## What it adds - Status indicator on every message you send - Three states: Sent, Delivered, Seen - Real-time updates — status changes appear instantly to the sender - Works in private and group conversations (group shows "seen by X" when applicable) - Visual icons familiar to users of major messaging apps - No configuration needed — automatic with WebSocket ## Status meanings | State | Icon (typical) | Meaning | |---|---|---| | **Sent** | ✓ (single check) | Message reached your server and is queued for the recipient | | **Delivered** | ✓✓ (double check) | Recipient's device has received the message | | **Seen** | ✓✓ (blue / colored) | Recipient has actively viewed the message in the conversation | In group conversations, "Delivered" means at least one other participant has received it; "Seen" indicates the read state per-participant. ## How it works When you send a message, the cycle is: 1. **Sent** — message reaches your WordPress server, status becomes Sent 2. **Delivered** — recipient's browser receives the message via WebSocket, sends an ACK back, status becomes Delivered 3. **Seen** — recipient opens the conversation and the message appears in their viewport for at least 1 second; their browser sends a read receipt, status becomes Seen The WebSocket connection makes these state transitions feel instant — typically < 1 second between Sent and Delivered for online recipients. ## When status indicators are useful | Use case | Why status matters | |---|---| | Sales / customer chat | Know when the prospect saw the offer | | Coaching / consulting | Confirm important messages were read | | Time-sensitive communications | Decide whether to follow up via another channel | | Group decisions | See who's read the announcement | | Marketplace order chat | Track buyer-vendor message engagement | ## Privacy considerations Read-receipt suppression is not exposed as a built-in setting today. Sites that need a per-user opt-out can wire one through a custom user-meta toggle and override the relevant React component via the plugin override pattern. ## Frequently asked questions ### Can users disable showing "Seen" status? Not in the default UI today. The setting is global — read receipts are either on or off site-wide. ### What about offline recipients? For offline recipients (browser closed), status stays at "Sent" until they open the conversation, then jumps to "Seen" (skipping Delivered) once their browser confirms. ### Does delivery / seen status work in chat rooms? Yes — chat rooms show participant read receipts. Useful for moderators verifying that critical announcements were seen. ### How fast do status updates appear? Typically < 200 ms after the underlying event. Faster than users can blink. ### Do AI bot messages have status? The bot's message gets the standard status. Your message to the bot gets "Seen" almost immediately (the bot reads it). ## See also - [Typing indicator](/docs/websocket/typing-indicator/) — see when someone is composing a reply - [Presence indicator](/docs/websocket/presence-indicator/) — online / away / DnD status - [Instant delivery](/docs/websocket/instant-delivery/) — why status updates are real-time - [Web push notifications](/docs/websocket/web-push/) — when status updates trigger off-site notifications --- ## Where Are Better Messages Messages Stored? — Database & Relay # Where are my messages stored? Better Messages stores every message body in **your own WordPress database** — the WebSocket cloud relay does not persist message content of any kind. The WebSocket servers act as transitional relays only: they route message payloads between participants in real time and store the minimum metadata needed to deliver them. Message content is encrypted in transit and the relay cannot read it — we couldn't read your messages even if we wanted to. ## What the WebSocket servers DO store * User IDs * Thread IDs * Message IDs * Unread message count per thread * Delivery status per message * Licensed website domains (e.g. `your-site.com`) ## What the WebSocket servers DO NOT store Anything else. No message bodies, no file content, and no user profile data. For sites with strict data-sovereignty requirements (GDPR Article 9, HIPAA-adjacent, jurisdictional rules), consider the [Self-Hosted plan](/docs/pricing/#self-hosted) — the relay runs on infrastructure you control. ## See also - [Privacy & GDPR](/docs/features/privacy-gdpr/) — full data-flow picture - [End-to-end encryption](/docs/websocket/e2e-encryption/) — opt-in per-thread E2EE - [Servers location](/docs/websocket/servers-location/) — where the cloud relay runs - [Pricing](/docs/pricing/) — including the self-hosted plan --- ## Facebook-Style Mini Chat Popups for WordPress # Mini Chats **Facebook Messenger-style chat popups** anchored to the bottom of the screen. Users open conversations from the mini threads list or notifications, and a compact chat window appears. Multiple windows can be open at once. Combined Mode lets the chat slide into the mini widget panel itself; Bubble Chat Heads keep recently closed conversations one click away. ## How it works Similar to Facebook Messenger's chat popups, mini chats provide a convenient way to have conversations without navigating to the main messaging page. When a user opens a conversation from the mini threads list or clicks on a notification, a compact chat window appears at the bottom of the screen. Multiple mini chat windows can be open simultaneously, allowing users to manage several conversations at once while browsing your site. ## Key capabilities - Compact chat windows anchored to the bottom of the screen - Multiple simultaneous chat windows - Real-time messaging without leaving the current page - Open from mini threads list or notifications - Full messaging features in a compact interface - Combined Mode — open chats inside the mini widget panel instead of as separate windows - Bubble Chat Heads — show recently closed conversations as avatar bubbles for quick re-opening - Smooth slide animations between conversation list and open chat (in Combined Mode) - Smooth minimize/maximize animations for chat windows :::note Mini Chats require the WebSocket version for real-time functionality. ::: ## Combined Mode When **Combined Mode** is enabled, opening a conversation displays it inside the mini widget panel itself instead of opening a separate floating window. The panel slides smoothly between the conversation list and the open chat: - Click a conversation → the chat slides in from the right - Press the back button → the conversation list slides back into view - Press the close (×) button → closes the chat and the panel Combined Mode works with both Classic Bar and Floating Bubble display styles. ## Bubble Chat Heads When using the **Floating Bubble** display style, you can enable **Bubble Chat Heads** — a feature that shows recently closed conversations as small circular avatar bubbles stacked above the main floating bubble button. This makes it easy to quickly jump back into recent conversations. ### How it works - After closing a mini chat, its avatar appears as a chat head bubble above the main bubble - Hovering a chat head shows a tooltip with the conversation name, time, and last message preview - Clicking a chat head reopens that conversation - Each chat head has a dismiss (×) button that appears on hover - Group conversations show a grid of participant avatars - Unread message counts appear as a red badge on each head - The number of chat heads shown is configurable (1–10, default 5) - Chat heads persist across page reloads via IndexedDB ## How to enable Navigate to **WP Admin** → **Better Messages** → **Settings** → **Mini Widgets**. - **Mini Chats** — Turn on popup chat windows - **Combined Mode** — Open chats inside the mini widget panel instead of separate windows - **Bubble Chat Heads** — Show recently closed conversations as avatar bubbles (requires Floating Bubble display style) - **Chat Heads Limit** — Maximum number of chat head bubbles to display ## Frequently asked questions ### How many mini chats can be open at once? There's no hard cap. Practical limit is what fits on screen — typically 3-5 windows on a desktop. The plugin auto-stacks them and lets users minimize / close individual windows. ### Does Combined Mode work with the Floating Bubble? Yes — both display styles (Classic Bar and Floating Bubble) support Combined Mode. The chat slides into the active panel rather than opening a separate window. ### Do mini chats persist across page reloads? Open mini chats reopen on the next page load if the user hasn't closed them. Combined with Bubble Chat Heads, recently closed chats also persist as bubble avatars (stored in IndexedDB). ### Can administrators force-close a user's mini chats? No — mini chat open state is per-user, stored client-side. Admins control whether the feature is available at all but not individual users' open windows. ### Are voice / video call buttons available in mini chats? Yes — see [Group Video Chat → Mini chat buttons](/docs/websocket/group-video-chat/) for the per-button toggles. 1-on-1 audio and video call buttons are also in mini chat headers when calls are enabled. ## See also - [Mini threads list](/docs/websocket/mini-threads/) — where users open mini chats from - [Mini widgets overview](/docs/features/mini-widgets/) — all widget types - [Video calls](/docs/websocket/video-calls/) — accessible from mini chat headers - [Floating chat / mini chats blog post](/blog/floating-chat-mini-chats-wordpress/) — feature deep-dive - [WordPress chat widget blog post](/blog/wordpress-chat-widget-mini-widgets/) — broader widgets overview --- ## Mini Threads List Widget # Mini Threads List The WebSocket version's **Mini Threads** is a compact conversation-list widget fixed to the bottom of every page. Users see their recent threads with live unread counts, and clicking opens a mini-chat popup without leaving the current page. Persistent across the site — your inbox follows you everywhere. :::info WebSocket version Real-time unread updates require the persistent WebSocket connection. The free version's Conversations mini-widget shows a static count refreshed on page load. ::: ## What it adds - Compact conversation list at the bottom of every page - Recent conversations with **live unread counts** updated in real-time - Click any thread to open it as a **mini-chat popup** (no page navigation) - New messages reorder the list automatically (busiest threads to the top) - Role-based visibility restrictions - Persistent presence across all site pages — your messenger is always one click away ## How it works The Mini Threads widget loads on page render and subscribes to the WebSocket events for the user's conversations. As messages arrive: | Event | Outcome | |---|---| | New message in a thread | Thread moves to the top of the list | | Unread count increments | Badge updates instantly | | User opens the thread | Unread count clears | | User reads on another tab | Read state syncs across tabs (cross-tab BroadcastChannel) | | Page navigation | Widget state persists; doesn't reload | The widget behaves like the bottom-of-screen messenger panels in Facebook and Slack — always accessible, never modal. ## When to enable | Site profile | Mini Threads is useful | |---|---| | Community / social network | Members message frequently — easy access matters | | Marketplace | Buyer-vendor messaging is a primary action | | LMS / training | Students message peers and instructors throughout the day | | Support / sales | Reps need to see incoming messages while on other pages | | Personal-use site | One-on-one with friends; persistent inbox keeps it natural | ## How to enable Navigate to **WP Admin → Better Messages → Settings → Mini Widgets**. - **Enable Mini Threads** — Show the conversation list widget - **Restrict by Roles** — Hide the widget for specific user roles (e.g., hide for guests) The widget pairs naturally with [Mini Chats](/docs/websocket/mini-chats/) — clicking a thread in Mini Threads opens it as a Mini Chat popup. ## Frequently asked questions ### Can I show only certain conversations in the list? By default, all of the user's conversations are shown, sorted by recency. There is no built-in filter for restricting the list today — override the relevant React component via the plugin override pattern if you need a custom filter. ### How many threads are shown? About 20 most recent by default. The user can scroll for older threads. ### Does the widget consume bandwidth even when idle? Minimal — the WebSocket connection is already open for other features. Mini Threads piggybacks on it. No extra connections, no polling. ### Can I hide the widget on specific pages? Yes — add custom CSS scoped to those pages targeting the mini-threads container, or dequeue the widget script with the `wp_enqueue_scripts` action on the pages where it shouldn't appear. ### What's the difference between Mini Threads and Mini Chats? **Mini Threads** = the conversation list widget (this doc). **Mini Chats** = the popup chat windows that open when you click a thread. They work together: Mini Threads is the launcher, Mini Chats is the active conversation surface. ## See also - [Mini chats (popup windows)](/docs/websocket/mini-chats/) — what opens when clicking a thread - [Mini widgets overview](/docs/features/mini-widgets/) — all 7 widget types - [WordPress chat widget blog post](/blog/wordpress-chat-widget-mini-widgets/) — feature overview - [Floating chat / mini chats blog post](/blog/floating-chat-mini-chats-wordpress/) — UX deep-dive --- ## No User or Message Limits on WebSocket Plan # No Usage Limits The Better Messages WebSocket service has **no caps on concurrent connections, monthly active users, or message volume**. Whether your site has 100 or 100,000 active users, the service works the same way — same pricing, same performance, no throttling, no overage charges, no surprise bills. :::info WebSocket version Flat-rate pricing is one of the most unusual things about the WebSocket version compared to typical SaaS chat services, which usually charge per-connection or per-message. ::: ## What it adds - No limit on concurrent WebSocket connections - No limit on monthly active users - No limit on message volume - No throttling, no rate limiting on the WebSocket service - Equal infrastructure access for every license holder regardless of site size - Predictable flat-rate pricing — your bill doesn't scale with success ## Pricing models compared | Approach | What's included | Pricing model | Typical cost at 10K MAU | |---|---|---|---| | **Better Messages WebSocket** | Messaging, voice / video calls, group calls, Cloud AI (moderation / translation / transcription), web push, mobile apps | Flat per-site license | License is the only cost | | Realtime-as-a-service platforms | WebSocket pub / sub only — calls, AI, push billed separately | Per-connection and / or per-message | Several hundred to thousands per month | | Chat-as-a-service platforms | Messaging only — calls, AI, push usually billed separately | Per monthly active user (MAU) | Hundreds to thousands per month | | Build your own relay | Whatever you build | Your infrastructure + your team | Hosting + dev time + ongoing maintenance | The comparison isn't apples-to-apples — the WebSocket plan bundles call infrastructure, AI services, and push delivery that other approaches charge for separately. On like-for-like infrastructure (messaging + calls + AI + push), the savings widen significantly. For sites with growth ambitions, the flat-rate license is **economically predictable** in a way that per-user or per-connection pricing isn't. ## How it works The Better Messages cloud relay infrastructure scales automatically. New connections are distributed across the relay fleet. There's no per-tenant cap — your site competes with no one for capacity, and the system grows with aggregate platform traffic. If your site experiences a sudden traffic surge (viral post, product launch), the WebSocket service absorbs it without rate limits. Messages continue to flow instantly even at peak load. ## Frequently asked questions ### Are there ANY soft limits I should know about? For pathological cases — a single user sending hundreds of messages per minute (clearly abuse) — there are anti-abuse protections at the application layer. Normal usage doesn't hit them. ### What if my site becomes huge — will pricing change? The WebSocket-version license pricing is the same regardless of site size. Sites with hundreds of thousands of users pay the same as sites with hundreds. ### Does "no limits" include voice/video call participants? The voice/video call participant cap is **50 per audio call** and **32 per video call** by default. This is a per-call media-server limit, not a usage limit. Sites with regular higher-participant needs should discuss the self-hosted plan with support. ### Is there a connection time limit? No — WebSocket connections stay open as long as the browser is open and connected. The infrastructure handles long-lived connections natively. ### What's the SLA? 99.5%+ uptime in practice. The infrastructure runs across multiple regions with automatic failover. See [Servers location](/docs/websocket/servers-location/) for the topology. ## See also - [Load optimization](/docs/websocket/load-optimization/) — minimal WordPress server load - [Servers location](/docs/websocket/servers-location/) — relay geographic distribution - [Users limit](/docs/websocket/users-limit/) — concurrent user details - [Group video chat](/docs/websocket/group-video-chat/) — 32-participant call cap --- ## Online Presence Indicators in WordPress Chat # Presence Indicators & User Statuses The WebSocket version shows **real-time online presence indicators** — colored dots next to user avatars throughout the messenger. Users see at a glance who's online, away, or busy. Each user can set their own availability status. Presence updates push instantly through WebSocket — no polling, no stale state. :::info WebSocket version Presence indicators require the persistent WebSocket connection. The free version cannot show real-time presence. ::: ## What it adds - Colored dot next to every user avatar showing their current status - Three states: Online (green), Away (yellow), Do Not Disturb (red) - Instant status updates across all connected clients via WebSocket - User-selectable availability — set your own status - Visible in conversations, user lists, mini widgets, member directories - No configuration needed — automatic with WebSocket ## Status meanings | Status | Color | Trigger | |---|---|---| | **Online** | 🟢 Green | User actively on the site, browsing or chatting | | **Away** | 🟡 Yellow | User inactive for ~5 minutes (configurable) | | **Do Not Disturb** | 🔴 Red | User manually set themselves as unavailable | | (no dot) | — | User is offline / not connected | ## How it works When a user opens a page with the messenger, their WebSocket connection registers them as Online. As they interact, their status stays Online. After a few minutes of inactivity, the plugin marks them as Away. They can manually set Do Not Disturb to override. | Action | Outcome | |---|---| | User loads page with messenger | Online dot appears on their avatar everywhere | | User stops moving / typing / clicking for 5 minutes | Status changes to Away | | User resumes activity | Status returns to Online | | User selects "Do Not Disturb" from settings | Red dot shown to others | | User closes browser entirely | Dot disappears after a short timeout | Status changes propagate to ALL connected users in real-time — no polling lag. ## Where presence is shown - Conversation headers (next to participant avatars) - Inbox conversation list (next to each thread's other participant) - Mini widgets — Friends, Users, Groups - Member directories (BuddyPress / BuddyBoss / PeepSo / Ultimate Member) - Mentions autocomplete dropdown - Recipient picker when starting a new conversation ## When presence matters most | Use case | Why presence is useful | |---|---| | Customer support | See if a rep is available before starting a chat | | Coaching / consulting | Clients see when the coach is online | | Dating community | Find users who are actively online for real-time conversation | | Marketplace | Buyer sees if vendor is reachable now or later | | Community manager dashboard | See team activity at a glance | ## Frequently asked questions ### Can users hide their presence entirely? Not in the default UI. To add a "Invisible" mode, hook the presence-status filter and don't broadcast the user's connection events. They'd appear offline to others while still using the chat. ### How is "Away" determined? Based on browser activity — mouse movement, key presses, scrolling. After ~5 minutes of no activity, the plugin marks the user Away. ### Does presence respect privacy / multiple sites? Presence is per-site. A user's presence on Site A doesn't leak to Site B. Same user logged into multiple browsers shows Online if any of those is active. ### Does the mobile app show presence? Yes — the native mobile app participates in the same presence system. Active mobile-app users appear Online. When the app is backgrounded, they show Away. ### Can administrators see invisible mode bypassed? No — presence is symmetric. If a user is shown as Online, they ARE online. Admin viewing doesn't reveal a different state. ## See also - [Typing indicator](/docs/websocket/typing-indicator/) — additional real-time activity feedback - [Message status (sent/delivered/seen)](/docs/websocket/message-status/) — message-level state - [Instant delivery](/docs/websocket/instant-delivery/) — same WebSocket connection that powers presence - [Mini widgets](/docs/features/mini-widgets/) — where presence shows in friends / users lists --- ## Priority Support for WebSocket License Holders # Priority Support WebSocket-version license holders receive **priority support** with faster response times. Priority requests are handled before standard support, covering any Better Messages topic — plugin configuration, troubleshooting, integration questions, custom development guidance, and feature requests. :::info WebSocket version Priority support is a license benefit, not a separately-purchased tier. ::: ## What it adds - Faster response times vs standard support - Covers all Better Messages topics — not limited to WebSocket-specific features - Email-based support with direct developer access - Issues triaged by license status - Same support quality across plugin configuration, troubleshooting, and integration questions ## How it works When you contact support with your license key and site URL, your ticket is automatically routed to the priority queue. The developer answers priority tickets first, then standard tickets. Typical response time during business hours is much faster for priority tickets, especially for time-sensitive issues like site-down or upgrade-blocking situations. ## How to contact support **Email:** support@better-messages.com **Include for fastest processing:** - Your WebSocket license key - Site URL (so the developer can verify and inspect) - Clear description of the issue or question - Browser console errors (if applicable) — screenshots help - Steps to reproduce (if reporting a bug) ## Frequently asked questions ### Is there a phone or live-chat support option? Email is the standard channel. For severe issues, mention "urgent" in the subject — the developer prioritizes those. The plugin author is a solo indie developer based in Ukraine; responses come directly from him, not from a tiered support team. ### What's the response SLA? There's no formal SLA. In practice, priority tickets typically get a same-day or next-business-day response. Sites running in production usually report response times in hours, not days. ### Does priority cover custom development? Custom development beyond plugin troubleshooting is out of scope, but the developer can usually point you to the right hook/filter or code pattern. Larger custom integrations are quoted separately. ### What if I have the free version — can I still get support? Yes — free-version users get standard support via the [WordPress.org support forum](https://wordpress.org/support/plugin/bp-better-messages/). The forum is monitored regularly. Priority email support is the WebSocket-version benefit. ### Are there hours of availability? The developer is in Ukraine (UTC+2/+3). Most responses go out during European business hours, but urgent tickets are often answered outside normal hours too. ## See also - [End user license](/docs/websocket/end-user-license/) — what the license covers - [Cancel subscription](/docs/websocket/cancel-subscription/) — for license management - [About Better Messages](/docs/getting-started/about/) — context on the indie developer - [Servers location](/docs/websocket/servers-location/) — for infrastructure-related support questions --- ## AES-256 Encrypted Messaging Through WebSocket # Private — Encrypted in Transit All sensitive message content is **AES-256 encrypted on your WordPress server** before transmission through the WebSocket infrastructure. The relay server only handles encrypted data and cannot read message content. Decryption happens in the authorized user's browser using keys only available to the conversation's participants. :::info WebSocket version This is a WebSocket-version feature. The free version uses AJAX polling against your own WordPress server, so no third-party relay is involved. ::: ## What it adds - AES-256 encryption of all message content on your WordPress server before send - WebSocket relay server cannot decrypt or read messages - Decryption only in the authorized recipient's browser - No plaintext message data ever leaves your server - Identical encryption applied to private DMs, group chats, and chat rooms - Same protection covers attachments, voice messages, and other content payloads ## How it works When a user sends a message, your WordPress server encrypts the content with AES-256 using a per-conversation key before pushing it to the WebSocket relay. The relay then forwards the encrypted payload to all conversation participants' open connections. Each participant's browser decrypts using the same per-conversation key, retrieved securely from your server. | Stage | What's visible | |---|---| | Sender's browser → your server | Plaintext over HTTPS | | Your server encrypts → relay | Encrypted ciphertext only | | Relay → recipient's browser | Encrypted ciphertext only | | Recipient decrypts | Plaintext locally | The relay's role is purely to **route encrypted bytes** between participants — it has no key, no inspection capability, no ability to comprehend what it's forwarding. ## Frequently asked questions ### Is this the same as end-to-end encryption? No — this is **transit encryption**. The WordPress server has the key. For true end-to-end encryption (where only the participants — not even your server — can decrypt), use the optional [end-to-end encryption (E2EE)](/docs/websocket/e2e-encryption/) per-thread feature. ### Does this require any setup? No — encryption is automatic on the WebSocket version. There's no key management, no user-facing setup. ### Does this apply to file attachments? File attachments are stored on your server. Their URLs are encrypted in the message payload but the files themselves are accessed via your WordPress media library security model. ### Are voice / video call streams encrypted? Yes — WebRTC uses DTLS/SRTP encryption for all media streams. See [Secure](/docs/websocket/secure/) for the connection-layer details. ### Can attackers intercept messages over the WebSocket? The WebSocket connection is itself TLS-encrypted (WSS). Even before AES-256 content encryption, the transport layer is secure. Combined, an attacker would need to break BOTH TLS AND AES-256 — neither is feasible with current technology. ## See also - [End-to-end encryption (E2EE)](/docs/websocket/e2e-encryption/) — optional per-thread true end-to-end encryption - [Secure (WSS)](/docs/websocket/secure/) — transport-layer security - [Local browser encryption](/docs/websocket/browser-encryption/) — encrypt cached data on the user's device - [Your data is yours](/docs/websocket/your-data/) — what's stored where - [Privacy & GDPR](/docs/features/privacy-gdpr/) — full privacy picture --- ## Better Messages WebSocket Refund Policy — 7-Day Money-Back Guarantee # Refund Policy We stand behind our plugin’s quality and your satisfaction with it is important to us. If you experience problems with the plugin, we will be happy to provide a full refund within 7 days of the original upgrade date. Refunds will be offered at our sole discretion and must meet all of the following conditions fully: * You are within the first 7 days of the purchase of the plugin. * Your issue(s) derives from not being able to install the plugin properly or get the plugin to perform its basic functions. * You have attempted to resolve your issue(s) with our support team by opening a support ticket through the “Contact Us” in the plugin’s admin settings. * No refunds will be granted after the first 7 days of the original purchase whatsoever. * Refunds will not be granted for missing feature(s). If you are not sure we support a specific feature, please contact us first. * Issues caused by conflicts with 3rd party plugins, themes or other software will not provide grounds for a refund. * Refunds will not be granted if you simply decide not to use the plugin. * By upgrading, you agree to this refund policy and relinquish any rights to subject it to any questions, judgment or legal actions. To submit a refund request, please open a refund [support ticket](mailto:support@better-messages.com). --- ## How to Reset a Better Messages License — Move to a New Domain # How to reset the license? When you want to change the licensed domain name, but old website is already deleted, you might need to reset your license. You can do it at your customer account dashboard, which you can find at that link: https://users.freemius.com/ As the login you should use the email which were used, when you bought the plugin. If you do not know the password, just recover it. After you logged in to your customer account dashboard, navigate to Licenses, find the license which you want to deactivate and press Deactivate button. Freemius license After that you will be able to activate this license at your new domain. --- ## Screen Sharing in WordPress Chat Calls # Screen Sharing The WebSocket version supports **screen sharing during any call** — 1-on-1 audio, 1-on-1 video, group audio, group video. Share your entire screen or just one application window with other participants. WebRTC-based, no browser plugins required, works in all modern desktop browsers. :::info WebSocket version Screen sharing is a WebSocket-version feature, only available during an active call. ::: ## What it adds - Share entire screen or specific application window during a call - Available in **all call types** — 1-on-1 audio/video and group audio/video - WebRTC-based — no extension or browser plugin needed - Other participants see the shared screen as a high-quality video feed - Switch between screen sharing and camera during a call - Audio sharing optional (share system audio along with the screen) ## How it works When a user clicks **Share Screen** during an active call, the browser shows the standard screen-share permission prompt — they choose what to share: | Sharing option | What participants see | |---|---| | **Entire screen** | Everything on the chosen monitor | | **Application window** | Just one app (Slack, browser, IDE, etc.) | | **Browser tab** | Just one tab — privacy-respectful for browser-based demos | The shared content streams to other participants via WebRTC. The user's camera feed pauses (replaced by the screen feed) but voice continues unchanged. ## When screen sharing is essential | Use case | Pattern | |---|---| | Customer support troubleshooting | "Show me what you're seeing" — visual debugging | | Coaching / consulting | Walk through documents, designs, code on screen | | Sales demo | Show the product working live during a call | | LMS office hours | Instructor shares slides or code editor for explanation | | Marketplace vendor support | Vendor walks buyer through product setup | ## Requirements - Website must use **HTTPS** (browsers require secure context for screen capture) - Supported on desktop browsers — Chrome, Firefox, Edge, Safari - Initiated from inside an active call (audio, video, group) - Browser screen-share permission granted by the user Mobile browsers don't support screen sharing (a browser limitation). Mobile-app users can view shared screens but can't share their own. ## Frequently asked questions ### Does screen sharing work on mobile? Receivers (viewing a shared screen) — yes, works fine. Sharers — no, mobile browsers don't expose the screen-capture API. The native iOS / Android app may support sharing in future versions. ### Can multiple participants share at once? Typically one sharer at a time. The new sharer replaces the current one. Group conversations support sequential sharing, not simultaneous. ### Is the shared screen recorded? No — screen-share streams are real-time only. Better Messages doesn't include screen recording. To record, participants use their own recording tools (with consent). ### What about audio from the shared application? Optional — the browser asks whether to share system audio along with the screen. If you say yes, the audio from the shared app/tab is streamed too. Useful for sharing videos with sound. ### Does screen sharing work in group calls with many participants? Yes — the shared screen flows through the media server (SFU) like any other video stream. Quality scales — participants on slower connections get a lower-resolution version automatically. ## See also - [Video calls (1-on-1)](/docs/websocket/video-calls/) — primary context for screen sharing - [Audio calls (1-on-1)](/docs/websocket/audio-calls/) — voice + screen, no video - [Group video chat](/docs/websocket/group-video-chat/) — share screen with up to 32 - [Group audio chat](/docs/websocket/group-audio-chat/) — voice group + screen sharing - [Mini chats](/docs/websocket/mini-chats/) — calls embedded in mini popups --- ## WSS / TLS Secure WebSocket Connection # Secure WebSocket Connection The WebSocket version uses **WSS (WebSocket Secure) over TLS/SSL** for every connection. Authentication tokens are generated server-side and validated on each connection, so only authorized users can subscribe to messaging channels. The WebSocket relay only forwards encrypted event data — it never has access to decrypted message content. :::info WebSocket version This is a transport-layer security feature. The free version doesn't use WebSocket; AJAX runs over your own site's HTTPS. ::: ## What it adds - WSS encryption for all WebSocket connections (TLS 1.2+ / 1.3) - Server-side authentication tokens validated on every connection - Unauthorized connection attempts rejected with detailed error codes - Message content **AES-256 encrypted** before transmission (see [Private](/docs/websocket/private/)) - WebSocket relay cannot read message content or metadata - Fresh authentication handshake on every reconnection (post-network-drop) ## How it works When a user opens a page with the messenger, the JavaScript client requests an authentication token from your WordPress server. The server validates the user's WordPress session, generates a short-lived signed token, and returns it. The client then opens a WSS connection to the cloud relay, passing the token. The relay verifies the token's signature and grants access. | Step | Security guarantee | |---|---| | WordPress auth (cookie) | Standard WordPress session security | | Token generation on your server | Token is signed; only your server can mint valid tokens | | WSS handshake to the relay | TLS encryption of the connection setup | | Token validation by relay | Cryptographically verifies the user has WordPress access | | Message routing | Only encrypted ciphertext forwarded between participants | | Reconnect after network drop | Fresh token re-issued by your server | ## Defense layers | Layer | Threat protected against | |---|---| | WSS (TLS) | Network eavesdropping, man-in-the-middle attacks | | Signed token | Unauthorized users impersonating others | | Token expiration | Stolen tokens become useless quickly | | Per-channel ACL | Users can only subscribe to channels they belong to | | AES-256 content encryption | Relay-level data breach can't reveal message content | ## Frequently asked questions ### What TLS version is used? TLS 1.2 minimum, with TLS 1.3 negotiated when both client and server support it (modern browsers all do). Cipher suites use modern algorithms (AEAD, forward secrecy). ### How long are authentication tokens valid? Short-lived — typically 1 hour. The client transparently refreshes them before expiry, so users never see a re-authentication prompt. ### Can a user subscribe to another user's private channel by guessing the channel ID? No — channels are guarded by signed token claims. Even if a user knows the channel ID, the relay only accepts subscriptions for channels included in the user's token claims. The server only mints tokens with channels the user is actually a participant in. ### What happens if my WordPress site uses HTTP (not HTTPS)? The WebSocket version requires HTTPS on your WordPress site. WSS-to-mixed-content rules in browsers would block the connection otherwise. WSS is hard-required. ### Is this enough to claim PCI compliance / HIPAA compliance? Transport encryption is necessary but not sufficient. For PCI / HIPAA, also consider [end-to-end encryption](/docs/websocket/e2e-encryption/), the self-hosted plan, message retention policies, and access controls. Discuss specific compliance requirements with support. ## See also - [Private (AES-256)](/docs/websocket/private/) — content encryption - [End-to-end encryption (E2EE)](/docs/websocket/e2e-encryption/) — optional per-thread true E2EE - [Local browser encryption](/docs/websocket/browser-encryption/) — encrypt the cache on user's device - [Your data is yours](/docs/websocket/your-data/) — what's stored where - [Privacy & GDPR](/docs/features/privacy-gdpr/) — full privacy posture --- ## Where Are the Better Messages WebSocket Servers Located? # Where are the WebSocket servers located? The Better Messages WebSocket cloud relay currently runs in **Frankfurt, Germany**. The relay is blind to message content (all message data is stored only in your WordPress database — see [where messages are stored](/docs/websocket/message-storage/)), so the relay location doesn't dictate where your data lives. But if your site has strict geographical or jurisdictional rules about which servers user data may transit, the [Self-Hosted plan](/docs/pricing/#self-hosted) lets you run the relay on infrastructure you control. ## See also - [Where messages are stored](/docs/websocket/message-storage/) - [Privacy & GDPR](/docs/features/privacy-gdpr/) - [Self-hosted plan pricing](/docs/pricing/#self-hosted) --- ## Typing & Activity Indicators in WordPress Chat # Typing & Activity Indicators The WebSocket version shows **real-time activity indicators** when a conversation participant is doing something — typing a message, recording a voice message, or uploading a file. Each activity has its own distinct icon. The indicator appears instantly and disappears when the activity ends. The "is typing…" pattern that defines modern chat apps, built into Better Messages. :::info WebSocket version Activity indicators require the persistent WebSocket connection. The free version doesn't show real-time typing state. ::: ## What it adds - "Is typing…" indicator when someone is composing a text message - "Is recording…" indicator when someone is recording a voice message - "Is uploading…" indicator when someone is uploading a file attachment - Distinct icons for each activity type - Real-time via WebSocket — sub-200 ms latency - Works in DMs, group chats, and chat rooms - Appears in conversation header AND inline above the input ## How it works When a user starts typing, their browser fires a "typing started" event through the WebSocket. The cloud relay forwards this to all conversation participants. Their UI shows the indicator. When the user stops typing for a couple seconds or sends the message, a "typing stopped" event fires, and the indicator disappears. | User action | Indicator shown to others | |---|---| | Starts typing in input | "is typing…" with pen icon | | Pauses typing > 3 seconds | Indicator disappears | | Starts recording voice | "is recording…" with microphone icon | | Cancels recording | Indicator disappears | | Starts file upload | "is uploading…" with file icon | | Upload completes / cancelled | Indicator disappears | | Sends the message | All indicators disappear; message appears | In group conversations, multiple users can have indicators at once — e.g., "Anna and Mike are typing…". ## When typing indicators matter | Use case | Why it improves the experience | |---|---| | Sales chat | Visitor knows the rep is composing — won't abandon | | Coaching session | Client feels heard while the coach formulates a response | | Group chat | Avoids interruptions — wait for the typing person to finish | | Customer support | Sets expectations — "the agent is responding now" | | Dating | Adds liveness to the conversation flow | ## Privacy considerations Per-user typing-broadcast opt-out is not exposed as a built-in setting today. The indicator is either on or off site-wide. Sites that need a per-user opt-out can wire one through a custom user-meta toggle plus a React component override. ## Frequently asked questions ### Does the indicator stay forever if I stop typing without clearing the input? After ~3 seconds of no typing, the indicator auto-clears. The threshold is configurable. ### Can users disable seeing typing indicators? Not in the default UI. To add a per-user toggle, hook the user-settings panel and use the appropriate filter. ### Are typing indicators shown for AI bots? Yes — when an AI bot is generating a response, it shows "AI is typing…". Useful for letting users know to wait. ### What about offline users? Do they see I was typing? No — typing events are real-time only. A user who comes online later sees only the final sent message, not the typing history. ### Does typing indicator work in voice / video calls? Calls have their own real-time medium (live audio/video). Typing in the chat alongside an active call works normally — the typing indicator displays in the chat panel. ## See also - [Presence indicator](/docs/websocket/presence-indicator/) — online / away / busy status - [Message status (sent/delivered/seen)](/docs/websocket/message-status/) — per-message state - [Instant delivery](/docs/websocket/instant-delivery/) — why typing updates are real-time - [Voice messages](/docs/addons/voice-messages/) — async voice (the "is recording…" indicator targets this) - [File sharing](/docs/features/file-sharing/) — file attachments (the "is uploading…" indicator targets this) --- ## Is There a User Limit on Better Messages WebSocket? # Is there a user limit on the WebSocket version? No. WebSocket connections, active users, messages, and threads are **not limited** on the standard subscription. A site with 100 active users pays the same as one with 100,000. See [no limits on connections or volume](/docs/websocket/no-limits/) for the full breakdown and [pricing](/docs/pricing/) for the current flat-rate plans. --- ## One-on-One HD Video Calls in WordPress Chat # HD Video Calls Video Calls The WebSocket version enables **HD 1-on-1 video calls** between users using WebRTC technology. Initiate from any conversation; quality is high (720p+ on capable networks), latency is low, and screen sharing is available during the call. :::info WebSocket version Video calls are a WebSocket-version feature. For multi-party video, see [group video chat](/docs/websocket/group-video-chat/) (up to 32 participants). ::: ## What it adds - 1-on-1 HD video calls between any two users in any conversation - WebRTC peer-to-peer streaming — media travels directly between participants when possible - Low latency, high-quality video (adaptive 720p+) and audio (Opus codec) - Screen sharing available during the call - Initiate calls with one click from the conversation header - Works in all modern browsers (Chrome, Firefox, Edge, Safari, mobile equivalents) - Built-in call UI with mute, camera toggle, hang up, and timer ## How it works When a user clicks the **Video Call** button: 1. The WebSocket relay carries SDP and ICE signaling between the two browsers 2. The browsers negotiate codecs and establish a direct WebRTC peer connection 3. Video and audio streams flow peer-to-peer between the participants 4. If direct P2P fails (corporate firewall, symmetric NAT), a TURN relay forwards the encrypted streams | Network scenario | What happens | |---|---| | Normal home/office network | Direct peer-to-peer; minimal latency | | One participant behind a strict firewall | TURN relay forwards encrypted media | | Both behind corporate proxies | TURN relay (slight added latency) | All media is **DTLS-SRTP encrypted** between participants even when relayed. ## When 1-on-1 video calls fit | Use case | Pattern | |---|---| | Coaching session | Coach-client face-to-face session in the existing thread | | Customer support escalation | Video helps when explaining visual problems | | Marketplace high-value deals | Buyer wants to see the product / vendor in person | | Telemedicine consultation | Practitioner-patient with optional screen-share for charts/notes | | Sales / consulting demo | Demo a product with screen-share during the call | | Dating community | Video call as a verification / connection step | ## Requirements - Website must use **HTTPS** (browsers require secure context for camera + microphone) - Each participant needs a working webcam + microphone - Modern browser with WebRTC support - WebSocket-version license ## Frequently asked questions ### Why does the call fail on HTTP sites? Browsers block camera and microphone access on non-HTTPS pages — a security requirement. There's no workaround; HTTPS is mandatory. ### Can I restrict who can place video calls? Yes — **WP Admin → Better Messages → Settings → Calls** has per-role permissions. Common pattern: paid members can call, free members can't. ### What if the recipient is offline? The caller sees a "user offline" notice. Better Messages doesn't queue ringing for offline users. ### Are calls recorded? No — calls are real-time only. Better Messages doesn't include built-in recording. Participants can use their own screen-recording tools (with consent). ### Does video quality adapt to poor networks? Yes — WebRTC adapts bitrate and resolution automatically based on bandwidth. Even on cellular, calls remain usable. For very poor connections, the video may downgrade to audio-only briefly. ### Does the mobile app support video calls? Yes — both the web (mobile browser) and the native iOS/Android app support video calls. ## See also - [Audio calls (1-on-1)](/docs/websocket/audio-calls/) — voice-only equivalent - [Group video chat](/docs/websocket/group-video-chat/) — multi-party (up to 32) - [Group audio chat](/docs/websocket/group-audio-chat/) — multi-party voice (up to 50) - [Screen sharing](/docs/websocket/screen-sharing/) — during video calls - [WordPress video call plugin blog post](/blog/wordpress-video-call-plugin/) — feature overview --- ## Web Push Notifications for WordPress Chat # Web Push Notifications The WebSocket version delivers **browser-native push notifications** for new messages and incoming calls — reaching users even when they've closed your tab or moved to another website. Push works across Chrome, Firefox, Edge, and other modern browsers that support the Web Push API, on both desktop and mobile. :::info WebSocket version Web push is a WebSocket-version feature. The free version does not include push delivery — users only receive notifications while they have the site open and the tab is active. ::: ## What it adds - Native browser push for **new messages** and **incoming calls** - Reaches users while they are on other sites, on other tabs, or have the browser minimized - One-time opt-in through the browser's permission prompt — no Better Messages account or third-party app required - Clicking the notification opens the relevant conversation in a new tab - Works on desktop (Chrome, Firefox, Edge, Brave, Opera) and Android browsers - Independent from the mobile-app push channel — both can be active at once ## How it works When a user is signed in and grants browser push permission, the browser registers a push subscription with the device's push service (Apple Push Notification service for Safari/macOS, Firebase Cloud Messaging for Chrome/Android, Mozilla's autopush for Firefox). Better Messages stores the subscription against the user's account. When a new message or incoming call arrives via the WebSocket relay, the plugin checks whether the recipient is currently active on the site: | Recipient state | What happens | |---|---| | Tab open, page focused | In-app notification + sound only (no push) | | Tab open, page unfocused | Web push fires | | Browser closed entirely | Web push fires (delivered when browser opens) | | Site never opened in this browser | No push subscription, falls back to email notification | Click handling is built in — tapping the push notification opens the conversation directly. Notifications include the sender's name and a message preview that respects the recipient's privacy settings. ## When users benefit most | Scenario | Why web push matters | |---|---| | Community managers replying to support DMs | Stay reachable without keeping the site tab open all day | | Marketplace vendors waiting on buyer questions | Pre-purchase questions don't get missed | | LMS instructor office hours | Students can ping the instructor; instructor is notified immediately | | Dating / fan communities | Real-time reach to users who only check the site occasionally | ## How to enable Web push is automatically available with the WebSocket version — there's no admin setting to flip. Users are prompted by their browser to allow notifications the first time they enter a conversation. They can manage the permission anytime through the browser's site settings, or via their account preferences inside Better Messages. For the cleanest user experience, the plugin only triggers the browser permission prompt at a meaningful moment (when the user has just opened a thread), not on first visit. This dramatically improves opt-in rates compared to prompting on landing. ## Frequently asked questions ### Does web push work on iPhone Safari? Web push for iOS Safari requires the user to **install the site as a Home Screen PWA** first (iOS 16.4+). For most iOS users, mobile-app push via OneSignal or the native iOS app is more reliable. Desktop Safari (macOS) supports web push directly. ### What happens if a user denies the browser permission prompt? They will not receive web push notifications. They still receive in-site notifications (badge, sound) when active, and email notifications when away — both fall back gracefully. They can re-enable push from browser site settings later. ### Does web push share data with third parties? The push service (Apple, Google, Mozilla) handles the delivery infrastructure but cannot read message content — the payload sent through the push service is encrypted in-transit and Better Messages controls the content. No third-party analytics or tracking is added. ### How does web push interact with the mobile app's push? Independently. A user with both the mobile app installed AND web push enabled will receive notifications in both channels for the same event. Most users disable one or the other manually in practice. There's no built-in coordination. ### Are notification previews configurable? Yes — the **Privacy Settings** under WP Admin → Better Messages → Settings → Notifications let you choose whether the message body appears in the notification or only the sender's name. Sites with sensitive content typically choose "sender only". ## See also - [Mobile app push notifications](/docs/category/mobile-app/) — native iOS/Android push - [OneSignal integration](/blog/onesignal-push-notifications-better-messages/) — multi-channel push provider - [Progressify PWA integration](/blog/progressify-pwa-push-notifications/) — PWA push for iOS Safari - [Email notifications](/docs/features/email-notifications/) — fallback when neither push channel is available --- ## Better Messages on WordPress Multisite — Subfolder & Subdomain # WordPress Multisite ## Subfolder Networks Subfolder network can use 1 plugin license per network. Plugin must be activated network wide and license should be activated at primary website: Subfolder network ## Subdomain Networks One license work only with 1 WP Multisite subdomain website instance. Why a license activation on a multisite network isn’t considered as a single activation? Multisite networks are way more complex than standard WordPress installations, have significantly more edge cases, and a higher chance for conflicts as subsites in the network can run different combinations of plugins and themes. Also, multisite-networks are largely used by bigger entities like agencies, boutique hosting providers, and WaaS, who generate revenue from their networks and, therefore, have higher load to us . Consequently, it’s only fair to charge them more for protecting each WPMU website instance. --- ## Your Chat Data Stays in Your WordPress DB # Your Data Is Yours Better Messages **stores all messaging data exclusively in your WordPress database**. The WebSocket relay only routes encrypted events to facilitate real-time delivery — no message content, no user data, no conversation history is retained on the relay infrastructure. You maintain full ownership and control of every byte. :::info WebSocket version Data ownership is preserved even when using the WebSocket-version cloud relay. The cloud is a router, not a database. ::: ## What it adds - All messages stored in your WordPress database only — no external data store - No message content ever stored on WebSocket servers - Only encrypted routing data (user IDs, thread IDs, delivery statuses) temporarily processed - Zero retention on relay infrastructure — events are forwarded then discarded - Full data portability — export, backup, migrate via standard WordPress tools - GDPR data sovereignty compliance built-in ## Data location matrix | Data type | Location | |---|---| | Message content (text, formatting) | Your WordPress database (`bm_messages` table) | | Attachments / files | Your WordPress media library (uploads folder) | | User profiles | Your WordPress `wp_users` + custom fields | | Conversation metadata (participants, subjects, timestamps) | Your WordPress database | | Reactions, mentions, pinned messages | Your WordPress database | | Read receipts, delivery statuses | Your WordPress database | | **Routing data on relay** | **Transient memory only — discarded after forwarding** | | **AI bot conversation content** | Routed through AI provider (OpenAI / Anthropic / Google) per their terms | ## How it works When a message is sent: 1. Browser → your WordPress server: the message text and metadata 2. Your server: stores the message in the database, then encrypts a routing payload 3. Your server → WebSocket relay: pushes the encrypted payload with routing info (user IDs, thread ID) 4. Relay → all participants' browsers: forwards the encrypted payload 5. Relay: discards the payload after forwarding — no retention 6. Recipient browsers: decrypt and render the message The relay is **stateless** for message content — it has no persistent storage of what flows through it. ## When data ownership matters most | Use case | Why it matters | |---|---| | GDPR / DSAR requests | You can export and erase data without involving third parties | | Site migration | Standard WordPress backup/restore preserves all chat history | | Compliance audits | Single point of data residence is auditable | | Self-hosted requirements | Combine with the [self-hosted plan](/docs/pricing/#self-hosted) for full sovereignty | | Data residency rules | Data stays in your hosting's region (the relay routes ephemeral packets only) | ## Frequently asked questions ### What if the WebSocket relay is breached? A breach of the relay would expose only currently-in-transit encrypted packets (which would still need AES-256 to decrypt) and routing metadata (user IDs, thread IDs). Historical messages, profiles, and attachments are not at risk — they're on your server. ### Can I migrate away from Better Messages and keep my data? Yes — all data is in standard WordPress tables. Export via WordPress's built-in tools or directly from the database. The plugin doesn't lock you in. ### What about voice / video calls? Call metadata (participants, duration, started time) is stored in your WordPress database. The actual audio/video streams flow peer-to-peer (for 1-on-1) or through the media server (for groups) — never stored anywhere. ### Does AI bot content stay in my database? The AI conversation itself (user message + bot response) is stored in your database like any conversation. But the user's message is also sent to the AI provider's API (OpenAI / Anthropic / Google) to generate the response — that's a one-time transit, subject to the AI provider's terms. ### How does the self-hosted plan differ? The self-hosted plan moves the WebSocket relay onto infrastructure you control. The data ownership pattern is the same (data stays in your DB), but the relay infrastructure also stays on your servers — useful for very strict data-sovereignty requirements. ## See also - [Privacy & GDPR](/docs/features/privacy-gdpr/) — full privacy posture - [Servers location](/docs/websocket/servers-location/) — where the relay servers run - [Self-hosted plan](/docs/pricing/#self-hosted) — for strict data-sovereignty needs - [Auto-delete messages](/docs/features/auto-delete-messages/) — retention policy - [End-to-end encryption](/docs/websocket/e2e-encryption/) — content-level protection