update: flow transaction service and job

This commit is contained in:
2026-05-13 21:00:45 +07:00
parent e1296e3c48
commit 023f1f5929
4 changed files with 139 additions and 41 deletions

5
.env Normal file
View File

@@ -0,0 +1,5 @@
OPENROUTER_API_KEY=your_key_here
BOT_API_SECRET=microjob_bot_secret_2024
BACKEND_URL=http://localhost:3001/api
TRANSACTION_TYPES=SERVICE,JOB
COUNT_PER_TYPE=1

View File

@@ -1,4 +1,5 @@
OPENROUTER_API_KEY=your_openrouter_api_key_here OPENROUTER_API_KEY=your_openrouter_api_key_here
BOT_API_SECRET=your_super_secret_bot_key BOT_API_SECRET=your_super_secret_bot_key
BACKEND_URL=http://localhost:3001/api BACKEND_URL=http://localhost:3001/api
TRANSACTION_TYPES=SERVICE,JOB
COUNT_PER_TYPE=1

View File

@@ -4,10 +4,10 @@ Bot ini dirancang untuk mensimulasikan aktivitas nyata di platform Microjob (mem
## 🚀 Fitur Utama ## 🚀 Fitur Utama
- **AI-Driven Data**: Menggunakan OpenRouter (Llama-3) untuk menghasilkan nama orang Indonesia, nama bisnis profesional, deskripsi, hingga ulasan yang realistis. - **Dual Flow Simulation**: Mendukung simulasi transaksi **Layanan** (pembelian langsung) dan **Lowongan** (post job -> lamar -> terima).
- **Dynamic Location**: Menghasilkan koordinat (Lat/Lng) dan alamat acak di berbagai kota besar di Indonesia. - **AI-Driven Data**: Menggunakan OpenRouter (Gemini/Llama) untuk menghasilkan persona Indonesia yang realistis.
- **Smart Simulation**: Meniru perilaku manusia dengan jeda waktu (*delay*) antar tindakan. - **Natural Behavior**: Meniru perilaku manusia dengan jeda waktu acak dan pengacakan urutan transaksi.
- **Automated Transactions**: Melewati gerbang pembayaran (*skip payment*) untuk memudahkan simulasi internal. - **Automated Transactions**: Melewati gerbang pembayaran untuk memudahkan pengisian data internal.
## 🛠️ Instalasi ## 🛠️ Instalasi
@@ -29,22 +29,29 @@ Buat file `.env` (salin dari `.env.example`) dan isi variabel berikut:
OPENROUTER_API_KEY=your_key_here OPENROUTER_API_KEY=your_key_here
BOT_API_SECRET=your_backend_bot_secret BOT_API_SECRET=your_backend_bot_secret
BACKEND_URL=http://localhost:3001/api BACKEND_URL=http://localhost:3001/api
TRANSACTION_TYPES=SERVICE,JOB
COUNT_PER_TYPE=1
``` ```
- `OPENROUTER_API_KEY`: Kunci API Anda dari [OpenRouter](https://openrouter.ai/). - `OPENROUTER_API_KEY`: Kunci API dari [OpenRouter](https://openrouter.ai/).
- `BOT_API_SECRET`: Kunci rahasia yang harus sama dengan yang ada di `.env` backend Anda (untuk otentikasi API Bot). - `BOT_API_SECRET`: Kunci rahasia yang **harus sama** dengan yang ada di `.env` backend Anda.
- `BACKEND_URL`: URL API backend Microjob Anda. - `TRANSACTION_TYPES`: Tipe transaksi yang ingin dijalankan (`SERVICE`, `JOB`, atau keduanya dipisah koma).
- `COUNT_PER_TYPE`: Berapa kali setiap tipe transaksi dijalankan dalam satu kali running.
## 🏁 Cara Menjalankan ## 🏁 Cara Menjalankan
### Jalankan Simulasi Sekali (On-Demand) ### Jalankan Sekali (On-Demand / Cron Job)
Untuk menjalankan satu siklus simulasi (Buat Akun -> Buat Jasa -> Order -> Selesai) secara instan: Untuk menjalankan simulasi sesuai jumlah di `.env` lalu berhenti:
```bash ```bash
python main.py python main.py
``` ```
### Jalankan Sebagai Scheduler (Harian) ### Jalankan Sebagai Background Service (VPS)
Bot ini mendukung penjadwalan otomatis. Anda bisa mengaktifkan bagian `schedule` di dalam `main.py` agar bot berjalan otomatis setiap hari pada jam tertentu. Anda bisa menggunakan **PM2** agar bot ini berjalan terus dan otomatis restart jika terjadi error:
```bash
pm2 start main.py --name "microjob-bot" --interpreter python3
```
## 📂 Struktur Folder ## 📂 Struktur Folder

141
main.py
View File

@@ -11,6 +11,12 @@ load_dotenv()
BACKEND_URL = os.getenv("BACKEND_URL", "http://localhost:3001/api") BACKEND_URL = os.getenv("BACKEND_URL", "http://localhost:3001/api")
BOT_SECRET = os.getenv("BOT_API_SECRET", "") BOT_SECRET = os.getenv("BOT_API_SECRET", "")
# Ambil list tipe transaksi dari ENV (misal: "SERVICE,JOB")
ALLOWED_TYPES = os.getenv("TRANSACTION_TYPES", "SERVICE,JOB").split(",")
# Ambil jumlah transaksi per tipe
COUNT_PER_TYPE = int(os.getenv("COUNT_PER_TYPE", "1"))
headers = { headers = {
"Content-Type": "application/json", "Content-Type": "application/json",
"x-bot-api-key": BOT_SECRET "x-bot-api-key": BOT_SECRET
@@ -19,75 +25,154 @@ headers = {
def log(msg): def log(msg):
print(f"[BOT] {time.strftime('%Y-%m-%d %H:%M:%S')} - {msg}") print(f"[BOT] {time.strftime('%Y-%m-%d %H:%M:%S')} - {msg}")
def run_daily_simulation(): def run_service_simulation():
log("=== Memulai Simulasi Transaksi Harian ===") """Menjalankan 1 siklus transaksi Layanan/Service"""
log("--- Memulai 1 Siklus Transaksi LAYANAN ---")
# 1. Generate Data AI # 1. Generate Data AI
log("Generating data using AI...") log("Generating data using AI...")
try:
ai_data = generate_bot_data() ai_data = generate_bot_data()
except Exception as e:
log(f"AI Generation failed: {e}")
return False
# 2. Setup Accounts (Akun 1 & Akun 2) # 2. Setup Accounts
log("Step 1: Setup Accounts") log("Step 1: Setup Accounts")
# TODO: Panggil API Backend
req1 = requests.post(f"{BACKEND_URL}/bot/setup-account", json={"data": ai_data}, headers=headers) req1 = requests.post(f"{BACKEND_URL}/bot/setup-account", json={"data": ai_data}, headers=headers)
if req1.status_code != 200: if req1.status_code != 200:
log(f"Failed to setup accounts: {req1.text}") log(f"Failed to setup accounts: {req1.text}")
return return False
res_data1 = req1.json() res_data1 = req1.json()
provider_id = res_data1['data']['user1']['providerProfile']['id'] provider_id = res_data1['data']['user1']['providerProfile']['id']
buyer_id = res_data1['data']['user2']['id'] buyer_id = res_data1['data']['user2']['id']
log(f"Accounts created! ProviderID: {provider_id}, BuyerID: {buyer_id}") log(f"Accounts created! ProviderID: {provider_id}, BuyerID: {buyer_id}")
# Delay acak agar terlihat natural (misal: 10 - 30 menit) time.sleep(random.randint(60, 180))
delay_minutes = random.randint(10, 30)
log(f"Menunggu {delay_minutes} menit sebelum membuat layanan...")
# time.sleep(delay_minutes * 60) # Uncomment in production
# 3. Create Service # 3. Create Service
log("Step 2: Create Service") log("Step 2: Create Service")
# TODO: Panggil API Backend
req2 = requests.post(f"{BACKEND_URL}/bot/create-service", json={ req2 = requests.post(f"{BACKEND_URL}/bot/create-service", json={
"providerId": provider_id, "providerId": provider_id,
"data": ai_data "data": ai_data
}, headers=headers) }, headers=headers)
if req2.status_code != 200: if req2.status_code != 200:
log(f"Failed to create service: {req2.text}") log(f"Failed to create service: {req2.text}")
return return False
res_data2 = req2.json() res_data2 = req2.json()
service_id = res_data2['data']['id'] service_id = res_data2['data']['id']
log(f"Service created! ServiceID: {service_id}") log(f"Service created! ServiceID: {service_id}")
# Delay tunggu pesanan (misal: 1 - 3 jam) time.sleep(random.randint(120, 300))
delay_hours = random.randint(1, 3)
log(f"Menunggu {delay_hours} jam sebelum simulasi order...")
# time.sleep(delay_hours * 3600) # Uncomment in production
# 4. Simulate Transaction & Payment # 4. Simulate Transaction
log("Step 3: Place Order & Skip Payment") log("Step 3: Place Order (Service)")
# TODO: Panggil API Backend
req3 = requests.post(f"{BACKEND_URL}/bot/simulate-transaction", json={ req3 = requests.post(f"{BACKEND_URL}/bot/simulate-transaction", json={
"buyerId": buyer_id, "buyerId": buyer_id,
"providerId": provider_id, "providerId": provider_id,
"serviceId": service_id, "serviceId": service_id,
"data": ai_data "data": ai_data
}, headers=headers) }, headers=headers)
if req3.status_code != 200: if req3.status_code != 200:
log(f"Failed to simulate transaction: {req3.text}") log(f"Failed to simulate transaction: {req3.text}")
return return False
res_data3 = req3.json()
log(f"Transaction Simulated Successfully! OrderID: {res_data3['data']['orderId']}")
log("=== Simulasi Selesai ===") log(f"Service Transaction Completed! OrderID: {req3.json()['data']['orderId']}")
return True
def run_job_simulation():
"""Menjalankan 1 siklus transaksi Lowongan/Job"""
log("--- Memulai 1 Siklus Transaksi JOB ---")
# 1. Generate Data AI
log("Generating data using AI...")
try:
ai_data = generate_bot_data()
except Exception as e:
log(f"AI Generation failed: {e}")
return False
# 2. Setup Accounts
log("Step 1: Setup Accounts")
req1 = requests.post(f"{BACKEND_URL}/bot/setup-account", json={"data": ai_data}, headers=headers)
if req1.status_code != 200:
log(f"Failed to setup accounts: {req1.text}")
return False
res_data1 = req1.json()
provider_id = res_data1['data']['user1']['providerProfile']['id']
buyer_id = res_data1['data']['user2']['id']
log(f"Accounts created! ProviderID: {provider_id}, BuyerID: {buyer_id}")
time.sleep(random.randint(120, 300))
# 3. Simulate Job Transaction (Post Job -> Apply -> Accept -> Transact)
log("Step 2: Simulate Job Lifecycle")
req2 = requests.post(f"{BACKEND_URL}/bot/simulate-job", json={
"buyerId": buyer_id,
"providerId": provider_id,
"data": ai_data
}, headers=headers)
if req2.status_code != 200:
log(f"Failed to simulate job: {req2.text}")
return False
res_data2 = req2.json()
log(f"Job Transaction Completed! JobID: {res_data2['data']['job']['id']}, OrderID: {res_data2['data']['transaction']['orderId']}")
return True
def run_job():
# Bersihkan whitespace dari list tipe
types = [t.strip().upper() for t in ALLOWED_TYPES if t.strip()]
log(f"=== Memulai Batch Harian: Tipe={types}, Jumlah/Tipe={COUNT_PER_TYPE} ===")
# Gabungkan semua tugas dan acak urutannya agar natural
tasks = []
for t in types:
tasks.extend([t] * COUNT_PER_TYPE)
random.shuffle(tasks)
success_count = 0
for i, task_type in enumerate(tasks):
log(f"Eksekusi ke-{i+1} dari {len(tasks)}: {task_type}")
success = False
if task_type == 'SERVICE':
success = run_service_simulation()
elif task_type == 'JOB':
success = run_job_simulation()
else:
log(f"Tipe transaksi '{task_type}' tidak dikenali. Melewati...")
continue
if success:
success_count += 1
# Jeda antar simulasi dalam batch (15-45 menit)
if i < len(tasks) - 1:
batch_delay = random.randint(900, 2700)
log(f"Jeda antar simulasi batch: {batch_delay} detik...")
time.sleep(batch_delay)
log(f"=== Batch Selesai: {success_count}/{len(tasks)} Berhasil ===")
if __name__ == "__main__": if __name__ == "__main__":
log("Bot Juaskill Started!") types = [t.strip().upper() for t in ALLOWED_TYPES if t.strip()]
total_trx = len(types) * COUNT_PER_TYPE
log(f"Bot Juaskill Started! (Target: {total_trx} trx/hari dari tipe: {types})")
# Jadwalkan bot untuk jalan 1 kali setiap hari di jam random antara 08:00 - 10:00 pagi # Mode Langsung
# Untuk testing, kita jalankan langsung 1x run_job()
run_daily_simulation()
# Uncomment untuk menjalankan scheduler
# schedule.every().day.at("09:00").do(run_daily_simulation) # Mode Scheduler (Opsional untuk VPS)
# schedule.every().day.at("09:00").do(run_job)
# while True: # while True:
# schedule.run_pending() # schedule.run_pending()
# time.sleep(60) # time.sleep(60)