6217a216a7
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).
199 lines
8.5 KiB
Markdown
199 lines
8.5 KiB
Markdown
# 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`, and `fileinfo`
|
|
- A web server with HTTPS for production
|
|
- Write access to `db/`, `archive/`, `uploads/voice/`, and `config.json`
|
|
- A modern browser with `MediaRecorder` for voice recording
|
|
- Optional: FFmpeg with AAC support; `libx264` is also required for the H.264 profile
|
|
- Optional: PDO MySQL for the MySQL/MariaDB mirror
|
|
|
|
## Installation
|
|
|
|
1. Place the application in the web root.
|
|
2. Make the runtime directories and configuration writable by the web-server user.
|
|
3. Configure Apache with the included `.htaccess`, or adapt `nginx-example.conf`.
|
|
4. Open `admin.php` and sign in with the initial password `changeme123`.
|
|
5. Immediately change `admin.password` in the Configuration tab.
|
|
6. 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:
|
|
|
|
```bash
|
|
chmod 0777 db archive uploads/voice
|
|
```
|
|
|
|
For a managed server, ownership is preferable:
|
|
|
|
```bash
|
|
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
|
|
|
|
1. Create recurring Stripe Prices for the paid tiers.
|
|
2. Enter each `price_...` ID in the matching dashboard plan.
|
|
3. Enter the Stripe secret key and webhook signing secret.
|
|
4. Add this webhook endpoint:
|
|
|
|
`https://YOUR-DOMAIN/YOUR-PATH/api/stripe-webhook.php`
|
|
|
|
5. Subscribe the endpoint to:
|
|
|
|
- `checkout.session.completed`
|
|
- `customer.subscription.created`
|
|
- `customer.subscription.updated`
|
|
- `customer.subscription.deleted`
|
|
- `invoice.paid`
|
|
- `invoice.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:
|
|
|
|
- <https://docs.stripe.com/api/checkout/sessions/create>
|
|
- <https://docs.stripe.com/webhooks>
|
|
|
|
## 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 desktop
|
|
- `MP4 / 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
|
|
|
|
```html
|
|
<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
|
|
|
|
```text
|
|
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 `.htaccess` rules enabled or reproduce all deny rules in the web-server configuration.
|
|
- Never expose `config.json`, `db/`, `archive/`, or `lib/`.
|
|
- Use separate Stripe test and live webhook secrets.
|
|
- Restrict `admin.php` by IP or additional HTTP authentication where practical.
|
|
- Back up SQLite databases and voice files together.
|