FBChat-Remake - Mã nguồn mở
Thư viện Python async-first cho Facebook Messenger API không chính thức
🇬🇧 English · 📖 Tài liệu · 📦 PyPI · 📊 Sơ đồ luồng · 🐛 Báo lỗi
👋 Giới thiệu
Mình là MinhHuyDev (m008v), tác giả và người duy trì dự án.
fbchat-v2 là thư viện Python để gửi và nhận tin nhắn Messenger bằng tài khoản Facebook cá nhân. Thư viện dùng async/await; E2EE chạy qua bridge Go. Codebase đã được tổ chức lại từ v2.2.0 và tiếp tục được sửa theo các lỗi người dùng báo về.
Cảm ơn mọi người đã góp ý và báo lỗi. Đây là API không chính thức nên một số chức năng có thể hỏng khi Facebook thay đổi. Nếu gặp lỗi, mở issue trên GitHub kèm cách tái hiện và log đã che thông tin nhạy cảm, hoặc nhắn mình qua Telegram.
📚 Mục lục
- Tính năng
- Kiến trúc tổng quan
- Cấu trúc dự án
- Yêu cầu hệ thống
- Cài đặt
- Cấu hình
- Bắt đầu nhanh
- Sử dụng API async
- Listener E2EE
- Bot mẫu
- Tài liệu từng module
- Kiểm tra chất lượng
- Bảo mật và giới hạn
- Đóng góp
- Vinh danh
- Bản quyền
✨ Tính năng
Thư viện dùng cookie hoặc thông tin đăng nhập của tài khoản cá nhân, không dùng access_token của fanpage như API chatbot chính thức. Các nhóm chức năng hiện có:
Xác thực
- Đăng nhập bằng username/password hoặc cookie phiên (*).
- Tái sử dụng phiên đăng nhập để không phải đăng nhập lại mỗi lần chạy.
Nhắn tin
- Đọc tin nhắn từ người dùng và nhóm chat (thread).
- Nhận tin cá nhân E2EE Messenger (Secret Conversations / Labyrinth) qua bridge Go.
- Gửi văn bản, tệp đính kèm, nhãn dán (sticker) và mention người dùng.
- Tìm kiếm tin nhắn và hội thoại.
- Sửa tin đã gửi, thả cảm xúc, thu hồi tin và xử lý message requests.
- Đổi theme/nền thread Messenger và quản lý Messenger Notes 24h.
- Nhận event theo thời gian thực để xử lý lệnh trong bot.
Thread & Nhóm
- Tạo nhóm, thêm admin, đổi tên/emoji/biệt danh trong nhóm.
- Tạo cuộc thăm dò ý kiến (poll) và lấy metadata của thread.
Tính năng Facebook (_features._facebook)
- Thả và gỡ cảm xúc bài viết timeline (
_reactionPost: Like, Love, Care, Haha, Wow, Sad, Angry, Undo). - Đăng bài (
_createPost), lưu trữ (_archivePost) và xóa bài viết (_deletePost). - Tìm kiếm người dùng (
_search), lấy thông tin profile (_get_user_info) và quản lý thông báo (_notification). - Chặn/bỏ chặn (
_blocking), hủy kết bạn (_unFriend), quản lý Marketplace và chế độ Professional. - Hướng dẫn chi tiết nằm trong Tài liệu
fbchat_v2._features._facebook.
Mới cập nhật
- Các API chính dùng
async/await; một số phần compatibility vẫn chạy blocking. - Bridge E2EE có quy trình build và phân phối binary cho Windows, Linux và macOS.
📂 Kiến trúc tổng quan
Codebase chia thành ba tầng. Core quản lý session và HTTP transport; feature và messaging dùng lại các phần này, không tự lưu credential trong code.
| Tầng | Đường dẫn | Trách nhiệm |
|---|---|---|
| Core | src/fbchat_v2/_core/ |
HTTP transport, session, storage, login và utility |
| Features | src/fbchat_v2/_features/ |
Nghiệp vụ Facebook và quản trị thread |
| Messaging | src/fbchat_v2/_messaging/ |
Send, listen, E2EE, attachment, reaction, theme và notes |
flowchart LR
A[Cookie hoặc storage] --> B[dataGetHome]
B --> C[dataFB]
C --> D[Features HTTP]
D --> E[httpx.AsyncClient]
C --> F[MQTT listener]
C --> G[Python E2EE wrapper]
G <--> H[Go JSON-RPC bridge]
H <--> I[Messenger E2EE]
F --> J[Ứng dụng asyncio]
G --> J
Xem luồng đầy đủ trong FLOWCHART.md.
🗂️ Cấu trúc dự án
fbchat-v2/
├── src/
│ ├── main.py # Bot mẫu async dùng listener E2EE
│ ├── config.example.json # Template cấu hình được phép commit
│ ├── config.json # Cấu hình local, bị gitignore
│ ├── _core/
│ │ ├── _http.py # Transport httpx sync/async dùng chung
│ │ ├── _session.py # Cookie -> dataFB
│ │ ├── _storage.py # File/Env session storage
│ │ ├── _facebookLogin.py # Credential login và 2FA
│ │ ├── _utils.py # Form, parser, cookie và ID helper
│ │ └── README.md
│ ├── _features/
│ │ ├── _facebook/ # Account, profile, Marketplace
│ │ ├── _thread/ # Thread và group administration
│ │ └── README.md
│ └── _messaging/
│ ├── _send.py # Gửi tin thường qua HTTP
│ ├── _attachments.py # Upload file
│ ├── _listening.py # MQTT listener thường
│ ├── _listening_e2ee.py # E2EE listener và bridge process
│ ├── _bridge_actions.py # Action async qua bridge
│ ├── _send_e2ee.py # Compatibility sender standalone
│ ├── _changeTheme.py
│ ├── _createNotes.py
│ ├── _editMessage.py
│ ├── _message_requests.py
│ ├── _reactions.py
│ ├── _unsend.py
│ └── README.md
├── bridge-e2ee/
│ ├── main.go # JSON-RPC dispatcher
│ ├── bridge/ # Messenger/E2EE operations
│ ├── meta/ # Git submodule mautrix-meta
│ ├── go.mod
│ └── README.md
├── build/ # Binary bridge local
├── tests/ # Unit và async contract tests
├── DOCS.md # Hướng dẫn API đầy đủ
├── FLOWCHART.md # Runtime flow
├── mindmap-mermaid.md # Bản đồ codebase
├── CHANGELOG.md
└── pyproject.toml
🔧 Yêu cầu hệ thống
| Thành phần | Tối thiểu | Khuyến nghị | Ghi chú |
|---|---|---|---|
| Python | 3.10 | 3.11 / 3.12 | Bắt buộc |
| Go (toolchain) | 1.26.9 | 1.26.9+ | Chỉ cần cho E2EE - để build fbchat-bridge-e2ee |
| Git | bất kỳ | latest | Cần cho go mod tidy kéo mautrix/meta |
| Hệ điều hành | Windows / Linux / macOS | - | - |
| RAM | 256 MB | 1 GB+ | Bridge E2EE chiếm ~80–150 MB khi chạy |
| Mạng | Kết nối ổn định, không bị chặn facebook.com và edge-chat.facebook.com |
- | - |
Phụ thuộc Python chính trong pyproject.toml:
dependencies = [
"httpx>=0.27.0",
"paho-mqtt>=1.6.1",
"pyotp>=2.9.0",
"requests>=2.32.0",
]
httpx xử lý HTTP cho session và các feature async. requests vẫn được dùng ở phần đăng nhập bằng thông tin tài khoản và upload compatibility chạy blocking.
📦 Cài đặt
Các bước dưới đây hướng dẫn cài từ source. Môi trường ảo ở bước 2 là tùy chọn; bước 5 bắt buộc nếu chạy bot mẫu
src/main.pyhoặc dùng E2EE.
1. Clone mã nguồn
git clone --recurse-submodules https://github.com/m008v/fbchat-v2.git
cd fbchat-v2
Cách khác:
Code → Download ZIPtrên GitHub.
2. Tạo môi trường ảo (không bắt buộc nhưng khuyến nghị)
python -m venv .venv
Kích hoạt môi trường:
# Windows (PowerShell)
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
3. Cài đặt phụ thuộc Python
python -m pip install --upgrade pip
python -m pip install -e .
Kiểm tra nhanh:
python -c "import fbchat_v2; from fbchat_v2._features._facebook import _unFriend; print('OK')"
4. Xác minh package đã cài
Chạy lệnh sau để kiểm tra namespace công khai fbchat_v2, với cả editable install và wheel:
python scripts/verify_distribution.py
Không cần đặt PYTHONPATH=src và không import bằng prefix src..
5. Build bridge E2EE - bắt buộc cho bot mẫu
Nếu chỉ dùng API HTTP hoặc listener MQTT thường, bạn có thể bỏ qua bước này. src/main.py, _e2ee_listening_test.py và _e2ee_send_test.py cần binary Go fbchat-bridge-e2ee: nếu bridge không sẵn sàng, chúng dừng thay vì chuyển sang Python MQTT.
5.1. Cài Go toolchain
-
Tải về: https://go.dev/dl/ (Go ≥ 1.26.9).
-
Sau khi cài, mở terminal mới và kiểm tra:
go version
5.2. Kéo source mautrix/meta
Repo khai báo bridge-e2ee/meta trong .gitmodules. Với bản clone từ Git, dùng submodule:
git submodule update --init --recursive bridge-e2ee/meta
Nếu build từ bản source không có .gitmodules, clone thủ công:
cd bridge-e2ee
git clone https://github.com/mautrix/meta.git ./meta
go.modcủabridge-e2ee/dùng directivereplacetrỏ tới thư mục./meta, nên pathbridge-e2ee/metaphải tồn tại trước khigo mod tidy/go build.
5.3. Tải dep & build
cd bridge-e2ee
go mod download
# Windows
go build -ldflags="-s -w" -o ../build/fbchat-bridge-e2ee.exe .
# Linux / macOS
go build -ldflags="-s -w" -o ../build/fbchat-bridge-e2ee .
Lần build đầu mất vài phút (~300 MB cache Go module). Sau đó binary khoảng 25–40 MB nằm ở fbchat-v2/build/.
5.4. Verify
cd ..
# Windows
python scripts/smoke_bridge_rpc.py .\build\fbchat-bridge-e2ee.exe --expected-version 2.3.3
# Linux/macOS
python scripts/smoke_bridge_rpc.py ./build/fbchat-bridge-e2ee --expected-version 2.3.3
Nếu binary không nằm ở vị trí mặc định, đặt biến môi trường:
# Windows
$env:FBCHAT_E2EE_BIN = "C:\path\to\fbchat-bridge-e2ee.exe"
# Linux/macOS
export FBCHAT_E2EE_BIN=/path/to/fbchat-bridge-e2ee
Xem thêm trong bridge-e2ee/README.md.
6. Cấu hình cookie
Sao chép src/config.example.json thành src/config.json, rồi dán cookie phiên Facebook vào trường cookies. Xem chi tiết ở mục Cấu hình.
7. Smoke test
python src/main.py
Khi console in E2EE listener đã sẵn sàng, bot đã kết nối được listener. Thông báo này chưa chứng minh gửi/nhận tin hoạt động. Bot mẫu không in ID tài khoản, cookie hoặc last_seq_id để tránh lộ metadata.
⚙️ Cấu hình
Tạo file cấu hình local từ template:
Copy-Item src\config.example.json src\config.json
cp src/config.example.json src/config.json
Ví dụ:
{
"botName": "fbchat-v2 demo bot",
"prefix": "/",
"cookies": "c_user=...; xs=...; fr=...; datr=...;",
"admins": [
"1000xxxxxxxxxx"
],
"log_message_content": false,
"debug_errors": false,
"version": "0.0.1"
}
| Khóa | Bắt buộc | Ý nghĩa |
|---|---|---|
cookies |
Có | Cookie phiên Facebook dạng chuỗi |
prefix |
Không | Tiền tố lệnh, mặc định / |
admins |
Không | Danh sách Facebook ID được dùng lệnh quản trị |
log_message_content |
Không | Cho phép ghi plaintext nội dung chat; mặc định false để bảo vệ riêng tư |
debug_errors |
Không | In diagnostic đã redact để debug bridge; mặc định false |
botName |
Không | Metadata cho config, bot mẫu hiện không dùng |
version |
Không | Metadata cho config, bot mẫu hiện không dùng |
src/config.json được Git bỏ qua. Bot đặt quyền file thành 0600 trên
POSIX hoặc ACL riêng cho user hiện tại/SYSTEM trên Windows. Không dùng
config.example.json để chứa cookie thật, và chỉ bật hai tùy chọn log trên khi
đang debug trong môi trường kiểm soát.
🚀 Bắt đầu nhanh
Sau khi cấu hình cookie và bridge:
python src/main.py
Bot đợi cả kết nối thường và E2EE sẵn sàng trước khi xử lý lệnh. Các lệnh mẫu:
/ping
/help
/id
/echo xin chào
/search Minh
/unsend
/unsend chỉ thu hồi tin E2EE cuối do bot gửi trong chat hiện tại. Chat thường không có chatJid sẽ được từ chối rõ ràng.
⚡ Sử dụng API async
Tạo session từ cookie
import asyncio
from fbchat_v2._core._session import dataGetHome
async def main() -> None:
data_fb = await dataGetHome("c_user=...; xs=...; fr=...; datr=...;")
if data_fb is None:
raise RuntimeError("Cookie hết hạn hoặc Facebook đã đổi token HTML.")
print(data_fb["FacebookID"])
asyncio.run(main())
Trong FastAPI, Jupyter hoặc bot framework đã có event loop, gọi await dataGetHome(...) trực tiếp. Không lồng thêm asyncio.run().
Gửi tin nhắn thường
from fbchat_v2._messaging._send import api as SendAPI
sender = SendAPI()
result = await sender.send(
data_fb,
"Xin chào từ fbchat-v2",
threadID="100012345678"
)
if result.get("error"):
raise RuntimeError(result["payload"]["error-description"])
threadID có thể là một ID hoặc danh sách ID khi typeChat="user". Khi gửi attachment, typeAttachment và attachmentID phải đi cùng nhau.
Tái sử dụng HTTP connection
import asyncio
import httpx
from fbchat_v2._features._facebook import _notification, _search
async with httpx.AsyncClient(timeout=30) as client:
notifications, users = await asyncio.gather(
_notification.func(data_fb, client=client),
_search.func(data_fb, "Minh", client=client),
)
Bạn tạo client thì cũng cần đóng nó sau khi dùng. Không dùng lại client đã đóng hoặc truyền httpx.Client sync vào tham số client= của API async.
Upload attachment
from fbchat_v2._messaging import _attachments
from fbchat_v2._messaging._send import api as SendAPI
uploaded = await _attachments.func("photo.jpg", data_fb, include_error=True)
if not uploaded or not uploaded.get("attachmentID"):
raise RuntimeError(f"Upload thất bại: {uploaded}")
await SendAPI().send(
data_fb,
"Ảnh đính kèm (file path)",
threadID="100012345678",
typeAttachment=uploaded["typeAttachment"],
attachmentID=uploaded["attachmentID"],
)
Listener MQTT thường
import asyncio
from fbchat_v2._messaging._listening import listeningEvent
listener = listeningEvent(data_fb, message_queue_maxsize=1000)
listener_task = asyncio.create_task(listener.connect_mqtt())
try:
while True:
event = await listener.get_message(timeout=30)
if event is not None:
print(event)
finally:
await listener.disconnect()
await listener_task
Đọc từng event qua get_message(). bodyResults chỉ giữ snapshot để tương thích với code cũ, nên có thể bỏ lỡ event khi nhiều tin đến cùng lúc.
🔐 Listener E2EE
listeningE2EEEvent khởi chạy bridge Go và trao đổi JSON-RPC qua stdin/stdout. Callback của bridge chạy ngoài event loop. Với ứng dụng asyncio, chuyển event vào asyncio.Queue bằng loop.call_soon_threadsafe như ví dụ dưới đây.
import asyncio
from fbchat_v2._messaging._listening_e2ee import listeningE2EEEvent
async def run_listener(data_fb: dict) -> None:
listener = listeningE2EEEvent(data_fb)
loop = asyncio.get_running_loop()
events: asyncio.Queue[dict] = asyncio.Queue(maxsize=1000)
def enqueue(event: dict) -> None:
if events.full():
events.get_nowait()
events.put_nowait(event)
listener.on_message(
lambda event: loop.call_soon_threadsafe(enqueue, event)
)
listener_task = asyncio.create_task(listener.connect_mqtt())
try:
ready = await asyncio.to_thread(
listener.wait_until_connected,
listener.startup_timeout,
require_e2ee=True,
)
if not ready:
raise TimeoutError("E2EE handshake chưa hoàn tất.")
await listener.send_e2ee_message(
"100012345678@msgr",
"Xin chào E2EE",
)
while True:
event = await events.get()
if event.get("type") in {"e2eeMessage", "message"}:
print(event["data"])
finally:
listener.stop()
await listener_task
Event chính:
| Type | Dữ liệu đáng chú ý | Ý nghĩa |
|---|---|---|
ready |
isNewSession |
Bridge đã tạo client |
e2eeConnected |
trạng thái handshake | Signal/Labyrinth đã sẵn sàng |
e2eeMessage |
chatJid, senderJid, id, text |
Tin cá nhân đã giải mã |
message |
threadId, senderId, id, text |
Tin thường |
error |
lỗi bridge/transport | Cần log và giám sát |
bridge_fatal |
số lần retry | Watchdog đã bỏ cuộc |
Các action edit, unsend, typing, mark-read, gửi ảnh/audio và download media nằm trong BridgeActions. Cách dùng có trong tài liệu messaging.
🤖 Bot mẫu
src/main.py ghép các phần trên thành một bot async:
- Đọc config bằng
FileSessionStorage. - Gọi
await dataGetHome(...)và kiểm tra các field bắt buộc. - Mở một
httpx.AsyncClientdùng chung cho command HTTP. - Chạy
listeningE2EEEvent.connect_mqtt()trong một task. - Chuyển callback bridge sang
asyncio.Queuethread-safe. - Đọc lệnh và bỏ qua message do chính bot gửi.
- Trả lời bằng E2EE khi có
chatJid, gửi tin thường khi chỉ cóthreadId. - Dừng bridge, await task và đóng HTTP client khi shutdown.
Queue của bot chứa tối đa 1000 event và bỏ event cũ nhất khi đầy. Cách này giới hạn bộ nhớ khi tin đến dồn dập, nhưng có thể làm mất event; không phải cơ chế đảm bảo giao nhận.
📖 Tài liệu từng module
| Tài liệu | Nội dung |
|---|---|
| DOCS.md | Hướng dẫn API và workflow đầy đủ |
| Core | Session, HTTP, storage và login |
| Features | Facebook feature và thread |
| Messaging | Send, listener, attachment và E2EE |
| Bridge E2EE | Build, binary discovery và JSON-RPC |
| Flowchart | Luồng session, HTTP, MQTT, E2EE và shutdown |
| Mindmap | Bản đồ module toàn dự án |
✅ Kiểm tra chất lượng
Chạy test bằng lệnh CI đang dùng:
pytest tests/ -v --tb=short
Trước khi commit, chạy thêm các bước kiểm tra:
python -m compileall -q src tests scripts
ruff check src tests scripts
black --check src tests scripts
mypy
python -m build --wheel
python scripts/verify_distribution.py dist/fbchat_v2-2.3.3-py3-none-any.whl
git diff --check
CI cài wheel và editable install vào hai virtual environment sạch trước khi chạy smoke test import.
Với bridge:
cd bridge-e2ee
go test ./...
go vet ./...
Lưu tài liệu tiếng Việt bằng UTF-8. Nếu PowerShell hiển thị ký tự lạ, kiểm tra codepoint hoặc đọc file với encoding="utf-8" trước khi sửa; lỗi hiển thị ở terminal chưa chắc là lỗi trong file.
🌟 Vinh danh người đóng góp
Trong 4 năm phát triển, nhiều người đã góp ý tưởng, báo lỗi và giúp duy trì fbchat. Cảm ơn mọi người đã dành thời gian cho dự án.
👥 Cộng đồng đóng góp
- tomdev112
- syrex1013
- Kheir Eddine
- 陶世玉
- Jihadi John
- Bắc Trịnh
- Quang Trần
- Minh Trần Ngọc
- Victor Knutsenberger
- Hoàng Lân
- Kareem Adel Abomandor
- @lluevy · @phuncnheo · @minhphatnw · @khanh235a · @chapesh1 · @klongg13 · @seafibrahem · @agent1047 · @stefekdziura
Nếu bạn đã đóng góp nhưng chưa có tên ở đây, mở issue hoặc PR để mình bổ sung nhé.
📜 Bản quyền
Dự án được phân phối theo điều khoản trong LICENSE. Phần bridge có thành phần upstream với giấy phép riêng; xem bridge-e2ee/README.md trước khi phân phối binary.
Metadata
Release files for fbchat-v2 2.3.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fbchat_v2-2.3.3.tar.gz | 149.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fbchat_v2-2.3.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 327.5 kB
Release files / fbchat_v2-2.3.3.tar.gz
| Download URL | fbchat_v2-2.3.3.tar.gz |
|---|---|
| Size | 149.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b571511e59e7e7a8da648c09f4fd474a6a1855eaa00ecc1128cc11240450d674
|
|
BLAKE2b-256 checksum How to use checksums |
a28890b2f71bfd5bfc27267778be0e69411e807d9dee01b927998a0ba8bea216
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.15
|
Release files / fbchat_v2-2.3.3-py3-none-any.whl
| Download URL | fbchat_v2-2.3.3-py3-none-any.whl |
|---|---|
| Size | 177.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
10417e4bdf7d2798333e521a5897fb976cdbc399e85107ad9cd2f3773ff4680b
|
|
BLAKE2b-256 checksum How to use checksums |
dc84daed1ed1e26ac9aa6fd98c7466165f28aae7008b02b5574e18a555d28926
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.15
|