Skip to content

Message Translation ​

MeshMonitor includes native inline chat message translation for mesh broadcast channels and direct messages. This allows operators and mesh communities across different regions and languages to communicate seamlessly over radio networks.


Overview ​

Message translation in MeshMonitor operates on-demand:

  • Inbound Messages: Hover over any received message in a channel or direct message thread and click the Translate icon to view the translated text inline directly below the message.
  • Outbound Composer: Click the Translate icon in the message compose bar to translate your draft into a destination language before transmitting over the mesh network.
  • Language Switcher: Dynamically change the destination language right on the message card, with choices automatically remembered for future translations.
  • LoRa Packet Awareness: Real-time UTF-8 byte counting warns you if translated text exceeds typical radio packet limits (~200–220 bytes).

Supported Translation Providers ​

MeshMonitor supports four flexible translation backends, catering to cloud APIs, self-hosted open-source software, and completely offline local language models:

ProviderCost / TierHostingSetup ComplexityBest For
DeepL API
(Recommended)
Free (500k chars/mo) or Paid ProCloudEasiestRecommended. Easiest setup. High translation quality. Free developer account requires no payment details.
LibreTranslateFree & Open SourceLocal (Docker) or CloudLowOffline/air-gapped nodes, self-hosted servers, privacy-focused deployments.
OpenAI-CompatibleFree (Local Ollama) or Pay-per-token (OpenAI, OpenRouter, vLLM)Local or CloudLow–MediumFlexible LLM-based translations, local Ollama models (llama3, qwen2.5), or cloud LLMs.
Google Cloud TranslationFree trial / Pay-as-you-goCloudMediumUsers with existing Google Cloud Console infrastructure.

For most users, DeepL API Free provides the best balance of speed, translation accuracy, and ease of setup:

  1. Sign up for a free DeepL API developer account at deepl.com/pro-api (select the DeepL API Free plan).
  2. Copy your Authentication Key from your DeepL account dashboard (Free keys end in :fx, such as xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:fx).
  3. In MeshMonitor, navigate to Settings β†’ Message Translation.
  4. Check Enable Message Translation.
  5. Select DeepL API (Free / Pro) from the Translation Provider dropdown.
  6. Paste your authentication key into the DeepL Auth Key field.
  7. Leave Custom DeepL Base URL blank.
  8. Click Test Connection to verify connectivity.
  9. Click Save Changes in the bottom save bar.

Automatic Endpoint Detection

MeshMonitor automatically detects whether your DeepL key is Free (:fx) or Pro and routes requests to the correct API endpoint (https://api-free.deepl.com/v2 vs https://api.deepl.com/v2). If using a custom reverse proxy or enterprise gateway, you can enter a custom URL in the Custom DeepL Base URL field.


Setting Up OpenAI or OpenAI-Compatible APIs ​

MeshMonitor supports OpenAI and OpenAI-compatible providers (such as OpenRouter, Groq, Together AI, etc...), and local inference engines (such as Ollama or vLLM).

Using the Official OpenAI API ​

  1. Create an account at the OpenAI Platform.
  2. Generate an API secret key from the OpenAI API Keys Dashboard. For full API details and rate limits, consult the OpenAI API Documentation.
  3. In MeshMonitor under Settings β†’ Message Translation:
    • Set Translation Provider to OpenAI-Compatible (Ollama, OpenRouter, OpenAI, vLLM).
    • Set OpenAI API Base URL to https://api.openai.com/v1.
    • Set Model Name to gpt-4o-mini (or gpt-4o).
    • Paste your key (sk-...) into the API Key field.
  4. Click Test Connection and then Save Changes.

Local & Offline Options ​

If your MeshMonitor node operates in an off-grid, air-gapped, or privacy-conscious environment without internet access, you can run a local translation engine on the same host or local network:

1. LibreTranslate (Self-Hosted Open Source) ​

LibreTranslate is a free, self-hosted, open-source machine translation engine powered by Argos Translate.

You can quickly launch a local instance using Docker:

bash
docker run -d -p 5000:5000 --restart always libretranslate/libretranslate

In MeshMonitor:

  • Set Translation Provider to LibreTranslate (Local / Self-Hosted / Cloud).
  • Set LibreTranslate URL to http://localhost:5000 (or leave blank to use the default http://libretranslate:5000).
  • Leave the API key blank if authentication is not enabled on your instance.

2. Ollama / Local Language Models ​

If you run Ollama or another OpenAI-compatible local inference server:

bash
ollama run llama3.2

In MeshMonitor:

  • Set Translation Provider to OpenAI-Compatible (Ollama, OpenRouter, OpenAI, vLLM).
  • Set OpenAI API Base URL to http://host.docker.internal:11434/v1 (or leave blank to use the default http://host.docker.internal:11434/v1/chat/completions).
  • Set Model Name to your desired model (e.g. llama3.2, qwen2.5, or mistral).
  • Leave the API key blank for local Ollama instances.

Provider Settings and API Keys ​

Each provider has its own settings, and its own API key. The settings page shows only the fields of the provider you select:

ProviderFieldsRequired
LibreTranslateLibreTranslate URL, API keyNeither (blank URL uses http://libretranslate:5000)
OpenAI-CompatibleBase URL, model name, API keyNone (blank URL uses local Ollama, blank model uses gpt-4o-mini)
DeepL APIAuth key, custom base URLAuth key
Google Cloud TranslationAPI keyAPI key
  • A key is sent only to the provider it was entered for. Switching provider never reuses another provider's key: a DeepL key is not sent to your OpenAI-compatible URL.
  • Keys you entered for other providers stay stored. Switch back and the key is still there.
  • A provider with a required key cannot be tested or used without one. Test Connection reports the missing field without calling the provider.
  • Test Connection tests the values on screen, saved or not.

Upgrading from a version with one shared API key

Earlier versions stored one API key shared by every provider. On upgrade, MeshMonitor moves that key to the provider that is selected at the time of the upgrade. The other providers start with a blank key.

If you used the same key field with more than one provider, select each of the other providers and enter its key again. The old shared key is removed from the database. A backup taken before the upgrade is converted the same way: restore it, then restart MeshMonitor.


Endpoint URL Configuration Rules ​

When configuring custom service URLs for LibreTranslate, OpenAI-compatible backends, or DeepL custom gateways, MeshMonitor applies the following resolution rules:

  • Leave Blank: Uses the provider's default endpoint.
  • Bare Origin (e.g. http://localhost:5000 or http://localhost:11434): The provider's standard default path (such as /translate, /v1/chat/completions, or /v2/translate) is automatically appended.
  • Version Base Path (a path that ends in a version, e.g. http://host.docker.internal:11434/v1, https://openrouter.ai/api/v1, https://api.groq.com/openai/v1 or https://api.deepl.com/v2): Automatically appends the required subpath (/chat/completions or /translate).
  • Full Endpoint / Custom Path (any other path, e.g. https://my-proxy.internal/v1/custom-translate or https://api.openai.com/v1/chat/completions): Used verbatim as the full request destination. A base URL that does not end in a version (such as Gemini's .../v1beta/openai) must be entered as the full endpoint, ending in /chat/completions.
  • No Protocol Specified (e.g. localhost:5000): Automatically adopts the default protocol (http:// or https://) for that provider.

How to Use Translation ​

Inbound Message Translation ​

  1. In the Channels or Messages tab, hover over any message.
  2. Click the Translate icon on the message toolbar.
  3. The message is translated into your primary language (configured in settings or your last chosen language).
  4. To switch the target language, select a new language from the inline dropdown on the translated banner. MeshMonitor will re-translate the message and remember your preference in your browser's local storage.
  5. Click the close (βœ•) icon to hide the translation banner at any time.

Outbound Message Translation ​

  1. Type a message in the chat composer input box.
  2. Click the Translate icon to the right of the compose box.
  3. The Translate Outgoing Message modal will appear with your text pre-populated.
  4. Select your Source Language (or keep Auto-detect) and choose the Target Language.
  5. Use the ⇄ (swap) button if you need to reverse the language direction.
  6. Click Translate.
  7. Review the translation and check the byte counter.
  8. Click Replace in Draft to insert the translated text directly into the compose box ready for transmission.

Radio Constraints & Byte Limits ​

LoRa packet payloads are typically constrained to approximately 200 to 220 UTF-8 bytes depending on modem presets and packet metadata.

  • The outbound translation modal features a real-time UTF-8 byte counter showing current payload usage (e.g., 45 / 200 bytes).
  • If a translation exceeds the 200-byte threshold, a LoRa Packet Payload Warning banner appears in the modal advising you to shorten the text before transmitting over RF.

Security & Privacy ​

  • Authentication & Permission Gating: Translation endpoints (POST /api/translate and POST /api/v1/translate) require an authenticated user with messages:read permission. Unauthenticated visitors or users lacking message permissions cannot access translation endpoints, and translation action buttons are hidden in the UI.
  • Dedicated Rate Limiting: Translation endpoints are protected by a dedicated user/IP rate limiter (RATE_LIMIT_TRANSLATE, defaulting to 30 requests/minute in production and 120 in development) to defend provider API quota against automated loops and excessive usage.
  • Secret Masking: Each provider's API key is stored server-side under its own setting and stripped from GET /api/settings for non-admin viewers. A settings save by a non-admin never changes a key. The connection test never returns a key.
  • One Key per Provider: A provider receives only its own key and URL. See Provider Settings and API Keys.
  • Admin Gating: Connection testing (POST /api/translate/test) requires administrative privileges (requireAdmin()).
  • Telemetry Filtering: Raw telemetry packets, system status logs, emojis, and standard radio pings (ack, ping, test, 73) are automatically detected and filtered out to prevent unnecessary API queries and costs.
  • Payload Limits: Inbound translation requests enforce a maximum character limit of 5,000 characters and include automatic request timeouts.