feat: implement FastAPI service with device-locked automation for Shopee commissions and Facebook commenting

This commit is contained in:
Victor Phan
2026-07-23 12:22:15 +07:00
parent 3d00741e7b
commit 2bd6cfef55
1558 changed files with 389 additions and 191545 deletions
+57 -7
View File
@@ -5,6 +5,14 @@ from typing import Optional
import logging
import os
import sys
import urllib.request
import uuid
import threading
from collections import defaultdict
from facebook_bot import FacebookBot
# Quản lý hàng đợi (Lock) cho từng thiết bị
device_locks = defaultdict(threading.Lock)
# Cấu hình logging: ghi log ra cả màn hình (console) và file (shopee_bot.log)
logging.basicConfig(
@@ -23,19 +31,26 @@ class CommissionRequest(BaseModel):
# Cho phép truyền IP linh hoạt từ n8n.
device_ip: Optional[str] = Field(default=None, description="IP:Port của điện thoại, ví dụ 192.168.1.100:5555 (WiFi) hoặc 10.8.0.5:5555 (VPN)")
class FacebookCommentRequest(BaseModel):
device_ip: Optional[str] = Field(default=None, description="IP:Port của điện thoại (Cấu hình trên n8n)")
group_id: str
content: str
image_url: Optional[str] = None
@app.post("/get_commission")
async def get_commission_endpoint(req: CommissionRequest):
def get_commission_endpoint(req: CommissionRequest):
if not req.link:
raise HTTPException(status_code=400, detail="Thiếu link sản phẩm")
try:
# Lấy IP theo độ ưu tiên:
# 1. Truyền từ Request Body của n8n
# 2. Truyền từ biến môi trường DEVICE_IP của Armbian/Windows
# 3. Để rỗng "" (Thư viện u2 sẽ tự tìm thiết bị ADB đang cắm/connect)
target_ip = req.device_ip or os.environ.get("DEVICE_IP") or ""
# Lấy IP theo độ ưu tiên
raw_ip = req.device_ip or os.environ.get("DEVICE_IP") or ""
lock_key = raw_ip if raw_ip else "default_device"
bot = ShopeeBot(device_ip=target_ip)
# Dùng Lock để xếp hàng: Nếu điện thoại đang bận, request sau phải chờ
with device_locks[lock_key]:
logging.info(f"Đã khóa thiết bị {lock_key} để chạy tác vụ Shopee.")
bot = ShopeeBot(device_ip=raw_ip)
result = bot.get_commission_rate(req.link)
@@ -51,6 +66,41 @@ async def get_commission_endpoint(req: CommissionRequest):
logging.error(f"Lỗi API: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))
@app.post("/post_facebook_comment")
def post_facebook_comment(req: FacebookCommentRequest):
try:
raw_ip = req.device_ip or os.environ.get("DEVICE_IP") or ""
lock_key = raw_ip if raw_ip else "default_device"
with device_locks[lock_key]:
logging.info(f"Đã khóa thiết bị {lock_key} để chạy tác vụ Facebook.")
bot = FacebookBot(device_ip=raw_ip)
local_image_path = None
if req.image_url:
# Tải ảnh về máy chủ Python tạm thời
local_image_path = f"temp_fb_{uuid.uuid4().hex}.jpg"
urllib.request.urlretrieve(req.image_url, local_image_path)
logging.info(f"Đã tải ảnh tạm thời: {local_image_path}")
result = bot.post_comment(req.group_id, req.content, local_image_path)
# Dọn dẹp ảnh tạm sau khi xong
if local_image_path and os.path.exists(local_image_path):
os.remove(local_image_path)
logging.info(f"Đã xóa ảnh tạm: {local_image_path}")
if isinstance(result, dict) and "status" in result:
if result["status"] == "error":
raise HTTPException(status_code=500, detail=result.get("message"))
return result
return {"status": "success", "message": "Hoàn tất"}
except Exception as e:
logging.error(f"Lỗi API Facebook: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
import uvicorn
# Chạy server API ở cổng 8000