205 lines
6.4 KiB
Python
205 lines
6.4 KiB
Python
import os
|
|
import time
|
|
import random
|
|
import requests
|
|
import schedule
|
|
import logging
|
|
from datetime import datetime
|
|
from dotenv import load_dotenv
|
|
from ai_generator import generate_bot_data
|
|
|
|
load_dotenv()
|
|
|
|
# Setup Logging
|
|
log_filename = "bot_activity.log"
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format='%(asctime)s [%(levelname)s] %(message)s',
|
|
handlers=[
|
|
logging.FileHandler(log_filename),
|
|
logging.StreamHandler()
|
|
]
|
|
)
|
|
|
|
BACKEND_URL = os.getenv("BACKEND_URL", "http://localhost:3001/api")
|
|
BOT_SECRET = os.getenv("BOT_API_SECRET", "")
|
|
BOT_MODE = os.getenv("BOT_MODE", "PROD").upper() # TEST or PROD
|
|
|
|
# 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"))
|
|
|
|
def smart_sleep(seconds):
|
|
"""Sleep only if BOT_MODE is PROD"""
|
|
if BOT_MODE == "PROD":
|
|
log(f"Sleeping for {seconds}s...")
|
|
time.sleep(seconds)
|
|
else:
|
|
log("Skipping delay (TEST mode)")
|
|
|
|
headers = {
|
|
"Content-Type": "application/json",
|
|
"x-bot-api-key": BOT_SECRET
|
|
}
|
|
|
|
def log(msg):
|
|
logging.info(msg)
|
|
|
|
def run_service_simulation():
|
|
"""Menjalankan 1 siklus transaksi Layanan/Service"""
|
|
log("--- Memulai 1 Siklus Transaksi LAYANAN ---")
|
|
|
|
# 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']
|
|
user1 = res_data1['data']['user1']
|
|
user2 = res_data1['data']['user2']
|
|
log(f"Accounts created! Provider: {user1['name']} ({user1['email']}), Buyer: {user2['name']} ({user2['email']})")
|
|
|
|
smart_sleep(random.randint(60, 180))
|
|
|
|
# 3. Create Service
|
|
log("Step 2: Create Service")
|
|
req2 = requests.post(f"{BACKEND_URL}/bot/create-service", json={
|
|
"providerId": provider_id,
|
|
"data": ai_data
|
|
}, headers=headers)
|
|
if req2.status_code != 200:
|
|
log(f"Failed to create service: {req2.text}")
|
|
return False
|
|
|
|
res_data2 = req2.json()
|
|
service_id = res_data2['data']['id']
|
|
log(f"Service created! '{res_data2['data']['name']}' - Price: Rp {res_data2['data']['price']}")
|
|
|
|
smart_sleep(random.randint(120, 300))
|
|
|
|
# 4. Simulate Transaction
|
|
log("Step 3: Place Order (Service)")
|
|
req3 = requests.post(f"{BACKEND_URL}/bot/simulate-transaction", json={
|
|
"buyerId": buyer_id,
|
|
"providerId": provider_id,
|
|
"serviceId": service_id,
|
|
"data": ai_data
|
|
}, headers=headers)
|
|
|
|
if req3.status_code != 200:
|
|
log(f"Failed to simulate transaction: {req3.text}")
|
|
return False
|
|
|
|
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']
|
|
user1 = res_data1['data']['user1']
|
|
user2 = res_data1['data']['user2']
|
|
log(f"Accounts created! Provider: {user1['name']} ({user1['email']}), Buyer: {user2['name']} ({user2['email']})")
|
|
|
|
smart_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()
|
|
job_title = res_data2['data']['job']['title']
|
|
order_id = res_data2['data']['transaction']['orderId']
|
|
log(f"Job Transaction Completed! Job: '{job_title}', OrderID: {order_id}")
|
|
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)
|
|
smart_sleep(batch_delay)
|
|
|
|
log(f"=== Batch Selesai: {success_count}/{len(tasks)} Berhasil ===")
|
|
|
|
if __name__ == "__main__":
|
|
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})")
|
|
|
|
# Mode Langsung
|
|
run_job()
|
|
|
|
|
|
# Mode Scheduler (Opsional untuk VPS)
|
|
# schedule.every().day.at("09:00").do(run_job)
|
|
# while True:
|
|
# schedule.run_pending()
|
|
# time.sleep(60)
|