Modernisasi Legacy PHP Autoresponder Menjadi Lightweight Self-Hosted Email Automation Platform

2. SQL Injection Protection

Legacy application sering memiliki query seperti:

$sql = "SELECT * FROM leads WHERE email='$email'";

Jika input berasal langsung dari HTTP request, pola tersebut dapat membuka SQL Injection vulnerability.

Versi modern akan menggunakan:

$stmt = $pdo->prepare(
    'SELECT * FROM leads WHERE email = :email'
);

$stmt->execute([
    'email' => $email
]);

Semua query yang menerima input eksternal harus mengikuti pendekatan serupa.

Targetnya sederhana:

Tidak ada lagi user input yang langsung digabungkan ke SQL statement.


3. Menghapus Hardcoded Credentials

Salah satu technical debt yang umum ditemukan pada aplikasi legacy adalah konfigurasi seperti:

$dbUser = 'root';
$dbPassword = 'password';

atau bahkan admin credentials yang tersimpan langsung dalam source code.

Pendekatan ini tidak cocok untuk repository modern, terlebih jika project nantinya menjadi open source.

Arsitektur konfigurasi akan diubah menjadi:

Environment Variables
        │
        ▼
Application Config
        │
        ▼
Application

Contohnya:

DB_HOST=localhost
DB_DATABASE=autoresponder
DB_USERNAME=autoresponder
DB_PASSWORD=

MAIL_DRIVER=smtp
SMTP_HOST=
SMTP_USERNAME=
SMTP_PASSWORD=

Repository hanya akan menyediakan:

.env.example

sedangkan:

.env

akan dimasukkan ke .gitignore.

Dengan model seperti ini aplikasi dapat dijalankan pada:

development
staging
production
Docker
VPS
cloud environment

tanpa mengubah source code.


4. Password Hashing dan Authentication

Legacy authentication sering menggunakan pola sederhana:

if ($username === $adminUser &&
    $password === $adminPassword) {
}

Versi baru tidak akan menyimpan password dalam plaintext.

PHP sudah menyediakan:

password_hash()
password_verify()

Contoh:

$passwordHash = password_hash(
    $password,
    PASSWORD_DEFAULT
);

dan login:

if (password_verify(
    $password,
    $storedHash
)) {
    // authenticated
}

Selain itu session management juga akan diperbaiki dengan:

HttpOnly cookies
Secure cookies
SameSite
session_regenerate_id()
session timeout

5. CSRF dan XSS Protection

Aplikasi legacy sering mengandalkan HTML form sederhana.

Misalnya:

Add Lead
Delete Lead
Create Message
Edit Message

Semua operasi tersebut akan dilindungi dengan CSRF token.

Secara konseptual:

Browser
   │
   ▼
Form + CSRF Token
   │
   ▼
Server
   │
   ├── validate session
   ├── validate CSRF
   └── execute request

Untuk mencegah Cross-Site Scripting, setiap user-generated output juga harus di-escape.

Contohnya:

htmlspecialchars(
    $value,
    ENT_QUOTES,
    'UTF-8'
);

6. Modern Unsubscribe Mechanism

Versi legacy menggunakan identifier lead seperti:

unsubscribe.php?id=10&email=user@example.com

Pendekatan ini terlalu mudah ditebak.

Versi modern akan menggunakan token:

unsubscribe.php?token=<random-token>

Token dapat berupa random cryptographically secure value atau signed HMAC token.

Selain itu unsubscribe tidak seharusnya langsung menghapus lead.

Lebih baik menyimpan:

status = unsubscribed
unsubscribed_at = timestamp

Dengan demikian sistem memiliki:

audit trail
suppression list
compliance history
campaign analytics

7. Menggantikan PHP mail()

Versi lama menggunakan:

mail();

Untuk project modern, pengiriman email akan menggunakan transport abstraction.

Target awalnya:

SMTP
Amazon SES

Arsitekturnya:

Application
    │
    ▼
Mail Transport Interface
    │
    ├───────────────┐
    ▼               ▼
 SMTP          Amazon SES

Dengan model ini aplikasi tidak bergantung pada satu provider.

Inilah dasar dari prinsip:

No vendor lock-in.

Pada masa depan transport tambahan juga dapat dibuat untuk:

Mailgun
SendGrid
Postmark
Brevo
Resend

tanpa mengubah campaign engine.


8. Queue dan Worker

Pada aplikasi lama, scheduler dapat langsung mengirim email ketika menemukan message yang harus dikirim.

Pendekatan ini cukup untuk volume kecil.

Namun sistem modern sebaiknya memisahkan:

menentukan email yang harus dikirim

dari:

mengirim email

Target architecture:

Scheduler
    │
    ▼
Campaign Resolver
    │
    ▼
email_jobs
    │
    ▼
Worker
    │
    ▼
Email Provider

Untuk mempertahankan positioning lightweight, queue tidak harus menggunakan Redis atau RabbitMQ.

Versi awal dapat menggunakan database-backed queue.

Contohnya:

email_jobs

dengan field:

id
lead_id
campaign_id
message_id
status
attempts
scheduled_at
sent_at
last_error

Pendekatan ini cukup untuk small VPS deployment.


9. Modern Data Model

Legacy system pada dasarnya hanya membutuhkan:

leads
messages

Tetapi jika ingin mendukung multiple campaigns, schema harus dikembangkan.

Target model:

leads

campaigns

campaign_messages

campaign_subscriptions

email_jobs

email_deliveries

unsubscribe_tokens

Relasi sederhananya:

Lead
 │
 ▼
Campaign Subscription
 │
 ▼
Campaign
 │
 ├── Message Day 0
 ├── Message Day 2
 ├── Message Day 5
 └── Message Day 10

Dengan model tersebut, satu lead dapat bergabung dengan beberapa campaign.


10. REST API

Salah satu tujuan modernization adalah membuat aplikasi menjadi automation friendly.

Karena itu aplikasi akan menyediakan REST API.

Contohnya:

POST /api/leads
GET  /api/leads
GET  /api/leads/{id}

Campaign:

POST /api/campaigns
GET  /api/campaigns

Subscription:

POST /api/campaigns/{id}/subscribe

Unsubscribe:

POST /api/unsubscribe

Versi awal cukup menggunakan:

API Key authentication

Tidak perlu langsung menggunakan OAuth karena akan menambah kompleksitas.


11. Webhook Architecture

REST API menangani komunikasi masuk.

Webhook menangani event keluar.

Misalnya ketika sebuah lead dibuat:

lead.created

atau email terkirim:

email.sent

Autoresponder akan dapat mengirim event ke external system.

Contohnya:

Autoresponder
      │
      ▼
Webhook
      │
      ▼
External Application

Event awal yang direncanakan:

lead.created
lead.unsubscribed

campaign.subscribed

email.queued
email.sent
email.failed

Webhook juga akan memakai HMAC signature agar penerima dapat memverifikasi authenticity dari request.


12. n8n Integration

Salah satu positioning utama project ini adalah:

n8n friendly

Tetapi kompatibilitas tidak cukup hanya dengan menyediakan REST API.

Project juga akan menyediakan beberapa contoh workflow.

Contoh:

Website Form
      │
      ▼
     n8n
      │
      ▼
Autoresponder API
      │
      ▼
Email Campaign

Use case lainnya:

Autoresponder
     │
 webhook
     ▼
    n8n
     │
     ├── Google Sheets
     ├── CRM
     ├── Slack
     └── Telegram

Repository nantinya dapat memiliki:

examples/
└── n8n/
    ├── lead-capture.json
    ├── crm-sync.json
    └── campaign-notification.json

13. Target Application Structure

Struktur aplikasi akan diubah dari banyak standalone PHP script menjadi struktur yang lebih modular.

Contoh target:

autoresponder/
│
├── public/
│   ├── index.php
│   ├── subscribe.php
│   └── unsubscribe.php
│
├── src/
│   ├── Auth/
│   ├── Lead/
│   ├── Campaign/
│   ├── Mail/
│   ├── Database/
│   └── Security/
│
├── config/
│   └── app.php
│
├── database/
│   ├── migrations/
│   └── schema.sql
│
├── bin/
│   ├── scheduler.php
│   └── worker.php
│
├── templates/
├── tests/
├── docs/
├── examples/
│
├── composer.json
├── .env.example
├── .gitignore
├── README.md
├── SECURITY.md
└── LICENSE

14. Composer dan PSR-4

Aplikasi modern akan menggunakan Composer untuk dependency management.

Contohnya:

composer install

Composer juga digunakan untuk PSR-4 autoloading.

Dengan demikian kita tidak lagi bergantung pada banyak:

require_once 'file1.php';
require_once 'file2.php';
require_once 'file3.php';

Class dapat di-load otomatis berdasarkan namespace.

Misalnya:

use App\Campaign\CampaignService;
use App\Mail\SMTPTransport;

15. Lightweight Tetap Menjadi Prinsip Utama

Modernisasi bukan berarti semua teknologi modern harus digunakan.

Project ini sengaja tidak akan menjadikan hal-hal berikut mandatory:

Kubernetes
Redis
RabbitMQ
Kafka
Elasticsearch
microservices
service mesh

Targetnya tetap:

1 small VPS
+
Nginx
+
PHP-FPM
+
MariaDB/MySQL

Misalnya:

1 vCPU
1 GB RAM
10–20 GB storage

sudah seharusnya cukup untuk penggunaan skala kecil.

Docker dapat disediakan sebagai pilihan, bukan keharusan.


16. Target Architecture

Arsitektur akhirnya dirancang seperti berikut:

                         Internet
                            │
                            ▼
                         Nginx
                            │
                            ▼
                 ┌─────────────────────┐
                 │ PHP Application     │
                 │                     │
                 │ Authentication      │
                 │ Leads               │
                 │ Campaigns           │
                 │ REST API            │
                 │ Webhooks            │
                 └──────────┬──────────┘
                            │
                ┌───────────┴────────────┐
                ▼                        ▼
          MySQL / MariaDB             Email Jobs
                                         │
                                         ▼
                                      Worker
                                         │
                             ┌───────────┴──────────┐
                             ▼                      ▼
                           SMTP                Amazon SES

17. Development Roadmap

Modernisasi akan dilakukan secara incremental.

v0.1 — Secure Legacy Foundation

Fokus:

PDO
prepared statements
PHP 8 compatibility
environment variables
secure authentication
CSRF protection
XSS protection
secure unsubscribe

Project masih private pada tahap ini.


v0.2 — Modern PHP Foundation

Fokus:

Composer
PSR-4
modular architecture
database migrations
structured configuration
documentation
basic tests

Setelah security review selesai, repository dapat mulai dijadikan public.


v0.3 — Email Delivery

Fokus:

SMTP
Amazon SES
mail transport abstraction
queue
worker
retry
delivery logs

v0.4 — Campaign Engine

Fokus:

multiple campaigns
campaign subscriptions
message scheduling
personalization
delivery history
pause/resume

v0.5 — API & Automation

Fokus:

REST API
API Key authentication
webhooks
HMAC signatures
n8n examples

v1.0 — Stable Release

Target v1.0:

Lead Management
Campaign Management
Drip Email
SMTP
Amazon SES
Queue Worker
REST API
Webhook
n8n Integration
Secure Unsubscribe
PHP 8.x
MySQL / MariaDB
Self-hosted Installation Guide
Basic Automated Testing

18. CI/CD dan Code Quality

Repository juga akan menggunakan GitHub Actions.

Pipeline minimal:

Pull Request
      │
      ▼
composer install
      │
      ▼
PHP Syntax Check
      │
      ▼
PHPUnit
      │
      ▼
PHPStan
      │
      ▼
Composer Security Audit

Tujuannya bukan sekadar automation.

Pipeline tersebut menjadi quality gate sebelum code masuk ke branch main.


19. Dokumentasi Architecture

Sebagai bagian dari project modernization, repository akan memiliki architecture documentation.

Contohnya:

docs/
├── architecture/
│   ├── legacy-architecture.md
│   ├── target-architecture.md
│   ├── data-model.md
│   ├── campaign-engine.md
│   └── email-delivery.md
│
├── security/
│   ├── threat-model.md
│   └── security-design.md
│
├── deployment/
│   ├── nginx.md
│   └── small-vps.md
│
└── integrations/
    ├── smtp.md
    ├── amazon-ses.md
    └── n8n.md

Dokumentasi ini penting karena project bukan hanya tentang code.

Project juga harus dapat menjelaskan:

Why?
What?
How?
Trade-off?
Security?
Scalability?
Operational model?

20. Mengapa Tidak Langsung Rewrite?

Salah satu keputusan architecture yang penting adalah tidak melakukan complete rewrite sejak awal.

Rewrite memang terlihat menarik.

Tetapi complete rewrite memiliki risiko:

business logic hilang
feature regression
scope membesar
development tidak pernah selesai

Pendekatan yang dipilih adalah:

Understand
   ↓
Secure
   ↓
Modernize
   ↓
Refactor
   ↓
Extend

Dengan begitu setiap milestone menghasilkan aplikasi yang tetap dapat dipahami dan diuji.


21. Modernisasi sebagai Engineering Exercise

Project ini bukan sekadar mengubah syntax PHP lama menjadi syntax PHP baru.

Modernisasi mencakup beberapa area sekaligus:

Software Architecture

Application Security

Database Engineering

Email Infrastructure

API Design

Automation

DevOps

Observability

Documentation

Dan mungkin bagian terpentingnya adalah:

membuat keputusan teknis yang proporsional terhadap kebutuhan aplikasi.

Tidak semua aplikasi membutuhkan microservices.

Tidak semua queue membutuhkan Kafka.

Tidak semua aplikasi membutuhkan Kubernetes.

Salah satu tujuan project ini justru membuktikan bahwa aplikasi modern juga dapat tetap:

simple
small
maintainable
secure
portable

Penutup

Autoresponder ini dimulai sebagai aplikasi PHP sederhana dengan satu tujuan utama:

mengirimkan email otomatis kepada leads berdasarkan waktu sejak mereka bergabung.

Business logic tersebut tetap relevan.

Yang sudah berubah adalah ekspektasi terhadap software modern.

Hari ini aplikasi harus memiliki:

secure database access
safe authentication
modern PHP compatibility
environment-based configuration
reliable email delivery
API integration
automation support
good documentation

Modernisasi ini bertujuan menjembatani kedua dunia tersebut.

Dari:

Legacy PHP Autoresponder

menuju:

Lightweight
Self-hosted
Secure
API-driven
Automation-friendly
Email Automation Platform

tanpa kehilangan filosofi awalnya:

Keep it simple.

Project ini juga akan menjadi sebuah perjalanan untuk mengeksplorasi bagaimana legacy application dapat dimodernisasi secara incremental—bukan hanya dari sisi source code, tetapi juga dari sisi security, architecture, deployment, integration, dan operational model.

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *