
About
netzSINN GPT — AI Middleware for Joomla 6
This plugin connects your Joomla website to an AI provider (such as OpenAI or Mistral AI) — securely, centrally, and without exposing your API key.
Typical use cases:
- A FAQ assistant that answers questions about your services in your website's tone
- An intake form that summarises a visitor's enquiry before it reaches your inbox
- A content tool that generates draft texts for your editors on the server side
The plugin has no visible frontend widget. It is infrastructure — a stable, secure foundation that any Joomla extension on your site can build on.
Features
-
Interchangeable AI providers: OpenAI, Mistral AI (EU servers, GDPR-compliant), Anthropic, Google, Groq, DeepSeek, OpenRouter, Custom (i. e. Ollama or any other). And for translation DeepL (EU servers, GDPR-compliant).
-
Admin-configurable AI contexts in the backend: context key + system prompt + individual parameters
-
Event-based context system: other plugins can register their own contexts server-side
-
Two usage paths: HTTP endpoint (AJAX, frontend JS) and direct PHP method call (server-side)
-
API key encryption: AES-256 with native PHP Sodium, using the Joomla site secret as the key
-
Protection: Rate limiting, CSRF token verification, origin check, and input sanitisation by default
-
Per-context parameters:
max_tokens,max_input_length, andtemperatureconfigurable per context -
Backend test system: verify the API connection directly inside the Plugin Manager
-
Conversation history: supports modern object-array format (
role/content) and legacy strings -
Stateless: no conversation data is stored; every request is independent
-
Built-in DeepL translation: translate text via HTTP or PHP with the same key management, CSRF protection, and rate limiting as the AI feature
-
DeepL context system: define named translation profiles (e.g. `html_de`, `formal_en`) in the backend — no per-call parameter juggling needed
GDPR & Security
Data protection built in
All AI requests pass through your own server. Your API key is encrypted automatically on first save (AES-256, PHP Sodium, using your Joomla site secret as the encryption key) — it never appears in plain text in your database or your website's HTML.
Every request is protected by:
- CSRF token verification
- Origin check
- Rate limiting (default: 10 requests per IP per minute)
- Input sanitisation
Suported Providers & Models
| Provider | Model | Server | GDPR |
|---|---|---|---|
|
OpenAI
|
|
US |
Requires privacy policy update |
|
Mistral AI
|
|
EU (Paris) |
✔ Compliant, DPA available |
|
Anthropic
|
|
US |
Requires privacy policy update |
|
Google
|
|
US |
Requires privacy policy update |
|
Groq
|
|
US |
Requires privacy policy update |
|
xAI (Grok)
|
|
US |
Requires privacy policy update |
|
Qwen (Alibaba)
|
|
China |
Requires privacy policy update |
|
DeepSeek
|
|
China |
Requires privacy policy update |
|
OpenRouter
|
|
US |
Requires privacy policy update |
|
Custom (i. e. Ollama, vLLM, llama, others)
|
Any OpenAI-compatible |
Selfhosted |
✔ Compliant, if your Server is inside EU |
|
DeepL
|
|
EU |
✔ Compliant, ADV |
- Model lists are always up to date. Each provider has a dropdown with a built-in fallback list of common models. A single click on "Reload models" fetches the current model list live from the provider's API and replaces the dropdown options — no manual editing of config files needed.
- DeepL is not integrated as a chat provider, but as a separate service ($gpt->translate(...)), independent of the LLM workflow.
How it works
Provider/LLM
How it works — Admin perspective
Three things to configure, then it runs.
Step 1 — Choose a provider and enter your API key.
Select OpenAI, Mistral, or one of the other supported providers. Enter your API key — it is encrypted automatically when you save.
Step 2 — Define AI contexts.
A context is a named instruction set for the AI. It tells the AI who it is, what it should and should not do, and in which language it should respond.
Example context faq:
You are a friendly assistant for this website. Only answer questions about our services. If you cannot answer a question, refer the visitor to a personal conversation. Respond in English.
You can create as many contexts as you need. Two are pre-configured and ready to use: faq and contact.
Step 3 — Connect your frontend or other plugins.
Any Joomla extension can now send a message to a context and receive a plain text answer. The API key, the provider, and all security logic remain invisible to the caller.
Per-context settings:
| Setting | What it controls |
|---|---|
System Prompt | The AI's role and instructions |
Max. Input Length | Maximum characters a user may send (protects against abuse) |
Max. Tokens | Maximum length of the AI's response (controls cost) |
Temperature | 0.2–0.4 factual · 0.7 balanced · 1.0+ creative |
Provider / Model | Optional override — leave empty to use the global setting |
Installation & Quick Start
- Install the ZIP file: Joomla backend → System → Extensions → Install
- Enable the plugin: System → Plugins → System - netzSINN GPT
- Select a provider, enter your API key — it is encrypted automatically on save
- Review or adjust the pre-configured
faqandcontactcontexts - Use the built-in Test button to verify the API connection
System requirements: Joomla 6.0+, PHP 8.1+, PHP Sodium extension (included in modern PHP installations by default)
DeepL Translation
Configure DeepL
-
Create an account at https://www.deepl.com/pro
-
Retrieve your API key under Account → API- Free plan: key ends with `:fx`- Pro plan: key without suffix
-
Enter the key in the plugin backend under the DeepL tab — it is encrypted automatically
Global defaults (DeepL tab)
| Parameter | Description | Default |
|---|---|---|
`deepl_default_target_lang` | Target language when none is specified | `DE` |
`deepl_default_source_lang` | Source language (empty = auto-detect) | – |
`deepl_tag_handling` | `text` · `html` · `xml` | `text` | |
`deepl_formality` | `more` · `less` · `prefer_more` · `prefer_less` | – |
`deepl_model_type` | `quality_optimized` · `latency_optimized` | – |
`deepl_preserve_formatting` | Retain original punctuation and capitalisation | `false` |
`deepl_split_sentences` | `0` · `1` · `nonewlines` | – |
DeepL contexts
Context Key | Unique identifier, e.g. `html_de`, `formal_en`, `plain_fr`
|
Target lang | Target language for this context |
Source lang | Source language (empty = auto-detect) |
Tag handling | `text` / `html` / `xml` |
Formality | `more` / `less` / `prefer_more` / `prefer_less` |
Model type | `quality_optimized` / `latency_optimized` |
Preserve formatting | Yes / No (empty = global) |
Split sentences | `0` / `1` / `nonewlines` |
Explicit request parameter > Context value > Global admin defaultFor Developers
Provider/ LLM
For Developers — How to use
Consumer plugins can register their own contexts via the event `onNetzsinnGptRegisterContexts` and thereby overwrite the system prompt of a corresponding admin entry. This is the only way to replace the prompt programmatically — front-end calls (JS/AJAX) cannot directly pass the system prompt.
Option A: Frontend JavaScript
const reply = await NetzsinnGptAPI.ask({
message: 'What are your opening hours?',
context: 'faq',
token: Joomla.getOptions('csrf.token')
});
document.getElementById('answer').textContent = reply;The API key stays server-side at all times — it is never exposed in JavaScript or HTML.
Option B: Server-side PHP (recommended)
<?php
$gpt = $this->getApplication()->bootPlugin('netzsinn_gpt', 'system');
$reply = $gpt->ask(
message: 'What are your opening hours?',
context: 'faq',
history: [] // optional: previous conversation turns
);The return value is a plain string. No API key handling, no security boilerplate required in the calling plugin.
Security: ask() only accepts pre-registered context keys. A browser request cannot invent a new context — the whitelist is built entirely server-side, which blocks prompt injection at the architecture level.
For Developers — Context System & Event API
Contexts can be provided from two sources, which are merged at plugin load time.
Option A — Admin panel (recommended)
The administrator creates contexts in the backend. Prompts can be updated at any time without code changes. Suitable for editorially managed content.
Option B — Event (for fixed prompts in code)
A consumer plugin registers contexts server-side at load time. Suitable when the system prompt should remain in version control or admin access is not desired.
<?php
public function onNetzsinnGptRegisterContexts(RegisterContextsEvent $event): void
{
$event->addContexts([
'tracking_report' => [
'system_prompt' => 'You are a data analysis assistant...',
'max_input_length' => 5000,
'max_tokens' => 1200,
'temperature' => 0.3,
],
]);
}Merge rules when both sources provide the same context key:
| Winner | Field | Reason |
|---|---|---|
Consumer plugin | system_prompt | The plugin knows its use case best |
Admin | max_tokens, temperature, max_input_length | Cost and quality control stays with the operator |
Admin | provider, model | Infrastructure decision, not the plugin's concern |
DeepL Translation
How to use DeepL
// Simple — use global admin defaults
const translation = await NetzsinnGptAPI.translate({
text: 'Hello, how are you?',
token: Joomla.getOptions('csrf.token')
});
// With a named context (profile stored in backend)
const translation = await NetzsinnGptAPI.translate({
text: '<p>Hello World</p>',
context: 'html_de',
token: Joomla.getOptions('csrf.token')
});
// Context + explicit override (override wins)
const translation = await NetzsinnGptAPI.translate({
text: '<p>Hello World</p>',
context: 'html_de',
tagHandling: 'text', // overrides the context value
token: Joomla.getOptions('csrf.token')
});$gpt = $this->getApplication()->bootPlugin('netzsinn_gpt', 'system');
// Simple — global admin defaults apply
$translation = $gpt->translate(
text: 'Hello, how are you?',
targetLang: 'DE'
);
// All optional parameters
$translation = $gpt->translate(
text: '<p>Hello World</p>',
targetLang: 'DE',
sourceLang: 'EN',
tagHandling: 'html',
formality: 'more',
modelType: 'quality_optimized',
preserveFormatting: true,
splitSentences: '1'
);
DeepL Context System
use Netzsinn\Plugin\System\NetzsinnGpt\Event\RegisterDeepLContextsEvent;
public function onNetzsinnGptRegisterDeepLContexts(RegisterDeepLContextsEvent $event): void
{
$event->addContexts([
'html_de' => [
'target_lang' => 'DE',
'tag_handling' => 'html',
'formality' => 'more',
// omitted fields → null = global admin value as fallback
],
'plain_en' => [
'target_lang' => 'EN-GB',
'tag_handling' => 'text',
],
]);
}
Merge priority (Admin vs. Plugin):
Admin field is set (non-null) | Admin always wins
|
Admin field is empty/null | Plugin value is used
|
Key exists only in plugin | All plugin values are adopted
|
System Requirements
-
Joomla 6.0+
-
PHP 8.1+
-
PHP Sodium Extension (libsodium) — included by default in modern PHP installations
-
A valid API key from OpenAI or Mistral AI
Changelog
-
v1.11.0
- Security: New API keys are now stored in a new ENC-prefixed hex format; older saved keys still work and can be migrated automatically
- Security: Encryption checks and decryption now recognise the new format strictly while still supporting older saved keys
- Fix: Direct error logging was removed from decryption; masked messages now only go through the plugin log
-
v1.10.3
- Fix: API test popup now only shows contexts that are actually configured; removed the static faq and contact options; falls back to example or the first available context
- Docs: Documentation updated to use example as the default context and explain configuration-based context selection in the test popup
-
v1.10.2
- refactor: package cleanup
-
v1.10.1
- Style: GPL license notice ensured in all PHP files (tests/, test/)
- Style: Security guard placement verified in all src/ files (after namespace, before use)
-
v1.10.0
- Improved privacy warning hints — China providers (DeepSeek, Qwen) upgraded to alert-danger (red)
- OpenRouter warning extended to note possible data transfer to China depending on selected model
- Feature: Alibaba Qwen support — Qwen models (qwen-max, qwen-plus, qwen-turbo and more) are now available as an AI provider; includes a GDPR notice (Chinese service)
- Feature: xAI Grok support — Grok models (grok-3, grok-3-fast, grok-3-mini, grok-2) are now available as an AI provider
- Feature: Both new providers can be configured in the backend with their own API key and model selection, and are available as per-context provider overrides
-
v1.9.0
- Feature: Dynamic model list — available AI models are no longer hardcoded; a "Reload models" button fetches the current list directly from the provider's API
- Feature: All model defaults and fallback lists are now managed centrally in one place, making future updates easier
- Fix: CSRF token handling and response parsing for the model reload corrected
-
v1.8.1
- Fix: API test button now works correctly for all providers (DeepSeek, Groq, Anthropic, Google, OpenRouter, Custom) — previously only OpenAI and Mistral were supported
- Feature: HTTP timeout configurable in the backend (10–300 seconds, default 120 s) under "Security & Debug"
- Improvement: Default contexts reduced to a single generic example entry
-
v1.8.0
- Feature: DeepL context system — translation settings (target language, formality, etc.) can now be configured per context key, just like AI contexts
- Feature: Third-party plugins can register their own DeepL contexts via a new event
- Feature: Per-context translation parameters — admin settings always take priority; plugin-registered values only apply where the admin has not set a value
- Feature: The translate() API call now accepts an optional context key; individual per-request parameters still override the context values
-
v1.7.1
- Fix: Unexpected PHP errors during AJAX requests are now correctly caught and logged instead of failing silently
- Fix: Missing or invalid DeepL API responses now produce a clear error message instead of a silent crash
- Improvement: DeepL translation requests are now logged in detail (text length, target language, parameters, result, errors)
- Improvement: Debug & Diagnostics settings (rate limit, debug mode, API test button) are now grouped in a dedicated backend tab
-
v1.7.0
- Feature: Additional DeepL translation options — formality, model type, formatting preservation, and sentence splitting can now be configured in the backend as default values
- Feature: DeepL API test button in the backend — opens a modal to test the translation directly with the configured settings
-
v1.6.0
- Feature: DeepL translation — the plugin can now translate texts directly via the DeepL API, independently of the AI chat providers
- Feature: DeepL settings in the backend — API key, default target language (30 languages), optional source language, and GDPR notice (DeepL is an EU/German service)
- Security: API key storage improved — keys are now saved with a clear prefix to prevent incorrect detection of already-encrypted values
- Security: Old API keys in the previous format are automatically migrated to the new format on the next backend visit</item>
-
v1.5.1
-
Fix: Admin settings (max. tokens, temperature, etc.) now always take priority over values set by other plugins — only the system prompt can still be overridden by other plugins
-
-
v1.5.0
- Feature: OpenRouter support — access to 200+ AI models (GPT-4o, Claude, Llama, Gemini, DeepSeek and more) with a single API key
- Feature: Per-context provider and model — each AI context in the backend can now use a different provider and model
- Fix: API keys for all providers are now correctly encrypted when saving
-
v1.4.1
- Improvement: The backend now has a single Test button; the provider is selected via a dropdown instead of separate buttons
- Fix: Test button now correctly sends the request to the selected provider
- Improvement: Label of the Debug Mode button revised
- Improvement: The backend now has a single Test button; the provider is selected via a dropdown instead of separate buttons
-
v1.4.0
- Feature: Multi-provider support — DeepSeek, Groq (Llama), Anthropic Claude, Google Gemini, and custom OpenAI-compatible services
- Feature: GDPR notices for all non-EU providers (DeepSeek from China, Groq/Anthropic/Google from the US)
- Improvement: Internal code refactoring for better maintainability and automated testing
-
v1.3.1
- Fix: Event-registered contexts without an explicit
max_tokensnow correctly fall back to the global admin value (instead of hardcoded 400) - Fix: Admin panel contexts now take priority over event-registered contexts with the same key
- Fix: Event-registered contexts without an explicit
-
v1.3.0
- Feature: Per-context parameters —
max_tokens,max_input_length,temperatureconfigurable per context - Feature:
max_tokensmoved from global-only to per-context (global value remains as fallback) - Feature: Subform layout changed to vertical blocks (no more horizontal scrolling)
- Feature: Native support for modern history format (object-array with
role/content) - Refactor: Internal context data structure changed from string to array-of-arrays
- Feature: Per-context parameters —
-
v1.2.3
- Fix:
loadCustomContexts()correctly reads subform data - Feature: Custom
RegisterContextsEventclass for a stable event system
- Fix:
-
v1.2.2
- Security: API keys in logs are now masked (first 10 + last 4 characters)
-
v1.2.1
- Feature: AES-256 API key encryption with PHP Sodium
-
v1.0.0 First official release
License
GNU General Public License version 2 or later
Download
Please, support this extension and review on Joomla Extension Directory JED!