diff --git a/serverPython/facebook_bot.py b/serverPython/facebook_bot.py index 0e82c5c..ea6c177 100644 --- a/serverPython/facebook_bot.py +++ b/serverPython/facebook_bot.py @@ -14,9 +14,15 @@ class FacebookBot: logging.warning("Không có file ảnh cục bộ để đẩy lên điện thoại.") return False + import uuid logging.info(f"Đang đẩy ảnh {local_image_path} vào điện thoại...") - # Đẩy ảnh vào thư mục Pictures - remote_path = "/sdcard/Pictures/n8n_fb_comment.jpg" + # Tạo tên file độc nhất để đảm bảo luôn hiện lên ĐẦU thư viện ảnh + random_name = f"n8n_fb_{uuid.uuid4().hex[:8]}.jpg" + remote_path = f"/sdcard/Pictures/{random_name}" + + # Xóa bớt các file tạm cũ trước khi đẩy file mới (giữ điện thoại sạch sẽ) + self.d.shell("rm -f /sdcard/Pictures/n8n_fb_*.jpg") + self.d.push(local_image_path, remote_path) # Gọi Media Scanner để Thư viện ảnh nhận diện ngay lập tức @@ -111,11 +117,16 @@ class FacebookBot: time.sleep(3) self.dump_ui_for_debug("fb_step5_camera_opened.xml") - # Chọn ảnh đầu tiên trong thư viện (vừa mới push vào) - # Facebook gallery thường có checkbox hoặc chỉ cần click vào vùng ảnh - gallery_images = self.d(className="android.widget.ImageView") - if gallery_images.count >= 2: - gallery_images[1].click() # Bỏ qua icon đầu tiên thường là icon camera + # Facebook gallery mới dùng Button với description 'Ảnh, mục X...' + gallery_images = self.d(descriptionContains="Ảnh, mục") + if not gallery_images.exists: + gallery_images = self.d(descriptionContains="Photo") + if not gallery_images.exists: + gallery_images = self.d(descriptionContains="Ảnh") + + if gallery_images.exists: + # Bấm vào ảnh đầu tiên (ảnh vừa mới push vào điện thoại sẽ nằm ở đầu danh sách) + gallery_images[0].click() time.sleep(1) self.dump_ui_for_debug("fb_step6_image_selected.xml") diff --git a/serverPython/main.py b/serverPython/main.py index 6e6cab3..dbdf998 100644 --- a/serverPython/main.py +++ b/serverPython/main.py @@ -38,6 +38,7 @@ class FacebookCommentRequest(BaseModel): group_id: Any content: str image_url: Optional[str] = None + image_base64: Optional[str] = None @app.post("/get_commission") def get_commission_endpoint(req: CommissionRequest): @@ -79,18 +80,47 @@ def post_facebook_comment(req: FacebookCommentRequest): 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 + if req.image_base64: + import base64 + # Bỏ phần header data:image/jpeg;base64, nếu có + b64_data = req.image_base64 + if "," in b64_data: + b64_data = b64_data.split(",", 1)[1] + local_image_path = f"temp_fb_{uuid.uuid4().hex}.jpg" - urllib.request.urlretrieve(str(req.image_url), local_image_path) - logging.info(f"Đã tải ảnh tạm thời: {local_image_path}") + with open(local_image_path, "wb") as f: + f.write(base64.b64decode(b64_data)) + logging.info(f"Đã tạo ảnh từ chuỗi Base64: {local_image_path}") + + elif req.image_url: + import re + url = str(req.image_url) + + # Kiểm tra xem url có phải là một đường dẫn file nội bộ trên máy hay không + if os.path.exists(url): + local_image_path = url + logging.info(f"Sử dụng file ảnh nội bộ có sẵn: {local_image_path}") + else: + # Tự động chuyển link Google Drive sang link tải trực tiếp + if "drive.google.com" in url: + file_id_match = re.search(r"/d/([a-zA-Z0-9_-]+)", url) + if file_id_match: + file_id = file_id_match.group(1) + url = f"https://drive.google.com/uc?export=download&id={file_id}" + logging.info(f"Đã convert link Google Drive thành direct link: {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(url, local_image_path) + logging.info(f"Đã tải ảnh tạm thời từ internet: {local_image_path}") result = bot.post_comment(str(req.group_id), str(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 "temp_fb_" in local_image_path: + os.remove(local_image_path) + logging.info(f"Đã dọn dẹp file tạm: {local_image_path}") if isinstance(result, dict) and "status" in result: # Trả về luôn JSON kết quả, n8n sẽ nhận HTTP 200 và tiếp tục vòng lặp