import os import requests import mimetypes from te...
Tạo vào: 13 tháng 12, 2025
Trả lời bằng GPT-5.1 Thinking bởi Chat01
Tạo vào: 13 tháng 12, 2025
Trả lời bằng GPT-5.1 Thinking bởi Chat01
import os
import requests
import mimetypes
from telethon import TelegramClient, events
import google.generativeai as genai
import asyncio
API_ID = '31972804'
API_HASH = 'aa25d83f53ab3f625b071850efb8de29'
TARGET_CHANNEL = 'vmaxgiaitri'
GEMINI_API_KEY = 'AIzaSyAxRutZRTY6H4XvXu62OL4bjtxFPAdaKHk'
GEMINI_MODEL = 'gemini-2.5-flash'
FB_PAGE_ID = '835337329656882'
FB_ACCESS_TOKEN = 'EAAWCpu3800UBQGFoE81vzBkSOPn6sPwAb3qb6wZAe6fJSqmZARstekdbJdSHgSIiZCnzDSbTfZAvgZAKpJSUe6xbGrjVm2ZAgCJWqKSazhgdpZAhZCkZAx3RGhJbkoHLeyxeEB4JetqleUwlPnI860Eny0BNotNUck6slmnC6M6Wk0Q9qKn0v9jpbniMDRYhRxZAmvmJmk'
genai.configure(api_key=GEMINI_API_KEY)
model = genai.GenerativeModel(GEMINI_MODEL)
def call_gemini(prompt, content):
"""Gửi nội dung lên Gemini và lấy caption."""
try:
full_prompt = f"{prompt}\n\nNội dung gốc: {content}"
response = model.generate_content(full_prompt)
return response.text
except Exception as e:
print(f"❌ Lỗi Gemini: {e}")
return None
def post_to_facebook(message, file_path=None):
"""Đăng bài Facebook: text / ảnh / video."""
try:
url = ""
data = {"access_token": FB_ACCESS_TOKEN}
files = {}
textif file_path: mime_type, _ = mimetypes.guess_type(file_path) if mime_type and mime_type.startswith("video"): print("detect: Đang đăng VIDEO...") url = f"https://graph.facebook.com/{FB_PAGE_ID}/videos" data["description"] = message files = {"source": open(file_path, "rb")} else: print("detect: Đang đăng ẢNH...") url = f"https://graph.facebook.com/{FB_PAGE_ID}/photos" data["message"] = message files = {"source": open(file_path, "rb")} else: print("detect: Đang đăng TEXT…") url = f"https://graph.facebook.com/{FB_PAGE_ID}/feed" data["message"] = message if files: response = requests.post(url, data=data, files=files) else: response = requests.post(url, data=data) if files: files["source"].close() if response.status_code == 200: print(f"✅ Đăng thành công, ID = {response.json().get('id')}") else: print(f"❌ Lỗi Facebook ({response.status_code}): {response.text}") except Exception as e: print(f"❌ Lỗi kết nối Facebook: {e}")
client = TelegramClient("anon_session", API_ID, API_HASH)
@client.on(events.NewMessage(chats=TARGET_CHANNEL))
async def main_handler(event):
print("\n------------------------------------------------")
print(f"📩 Nhận tin mới từ: {TARGET_CHANNEL}")
textoriginal_text = event.text or "" media_path = None # --- Tải media nếu có --- if event.message.media: print("📥 Phát hiện media, đang tải xuống...") try: media_path = await event.download_media() print(f"✅ Download thành công: {media_path}") except Exception as e: print(f"⚠️ Lỗi tải media: {e}") # --- Không có gì thì bỏ qua --- if not original_text and not media_path: print("⚠️ Tin nhắn rỗng -> bỏ qua") return # --- Tạo caption với Gemini --- print("🔄 Đang viết caption với Gemini...") prompt_fb = """ Hãy viết một caption Facebook ngắn gọn, viral, hấp dẫn dựa trên nội dung được cung cấp. - Nếu nội dung quá ngắn chuẩn seo facebook, hãy sáng tạo thêm cho phù hợp ngữ cảnh. - Thêm emoji phù hợp. - Giọng văn vui vẻ, lôi cuốn. - Không dùng Markdown. - Mỗi bài viết phải có: Tele: @vmaxhotro. - Thêm hashtag: #Vmax #Vmaxcom #Dangkyvmax #Nhacaivmax #Linkvmax. """ content_input = ( original_text if original_text else "Đây là một bài đăng có hình ảnh/video nhưng không có mô tả. Hãy viết caption hấp dẫn." ) fb_caption = call_gemini(prompt_fb, content_input) if not fb_caption: print("⚠️ Gemini không trả kết quả, dùng text gốc.") fb_caption = original_text # --- Đăng lên Facebook --- post_to_facebook(fb_caption, media_path) # --- Xóa file tải tạm --- if media_path and os.path.exists(media_path): try: os.remove(media_path) print("🧹 Đã xóa file tạm") except: print("⚠️ Không thể xóa file tạm")
print("🚀 Bot Facebook & Telegram đang chạy... Nhấn Ctrl+C để dừng.")
async def main():
await client.start()
await client.run_until_disconnected()
asyncio.run(main())
tôi muốn tự động đăng lên nhiều page
Bạn chỉ cần biến 1 page hiện tại thành danh sách nhiều page rồi loop qua là xong 😊
Dưới đây là cách sửa đơn giản nhất cho code của bạn.
Thay vì:
pythonFB_PAGE_ID = '835337329656882' FB_ACCESS_TOKEN = '...'
Sửa thành:
python# DANH SÁCH CÁC PAGE MUỐN ĐĂNG FB_PAGES = [ { "page_id": "835337329656882", "access_token": "EAAW..." }, { "page_id": "PAGE_ID_THỨ_2", "access_token": "TOKEN_PAGE_2" }, # Thêm nữa nếu cần ]
⚠️ Gợi ý bảo mật: đừng commit mấy token này lên GitHub công khai, nên đọc từ biến môi trường (.env) thì an toàn hơn.
post_to_facebook để dùng page_id & token truyền vàoThay vì dùng 2 biến global FB_PAGE_ID và FB_ACCESS_TOKEN, ta cho vào tham số:
pythondef post_to_facebook(page_id, access_token, message, file_path=None): """Đăng bài Facebook: text / ảnh / video lên 1 page cụ thể.""" try: url = "" data = {"access_token": access_token} files = {} if file_path: mime_type, _ = mimetypes.guess_type(file_path) if mime_type and mime_type.startswith("video"): print(f"[{page_id}] detect: Đang đăng VIDEO...") url = f"https://graph.facebook.com/{page_id}/videos" data["description"] = message files = {"source": open(file_path, "rb")} else: print(f"[{page_id}] detect: Đang đăng ẢNH...") url = f"https://graph.facebook.com/{page_id}/photos" data["message"] = message files = {"source": open(file_path, "rb")} else: print(f"[{page_id}] detect: Đang đăng TEXT…") url = f"https://graph.facebook.com/{page_id}/feed" data["message"] = message if files: response = requests.post(url, data=data, files=files) else: response = requests.post(url, data=data) if files: files["source"].close() if response.status_code == 200: print(f"[{page_id}] ✅ Đăng thành công, ID = {response.json().get('id')}") else: print(f"[{page_id}] ❌ Lỗi Facebook ({response.status_code}): {response.text}") except Exception as e: print(f"[{page_id}] ❌ Lỗi kết nối Facebook: {e}")
Đoạn trong main_handler hiện tại:
python# --- Đăng lên Facebook --- post_to_facebook(fb_caption, media_path)
Sửa thành:
python# --- Đăng lên TẤT CẢ PAGE FACEBOOK --- for page in FB_PAGES: page_id = page["page_id"] access_token = page["access_token"] post_to_facebook(page_id, access_token, fb_caption, media_path)
Thế là mỗi lần nhận message từ Telegram, bot sẽ auto đăng cùng một nội dung/caption (và media nếu có) lên tất cả các page trong FB_PAGES.
FB_PAGES thay cho FB_PAGE_ID / FB_ACCESS_TOKEN.post_to_facebook(page_id, access_token, message, file_path=None).FB_PAGES và gọi post_to_facebook cho từng page.Nếu bạn muốn mỗi page có caption khác nhau (ví dụ thêm hashtag riêng từng page), mình cũng có thể chỉnh logic Gemini hoặc thêm config riêng cho từng page. Nếu bạn muốn, mình viết luôn phiên bản đó cho bạn.
có, giúp tôi viết lại 1 bản hoàn chỉnh
Dưới đây là bản code hoàn chỉnh, đã sửa để:
style_note).✅ Bạn chỉ cần thay API_ID, API_HASH, GEMINI_API_KEY, danh sách FB_PAGES bằng thông tin của bạn là chạy được.
pythonimport os import requests import mimetypes from telethon import TelegramClient, events import google.generativeai as genai import asyncio # ========================================== # PHẦN 1: CẤU HÌNH # ========================================== # --- TELEGRAM BOT / CLIENT --- API_ID = 12345678 # <- THAY BẰNG API ID CỦA BẠN API_HASH = "YOUR_TELEGRAM_API_HASH" # <- THAY BẰNG API HASH CỦA BẠN TARGET_CHANNEL = "vmaxgiaitri" # username channel / group nguồn # --- GEMINI --- GEMINI_API_KEY = "YOUR_GEMINI_API_KEY" # <- THAY BẰNG API KEY GEMINI_MODEL = "gemini-2.5-flash" # --- DANH SÁCH FANPAGE FACEBOOK --- # Mỗi phần tử là 1 page, có thể tuỳ chỉnh style riêng. FB_PAGES = [ { "page_id": "PAGE_ID_1", "access_token": "PAGE_ACCESS_TOKEN_1", "name": "Vmax Giải trí", # chỉ để log & thêm vào prompt "style_note": "Phong cách vui vẻ, gần gũi, kêu gọi đăng ký nhanh." }, { "page_id": "PAGE_ID_2", "access_token": "PAGE_ACCESS_TOKEN_2", "name": "Vmax Kèo Nóng", "style_note": "Nhấn mạnh kèo thơm, ưu đãi, chốt nhanh tay." }, # Thêm page khác nếu cần ] # Gợi ý an toàn hơn (tùy bạn dùng): # FB_PAGES = [ # { # "page_id": os.getenv("FB_PAGE_ID_1", ""), # "access_token": os.getenv("FB_ACCESS_TOKEN_1", ""), # "name": "Vmax Giải trí", # "style_note": "Phong cách vui vẻ, gần gũi, kêu gọi đăng ký nhanh." # }, # ] # ========================================== # PHẦN 2: CẤU HÌNH GEMINI # ========================================== genai.configure(api_key=GEMINI_API_KEY) model = genai.GenerativeModel(GEMINI_MODEL) def call_gemini_for_page(base_prompt: str, content: str, page_config: dict) -> str | None: """ Gửi nội dung lên Gemini để tạo caption cho TỪNG PAGE. Có thêm thông tin tên page + style riêng để caption khác nhau. """ try: page_name = page_config.get("name", "Fanpage Vmax") style_note = page_config.get("style_note", "") full_prompt = f""" {base_prompt} Thông tin fanpage: - Tên fanpage: {page_name} - Phong cách riêng: {style_note} Nội dung gốc (từ Telegram hoặc mô tả media): {content} """ response = model.generate_content(full_prompt) return response.text except Exception as e: print(f"❌ Lỗi Gemini khi xử lý cho page {page_config.get('page_id')}: {e}") return None def build_fallback_caption(content: str, page_config: dict) -> str: """ Caption dự phòng nếu Gemini lỗi. Vẫn đảm bảo có Tele & hashtag. """ page_name = page_config.get("name", "Vmax") base = content.strip() or "Kèo ngon từ nhà cái Vmax, vào chơi ngay anh em!" caption = ( f"{base}\n\n" f"Fanpage: {page_name}\n" f"Tele: @vmaxhotro\n" f"#Vmax #Vmaxcom #Dangkyvmax #Nhacaivmax #Linkvmax" ) return caption def post_to_facebook(page_config: dict, message: str, file_path: str | None = None): """ Đăng bài Facebook: text / ảnh / video lên 1 fanpage cụ thể. """ page_id = page_config["page_id"] access_token = page_config["access_token"] if not page_id or not access_token: print(f"[{page_config.get('name', page_id)}] ⚠️ Thiếu page_id hoặc access_token, bỏ qua.") return try: url = "" data = {"access_token": access_token} files = {} if file_path: mime_type, _ = mimetypes.guess_type(file_path) if mime_type and mime_type.startswith("video"): print(f"[{page_id}] detect: Đang đăng VIDEO...") url = f"https://graph.facebook.com/{page_id}/videos" data["description"] = message files = {"source": open(file_path, "rb")} else: print(f"[{page_id}] detect: Đang đăng ẢNH...") url = f"https://graph.facebook.com/{page_id}/photos" data["message"] = message files = {"source": open(file_path, "rb")} else: print(f"[{page_id}] detect: Đang đăng TEXT…") url = f"https://graph.facebook.com/{page_id}/feed" data["message"] = message if files: response = requests.post(url, data=data, files=files) else: response = requests.post(url, data=data) if files: files["source"].close() if response.status_code == 200: print(f"[{page_id}] ✅ Đăng thành công, ID = {response.json().get('id')}") else: print(f"[{page_id}] ❌ Lỗi Facebook ({response.status_code}): {response.text}") except Exception as e: print(f"[{page_id}] ❌ Lỗi kết nối Facebook: {e}") # ========================================== # PHẦN 3: TELEGRAM LISTENER # ========================================== client = TelegramClient("anon_session", API_ID, API_HASH) @client.on(events.NewMessage(chats=TARGET_CHANNEL)) async def main_handler(event): print("\n------------------------------------------------") print(f"📩 Nhận tin mới từ: {TARGET_CHANNEL}") original_text = event.text or "" media_path = None # --- Tải media nếu có --- if event.message.media: print("📥 Phát hiện media, đang tải xuống...") try: media_path = await event.download_media() print(f"✅ Download thành công: {media_path}") except Exception as e: print(f"⚠️ Lỗi tải media: {e}") # --- Không có text & không có media thì bỏ qua --- if not original_text and not media_path: print("⚠️ Tin nhắn rỗng -> bỏ qua") return # --- Chuẩn bị content đưa cho Gemini --- content_input = ( original_text if original_text else "Đây là một bài đăng có hình ảnh/video nhưng không có mô tả. Hãy viết caption hấp dẫn." ) # --- Prompt chung cho tất cả page (phần cứng) --- prompt_fb = """ Hãy viết một caption Facebook ngắn gọn, viral, hấp dẫn dựa trên nội dung được cung cấp. Yêu cầu bắt buộc: - Nếu nội dung quá ngắn, hãy sáng tạo thêm cho phù hợp ngữ cảnh. - Thêm emoji phù hợp. - Giọng văn vui vẻ, lôi cuốn, phù hợp lĩnh vực cá cược/giải trí online. - Không dùng Markdown (không dùng **, _, # heading...). - Mỗi bài viết phải có: "Tele: @vmaxhotro" (ở gần cuối caption). - Mỗi bài viết phải có đầy đủ hashtag sau (có thể ở cuối dòng): #Vmax #Vmaxcom #Dangkyvmax #Nhacaivmax #Linkvmax. Nếu nội dung là video/ảnh không có mô tả, hãy tự viết caption hấp dẫn, kích thích người đọc click. """ # --- Vòng lặp qua TẤT CẢ FANPAGE --- for page in FB_PAGES: page_name = page.get("name", page.get("page_id")) print(f"\n🔄 Đang viết caption với Gemini cho page: {page_name}") fb_caption = call_gemini_for_page(prompt_fb, content_input, page) if not fb_caption: print(f"[{page_name}] ⚠️ Gemini không trả kết quả, dùng caption dự phòng.") fb_caption = build_fallback_caption(content_input, page) print(f"[{page_name}] 📝 Caption (rút gọn log): {fb_caption[:120]}...") # --- Đăng lên Facebook PAGE TƯƠNG ỨNG --- post_to_facebook(page, fb_caption, media_path) # --- Xóa file tải tạm (sau khi đã dùng cho tất cả page) --- if media_path and os.path.exists(media_path): try: os.remove(media_path) print("🧹 Đã xóa file media tạm.") except Exception: print("⚠️ Không thể xóa file tạm, bạn kiểm tra lại quyền ghi file.") # ========================================== # PHẦN 4: KHỞI CHẠY BOT # ========================================== print("🚀 Bot Facebook & Telegram đang chạy... Nhấn Ctrl+C để dừng.") async def main(): await client.start() await client.run_until_disconnected() if __name__ == "__main__": asyncio.run(main())
API_ID, API_HASHGEMINI_API_KEYFB_PAGES → page_id + access_token thật của từng fanpage.TARGET_CHANNEL đúng với channel Telegram bạn đang lấy nội dung.Nếu bạn muốn:
mình có thể chỉnh thêm logic điều kiện cho từng page (ví dụ thêm key extra_hashtags, only_with_media, v.v.) trong một bản nâng cấp tiếp theo.