Safari/iPhone recording now uses MP4/AAC when WebM is unavailable. WebM remains the default when supported and FFmpeg is disabled. Added optional FFmpeg profiles: recommended M4A/AAC-LC or requested MP4/H.264 + AAC. Added MIME-aware, playsinline audio playback. Added dashboard controls under Plans & Platform → Voice Transcoding / FFmpeg. Added Apache/Nginx media MIME configuration and documentation. Core implementation: voice_transcoder.php (line 72), messages.php (line 86), and cyberchat-app.js (line 635).
8.5 KiB
CyberChat
CyberChat is a framework-free PHP, SQLite, JavaScript, and HTML5 chat application with configurable paid tiers, Stripe subscriptions, Mailgun email verification, voice messages, personal archives, an administrator dashboard, and an optional MySQL/MariaDB mirror.
Included Features
- Registration without an email address
- Verified email required before premium checkout
- Mailgun email verification and email two-factor login codes
- Stripe Checkout, Billing Portal, webhook synchronization, and cancellation
- Configurable plans, prices, Stripe Price IDs, limits, and feature assignments
- Subscription display switch that hides new sales while preserving billing management for existing customers
- Premium-configurable recording presence for both sending and viewing
- Premium-configurable automatic voice sending
- Tier-configurable automatic playback of newly received voice clips
- Optional FFmpeg voice transcoding to iPhone-compatible AAC/M4A or H.264/AAC MP4
- Administrator tier overrides that grant plan features without payment
- Single-worker queued polling with cursor catch-up, request timeouts, deduplication, bounded retry backoff, and a capped browser message buffer
- Plan-based custom username colors
- Personal text archives retained for at least 30 days
- Plan-based voice archive access and JSON/CSV exports
- Visitor and feature usage statistics
- SQLite by default, with optional automatic MySQL/MariaDB mirroring
- Dark neon interface with a saved light-mode toggle
Requirements
- PHP 8.1 or newer
- PHP extensions:
pdo_sqlite,curl, andfileinfo - A web server with HTTPS for production
- Write access to
db/,archive/,uploads/voice/, andconfig.json - A modern browser with
MediaRecorderfor voice recording - Optional: FFmpeg with AAC support;
libx264is also required for the H.264 profile - Optional: PDO MySQL for the MySQL/MariaDB mirror
Installation
- Place the application in the web root.
- Make the runtime directories and configuration writable by the web-server user.
- Configure Apache with the included
.htaccess, or adaptnginx-example.conf. - Open
admin.phpand sign in with the initial passwordchangeme123. - Immediately change
admin.passwordin the Configuration tab. - Open Plans & Platform to configure tiers, Mailgun, Stripe, optional voice transcoding, and MySQL mirroring.
The SQLite schema and default Free, Plus, and Pro tiers are created automatically on first use.
For a simple shared-hosting deployment:
chmod 0777 db archive uploads/voice
For a managed server, ownership is preferable:
chown -R www-data:www-data db archive uploads/voice
chmod -R 0770 db archive uploads/voice
Replace www-data with the PHP-FPM or web-server account. SQLite must be able to create the database plus -wal and -shm sidecar files. When the application directory itself is restricted, database.main_db may be an absolute path to a writable persistent directory.
Default Tiers
The defaults are starting points and are fully editable in the dashboard.
| Feature | Free | Plus | Pro |
|---|---|---|---|
| Recording status send/view | No | Yes | Yes |
| Automatic voice send | No | Yes | Yes |
| Automatic voice play | No | Yes | Yes |
| Custom username color | No | Yes | Yes |
| Text archive | 30 days | 90 days | 365 days |
| Text export | Yes | Yes | Yes |
| Voice archive/export | No | Yes | Yes |
| Email 2FA | No | Yes | Yes |
Administrators can assign a tier directly from Admin > Users > Edit > Tier Override. The override grants that tier's features without changing Stripe billing data and remains in effect until it is changed back to Follow Stripe / billing status.
Mailgun
Configure these fields under Admin > Plans & Platform:
- API key
- Sending domain
- From address
- API base, normally
https://api.mailgun.net/v3 - EU API base, when applicable:
https://api.eu.mailgun.net/v3
The reusable mailer is in lib/mailer.php. It sends verification links and codes, limits verification attempts, and sends 2FA codes with a direct link to the authentication screen.
Mailgun API reference: https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/messages/post-v3--domain-name--messages
Stripe
-
Create recurring Stripe Prices for the paid tiers.
-
Enter each
price_...ID in the matching dashboard plan. -
Enter the Stripe secret key and webhook signing secret.
-
Add this webhook endpoint:
https://YOUR-DOMAIN/YOUR-PATH/api/stripe-webhook.php -
Subscribe the endpoint to:
checkout.session.completedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedinvoice.paidinvoice.payment_failed
Checkout is rejected until the account has a verified email. Stripe customer and subscription IDs, status, current period end, cancellation state, and selected plan are synchronized into SQLite.
When subscriptions.enabled is off, plans and checkout are hidden from non-subscribers. Existing Stripe customers retain Billing Portal and cancellation access.
Stripe references:
Voice Compatibility and FFmpeg
Browsers that support WebM continue to record WebM by default. Safari and iPhone may record MP4/AAC instead, which the upload API also accepts.
Under Admin > Plans & Platform > Voice Transcoding / FFmpeg, configure:
- Enable or disable server-side transcoding
- FFmpeg executable name or absolute path
M4A / AAC-LC, recommended for audio-only playback on iPhone, Safari, Android, and desktopMP4 / H.264 + AAC, which adds a tiny black H.264 video track for systems requiring a conventional MP4- Audio bitrate and conversion timeout
- Whether to retain the original source when conversion fails
When transcoding is disabled, the original browser recording is stored. WebM remains the preferred default on supported browsers. When enabled, new uploads are converted; existing voice files are unchanged.
Archives
The application archives daily messages into:
archive/{year}/{month}/{day}.sqlite
The public legacy archive browser now redirects to the authenticated My Archive view. Users can only query their own sent messages within their plan retention window. Free users receive text history only; voice history and voice export require the corresponding plan entitlements.
MySQL/MariaDB Mirror
SQLite remains the required primary database. The optional mirror imports the main database and all archive databases into sqlite_mirror_rows using:
- source database path
- source table
- row key
- JSON row data
- synchronization time
Set a PDO MySQL DSN in the dashboard, enable the mirror, and optionally enable automatic import. A manual Run MySQL Mirror Now action is also available.
Embedding
<link rel="stylesheet" href="/chat/assets/css/cyberchat.css?v=20260609.3">
<div id="my-chat" style="width:100%;height:600px"></div>
<script>
window.CYBERCHAT_BASE = '/chat';
</script>
<script src="/chat/assets/js/cyberchat-app.js?v=20260609.6"></script>
<script>
CyberChat.init('#my-chat');
</script>
See embed-example.html for a complete example.
Main Files
admin.php Administrator dashboard
bootstrap.php Configuration, schema, auth, plans, archives, stats
config.json Runtime settings and service credentials
api/account.php Email, color, and 2FA settings
api/archive.php Private personal archive and export
api/auth.php Registration, login, 2FA, sessions
api/billing.php Stripe checkout, portal, and cancellation
api/messages.php Text, voice, polling, and recording presence
api/stripe-webhook.php Stripe event synchronization
assets/js/cyberchat-app.js Browser application
lib/mailer.php Reusable Mailgun sender
lib/stripe.php Stripe REST client and subscription sync
lib/voice_transcoder.php Optional FFmpeg voice compatibility pipeline
lib/mysql_mirror.php Optional SQLite-to-MySQL mirror
Production Security
- Change the default administrator password and statistics salt.
- Serve the application only over HTTPS.
- Keep
.htaccessrules enabled or reproduce all deny rules in the web-server configuration. - Never expose
config.json,db/,archive/, orlib/. - Use separate Stripe test and live webhook secrets.
- Restrict
admin.phpby IP or additional HTTP authentication where practical. - Back up SQLite databases and voice files together.