442 lines
12 KiB
Markdown
442 lines
12 KiB
Markdown
# Setup Bot WhatsApp di Ubuntu VPS - Step by Step
|
||
|
||
## 1. Update Sistem & Install Dependencies
|
||
|
||
```bash
|
||
# Update package list dan upgrade sistem
|
||
apt update && apt upgrade -y
|
||
|
||
# Install curl, wget, dan tools penting lainnya
|
||
apt install -y curl wget git unzip software-properties-common build-essential
|
||
|
||
# Install Node.js versi terbaru (LTS)
|
||
curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -
|
||
apt install -y nodejs
|
||
|
||
# Verifikasi instalasi
|
||
node --version
|
||
npm --version
|
||
```
|
||
|
||
## 2. Buat User Non-Root (Recommended untuk Security)
|
||
|
||
```bash
|
||
# Buat user baru
|
||
adduser botuser
|
||
|
||
# Tambahkan ke grup sudo
|
||
usermod -aG sudo botuser
|
||
|
||
# Switch ke user baru
|
||
su - botuser
|
||
```
|
||
|
||
## 3. Setup Project Bot WhatsApp
|
||
|
||
```bash
|
||
# Buat direktori project
|
||
mkdir ~/whatsapp-bot
|
||
cd ~/whatsapp-bot
|
||
|
||
# Inisialisasi npm project
|
||
npm init -y
|
||
|
||
# Install dependencies
|
||
npm install @whiskeysockets/baileys qrcode-terminal
|
||
|
||
# Buat struktur folder
|
||
mkdir session
|
||
mkdir logs
|
||
```
|
||
|
||
## 4. Buat File Bot
|
||
|
||
Buat file `bot.js`:
|
||
|
||
```bash
|
||
nano bot.js
|
||
```
|
||
|
||
Copy paste kode berikut:
|
||
|
||
```javascript
|
||
const { default: makeWASocket, DisconnectReason, useMultiFileAuthState } = require('@whiskeysockets/baileys')
|
||
const fs = require('fs')
|
||
|
||
// Fungsi untuk log dengan timestamp
|
||
function log(message) {
|
||
const timestamp = new Date().toISOString()
|
||
const logMessage = `[${timestamp}] ${message}`
|
||
console.log(logMessage)
|
||
|
||
// Simpan ke file log
|
||
fs.appendFileSync('./logs/bot.log', logMessage + '\n')
|
||
}
|
||
|
||
async function startBot() {
|
||
try {
|
||
// Setup authentikasi
|
||
const { state, saveCreds } = await useMultiFileAuthState('./session')
|
||
|
||
// Buat koneksi WhatsApp
|
||
const sock = makeWASocket({
|
||
auth: state,
|
||
printQRInTerminal: true,
|
||
browser: ['Bot WhatsApp', 'Chrome', '1.0.0']
|
||
})
|
||
|
||
// Event ketika koneksi berubah
|
||
sock.ev.on('connection.update', async (update) => {
|
||
const { connection, lastDisconnect, qr } = update
|
||
|
||
if (qr) {
|
||
log('📱 QR Code generated! Scan dengan WhatsApp Anda.')
|
||
}
|
||
|
||
if (connection === 'close') {
|
||
const shouldReconnect = lastDisconnect?.error?.output?.statusCode !== DisconnectReason.loggedOut
|
||
log(`â<>Œ Koneksi terputus: ${lastDisconnect?.error?.output?.statusCode}`)
|
||
|
||
if (shouldReconnect) {
|
||
log('🔄 Mencoba reconnect dalam 5 detik...')
|
||
setTimeout(() => startBot(), 5000)
|
||
} else {
|
||
log('ðŸ”<C5B8> Bot logout. Perlu scan QR lagi.')
|
||
}
|
||
} else if (connection === 'open') {
|
||
log('✅ Bot WhatsApp berhasil terhubung!')
|
||
|
||
// Kirim pesan ke diri sendiri sebagai test
|
||
const myNumber = sock.user?.id
|
||
if (myNumber) {
|
||
await sock.sendMessage(myNumber, {
|
||
text: '🤖 Bot WhatsApp berhasil online!\n\nBot siap menerima pesan.'
|
||
})
|
||
}
|
||
}
|
||
})
|
||
|
||
// Simpan kredensial ketika berubah
|
||
sock.ev.on('creds.update', saveCreds)
|
||
|
||
// Event ketika ada pesan masuk
|
||
sock.ev.on('messages.upsert', async (messageUpdate) => {
|
||
try {
|
||
const messages = messageUpdate.messages
|
||
|
||
for (const message of messages) {
|
||
// Skip pesan dari bot sendiri
|
||
if (message.key.fromMe) continue
|
||
|
||
// Skip status updates
|
||
if (message.key.remoteJid === 'status@broadcast') continue
|
||
|
||
// Ambil informasi pesan
|
||
const text = message.message?.conversation ||
|
||
message.message?.extendedTextMessage?.text || ''
|
||
|
||
if (!text) continue
|
||
|
||
const sender = message.key.remoteJid
|
||
const senderName = message.pushName || 'Unknown'
|
||
const isGroup = sender.endsWith('@g.us')
|
||
|
||
log(`📩 Pesan ${isGroup ? 'grup' : 'pribadi'} dari ${senderName}: ${text}`)
|
||
|
||
// Handle pesan
|
||
await handleMessage(sock, sender, text.toLowerCase().trim(), senderName, isGroup)
|
||
}
|
||
} catch (error) {
|
||
log(`â<>Œ Error processing messages: ${error.message}`)
|
||
}
|
||
})
|
||
|
||
return sock
|
||
|
||
} catch (error) {
|
||
log(`â<>Œ Error starting bot: ${error.message}`)
|
||
log('🔄 Restart bot dalam 10 detik...')
|
||
setTimeout(() => startBot(), 10000)
|
||
}
|
||
}
|
||
|
||
// Fungsi untuk menangani pesan
|
||
async function handleMessage(sock, sender, message, senderName, isGroup) {
|
||
try {
|
||
let response = ''
|
||
|
||
// Perintah bot
|
||
switch (message) {
|
||
case '/start':
|
||
case '/help':
|
||
response = `🤖 *Bot WhatsApp Server*\n\n` +
|
||
`Halo ${senderName}! Bot berjalan di Ubuntu VPS.\n\n` +
|
||
`*Perintah tersedia:*\n` +
|
||
`🆘 /help - Menu bantuan\n` +
|
||
`â<>° /time - Waktu server\n` +
|
||
`📊 /status - Status server\n` +
|
||
`🎲 /random - Angka random\n` +
|
||
`ðŸ“<C5B8> /ping - Test koneksi\n` +
|
||
`ℹï¸<C3AF> /info - Info bot`
|
||
break
|
||
|
||
case '/time':
|
||
const now = new Date().toLocaleString('id-ID', {
|
||
timeZone: 'Asia/Jakarta',
|
||
dateStyle: 'full',
|
||
timeStyle: 'medium'
|
||
})
|
||
response = `â<>° *Waktu Server*\n${now}\n\nðŸ“<C5B8> Timezone: Asia/Jakarta (WIB)`
|
||
break
|
||
|
||
case '/status':
|
||
const uptime = process.uptime()
|
||
const uptimeFormatted = Math.floor(uptime / 3600) + 'h ' +
|
||
Math.floor((uptime % 3600) / 60) + 'm ' +
|
||
Math.floor(uptime % 60) + 's'
|
||
|
||
const memUsage = process.memoryUsage()
|
||
const memUsed = Math.round(memUsage.heapUsed / 1024 / 1024)
|
||
|
||
response = `📊 *Status Server*\n\n` +
|
||
`🟢 Status: Online\n` +
|
||
`â<>±ï¸<C3AF> Uptime: ${uptimeFormatted}\n` +
|
||
`💾 Memory: ${memUsed} MB\n` +
|
||
`🖥ï¸<C3AF> OS: Ubuntu 24.04 LTS\n` +
|
||
`âš¡ Node.js: ${process.version}`
|
||
break
|
||
|
||
case '/ping':
|
||
const startTime = Date.now()
|
||
response = `ðŸ<C3B0>“ *Pong!*\n\nâš¡ Latency: ${Date.now() - startTime}ms\n🟢 Bot responsive`
|
||
break
|
||
|
||
case '/random':
|
||
const randomNum = Math.floor(Math.random() * 100) + 1
|
||
response = `🎲 *Random Number*\n\nAngka untuk ${senderName}: *${randomNum}*`
|
||
break
|
||
|
||
case '/info':
|
||
response = `ℹï¸<C3AF> *Bot Information*\n\n` +
|
||
`🤖 Bot WhatsApp Server\n` +
|
||
`🖥ï¸<C3AF> Platform: Ubuntu VPS\n` +
|
||
`📡 API: Baileys WhatsApp\n` +
|
||
`âš¡ Runtime: Node.js\n` +
|
||
`🔧 Status: Production Ready\n` +
|
||
`📅 Started: ${new Date().toLocaleDateString('id-ID')}`
|
||
break
|
||
|
||
default:
|
||
// Auto-reply untuk pesan umum
|
||
if (message.includes('halo') || message.includes('hai') || message.includes('hello')) {
|
||
response = `👋 Halo ${senderName}!\n\nBot berjalan dari Ubuntu VPS. Ketik /help untuk melihat perintah tersedia.`
|
||
} else if (message.includes('bot')) {
|
||
response = `🤖 Ya, saya bot WhatsApp yang berjalan di server Ubuntu!\n\nKetik /help untuk menu lengkap.`
|
||
} else if (message.includes('terima kasih') || message.includes('thanks')) {
|
||
response = `ðŸ™<C5B8> Sama-sama ${senderName}! Senang bisa membantu.`
|
||
} else {
|
||
// Respon default dengan rate limiting
|
||
if (!isGroup) { // Hanya reply di chat pribadi
|
||
response = `ðŸ“<C5B8> Pesan diterima: "${message}"\n\n✨ Ketik /help untuk melihat perintah yang tersedia!`
|
||
}
|
||
}
|
||
}
|
||
|
||
// Kirim respon (jika ada)
|
||
if (response) {
|
||
// Delay untuk avoid spam detection
|
||
await new Promise(resolve => setTimeout(resolve, 1000))
|
||
|
||
await sock.sendMessage(sender, { text: response })
|
||
log(`✅ Respon terkirim ke ${senderName}`)
|
||
}
|
||
|
||
} catch (error) {
|
||
log(`â<>Œ Error handling message: ${error.message}`)
|
||
|
||
// Kirim pesan error ke user
|
||
try {
|
||
await sock.sendMessage(sender, {
|
||
text: 'âš ï¸<C3AF> Terjadi error saat memproses pesan. Tim teknis sudah diberitahu.'
|
||
})
|
||
} catch (sendError) {
|
||
log(`â<>Œ Error sending error message: ${sendError.message}`)
|
||
}
|
||
}
|
||
}
|
||
|
||
// Graceful shutdown
|
||
process.on('SIGINT', () => {
|
||
log('🛑 Bot dihentikan oleh user (SIGINT)')
|
||
process.exit(0)
|
||
})
|
||
|
||
process.on('SIGTERM', () => {
|
||
log('🛑 Bot dihentikan oleh sistem (SIGTERM)')
|
||
process.exit(0)
|
||
})
|
||
|
||
// Handle unhandled errors
|
||
process.on('uncaughtException', (error) => {
|
||
log(`💥 Uncaught Exception: ${error.message}`)
|
||
log('🔄 Restarting bot...')
|
||
setTimeout(() => startBot(), 5000)
|
||
})
|
||
|
||
process.on('unhandledRejection', (error) => {
|
||
log(`💥 Unhandled Rejection: ${error.message}`)
|
||
})
|
||
|
||
// Mulai bot
|
||
log('🚀 Starting WhatsApp Bot on Ubuntu VPS...')
|
||
startBot()
|
||
```
|
||
|
||
Simpan dengan `Ctrl+X`, lalu `Y`, lalu `Enter`.
|
||
|
||
## 5. Install PM2 untuk Production
|
||
|
||
```bash
|
||
# Install PM2 globally
|
||
sudo npm install -g pm2
|
||
|
||
# Buat file konfigurasi PM2
|
||
nano ecosystem.config.js
|
||
```
|
||
|
||
Isi file `ecosystem.config.js`:
|
||
|
||
```javascript
|
||
module.exports = {
|
||
apps: [{
|
||
name: 'whatsapp-bot',
|
||
script: 'bot.js',
|
||
instances: 1,
|
||
autorestart: true,
|
||
watch: false,
|
||
max_memory_restart: '500M',
|
||
error_file: './logs/err.log',
|
||
out_file: './logs/out.log',
|
||
log_file: './logs/combined.log',
|
||
time: true,
|
||
env: {
|
||
NODE_ENV: 'production'
|
||
}
|
||
}]
|
||
}
|
||
```
|
||
|
||
## 6. Menjalankan Bot
|
||
|
||
```bash
|
||
# Test jalankan sekali untuk scan QR
|
||
node bot.js
|
||
|
||
# Setelah berhasil scan QR, hentikan dengan Ctrl+C
|
||
# Lalu jalankan dengan PM2
|
||
pm2 start ecosystem.config.js
|
||
|
||
# Lihat status
|
||
pm2 status
|
||
|
||
# Lihat logs real-time
|
||
pm2 logs whatsapp-bot
|
||
|
||
# Auto-start saat server restart
|
||
pm2 startup
|
||
pm2 save
|
||
```
|
||
|
||
## 7. Setup Firewall (Optional tapi Recommended)
|
||
|
||
```bash
|
||
# Enable UFW firewall
|
||
sudo ufw enable
|
||
|
||
# Allow SSH
|
||
sudo ufw allow ssh
|
||
|
||
# Allow specific ports jika perlu
|
||
# sudo ufw allow 3000/tcp
|
||
|
||
# Check status
|
||
sudo ufw status
|
||
```
|
||
|
||
## 8. Monitoring dan Maintenance
|
||
|
||
```bash
|
||
# Restart bot
|
||
pm2 restart whatsapp-bot
|
||
|
||
# Stop bot
|
||
pm2 stop whatsapp-bot
|
||
|
||
# Delete bot dari PM2
|
||
pm2 delete whatsapp-bot
|
||
|
||
# Monitor resource usage
|
||
pm2 monit
|
||
|
||
# View logs
|
||
pm2 logs whatsapp-bot --lines 100
|
||
|
||
# Rotate logs
|
||
pm2 install pm2-logrotate
|
||
```
|
||
|
||
## 9. Backup Session (Penting!)
|
||
|
||
```bash
|
||
# Buat backup session
|
||
tar -czf session-backup.tar.gz session/
|
||
|
||
# Restore session
|
||
tar -xzf session-backup.tar.gz
|
||
```
|
||
|
||
## 10. Troubleshooting
|
||
|
||
### Jika QR Code tidak muncul:
|
||
```bash
|
||
# Install font untuk QR display
|
||
sudo apt install fonts-liberation2
|
||
|
||
# Atau gunakan external QR generator
|
||
npm install qrcode
|
||
```
|
||
|
||
### Jika ada masalah permission:
|
||
```bash
|
||
# Fix ownership
|
||
sudo chown -R botuser:botuser ~/whatsapp-bot
|
||
|
||
# Fix permissions
|
||
chmod +x bot.js
|
||
```
|
||
|
||
### Jika bot crash terus:
|
||
```bash
|
||
# Check logs
|
||
pm2 logs whatsapp-bot
|
||
|
||
# Clear session dan scan ulang
|
||
rm -rf session/*
|
||
pm2 restart whatsapp-bot
|
||
```
|
||
|
||
---
|
||
|
||
## ✅ Checklist Setup
|
||
|
||
- [ ] Update Ubuntu & install dependencies
|
||
- [ ] Install Node.js & npm
|
||
- [ ] Buat project directory
|
||
- [ ] Copy kode bot
|
||
- [ ] Install PM2
|
||
- [ ] Test run bot & scan QR
|
||
- [ ] Setup PM2 production
|
||
- [ ] Enable auto-restart
|
||
- [ ] Backup session
|
||
|
||
**Bot WhatsApp Anda siap production di Ubuntu VPS! 🎉** |