Đẩy dữ liệu GROUP CRAWL sang hệ thống của bạn
NextCore Browser gửi group tìm được sang API hoặc CSDL MySQL / PostgreSQL của bạn — payload, lược đồ bảng, ví dụ máy chủ nhận.
Đây là gì
GROUP CRAWL lưu group Facebook tìm được vào kho trên máy bạn. App còn có thể đẩy các group đó sang hệ thống của bạn — CRM tự viết, n8n, một bảng trong CSDL công ty — sau mỗi lượt tìm.
Mở ở NEXTCORE GROUPCRAWL › dòng Việc nền (bấm để mở) › Đẩy dữ liệu › Cài đặt. Có hai đích, bật riêng từng cái, mặc định TẮT:
| Đích | App làm gì |
|---|---|
| API | POST JSON từng lô (tối đa 100 group) tới URL bạn khai, kèm header xác thực nếu có |
| CSDL MySQL / MariaDB hoặc PostgreSQL | Nối thẳng tới CSDL, tự tạo bảng nếu chưa có, ghi đè theo group_id (UPSERT) |
- Chỉ gửi phần công khai của group: mã, tên, link, số thành viên, bài/ngày, chế độ, khu vực, danh mục, lần thấy. Không gửi tài khoản Facebook, tên profile, từ khoá tìm, bài viết hay danh sách thành viên.
- Chỉ gửi phần đổi: lần đầu gửi cả kho; sau đó chỉ group mới hoặc group đổi tên / số liệu / phân loại. Đổi URL hoặc đổi CSDL / bảng ⇒ app coi đích mới là trống và gửi lại cả kho.
- Khi nào gửi: ngay khi một lượt tìm kết thúc (kể cả dừng giữa chừng — nhóm đã ghi vẫn là dữ liệu thật), khi vừa bật công tắc, và khi bấm Đẩy ngay. Lượt nền kiểm mỗi phút, còn group chờ thì gửi tiếp.
- Lỗi đẩy không làm hỏng lượt tìm: kho trên máy vẫn đủ. Dòng Đẩy dữ liệu trong Việc nền hiện kết quả lần đẩy gần nhất (giờ, số group, câu lỗi). Sau một lần lỗi, app tự thử lại sau 10 phút, hoặc ngay khi lượt tìm kế tiếp xong / bạn bấm Đẩy ngay.
- Bí mật được mã hoá: giá trị header xác thực và mật khẩu CSDL lưu bằng mã hoá của hệ điều hành (Windows DPAPI, kho khoá của Linux khi có), app không hiện lại — để trống ô là giữ giá trị cũ. macOS hiện lưu dạng thô trong thư mục dữ liệu của app, như mật khẩu proxy và khoá API.
(a) Đẩy sang API
Yêu cầu app gửi
POST https://crm.cua-ban.vn/api/nextcore/groups
Content-Type: application/json; charset=utf-8
User-Agent: NextCoreBrowser/<bản app> (+group-crawl)
Authorization: Bearer <giá trị bạn nhập> ← tên header đổi được (X-Api-Key…), bỏ trống ⇒ không gửi{
"nguon": "nextcore-browser",
"phienBan": 1,
"guiLuc": "2026-10-19T01:36:12.418Z",
"kiem": false,
"soGroup": 2,
"groups": [
{
"id": "1481410332813761",
"ten": "Homestay Đà Lạt Giá Rẻ View Đẹp",
"url": "https://www.facebook.com/groups/homestaydalatgiare/",
"rutGon": "homestaydalatgiare",
"thanhVien": 48307,
"thanhVienLamTron": false,
"baiNgay": 90,
"cheDo": "PUBLIC",
"khuVucId": 38,
"khuVuc": "Lâm Đồng",
"danhMucId": 7,
"danhMuc": "Homestay & khách sạn",
"lanDau": "2026-10-17T06:00:00.000Z",
"lanCuoi": "2026-10-19T01:12:00.000Z"
}
]
}| Trường | Kiểu | Ý nghĩa |
|---|---|---|
phienBan |
số | phiên bản payload — hiện là 1; đổi cấu trúc sẽ tăng số |
kiem |
bool | true khi bấm Kiểm kết nối (lô rỗng groups: []) — trả 2xx là đạt, đừng ghi gì |
groups[].id |
chuỗi | mã group Facebook (số; group chưa đọc được mã số thì là tên rút gọn) — khoá để ghi đè |
rutGon |
chuỗi | null | phần tên trong link facebook.com/, null nếu link là mã số |
thanhVien |
số | null | số thành viên; thanhVienLamTron: true ⇒ số Facebook làm tròn (27K ⇒ 27000) |
baiNgay |
số | null | số bài mỗi ngày Facebook hiện ở trang tìm |
cheDo |
PUBLIC | PRIVATE | null |
chế độ nhóm |
khuVucId / khuVuc |
số / chuỗi | null | tỉnh hiện hành theo danh mục NextCore |
danhMucId / danhMuc |
số / chuỗi | null | danh mục ngành NextCore |
lanDau / lanCuoi |
ISO 8601 UTC | lần đầu / lần gần nhất app thấy group |
Máy chủ nhận phải trả
- 2xx ⇒ app coi lô đã nhận, đánh dấu đã gửi. Thân trả về không đọc.
- 429 hoặc 5xx, mất mạng, quá 15 giây ⇒ app thử lại trong cùng lượt: chờ 1 giây, rồi 4 giây (tổng 3 lần). Vẫn hỏng ⇒ ghi lỗi, 10 phút sau thử lại.
- 4xx khác (401, 403, 404, 413…) ⇒ dừng ngay, không thử lại (sửa cấu hình rồi bấm Đẩy ngay).
- Chuyển hướng (3xx) không được theo — khai đúng URL cuối.
- Cùng một group có thể tới nhiều lần (mỗi lần đổi số liệu) ⇒ ghi đè theo
id, đừng chèn trùng.
Ví dụ máy chủ nhận (Node.js, không thư viện)
// node nhan-groups.mjs — nghe :8080, kiểm khoá, ghi đè theo id vào groups.json
import http from 'node:http'
import fs from 'node:fs'
const KHOA = process.env.KHOA_NHAN // trùng giá trị header trong app (Authorization: Bearer …)
const kho = fs.existsSync('groups.json') ? JSON.parse(fs.readFileSync('groups.json', 'utf8')) : {}
http.createServer((req, res) => {
if (req.method !== 'POST' || req.url !== '/api/nextcore/groups') return res.writeHead(404).end()
if (req.headers.authorization !== `Bearer ${KHOA}`) return res.writeHead(401).end()
let chu = ''
req.on('data', (c) => (chu += c)).on('end', () => {
const lo = JSON.parse(chu)
if (!lo.kiem) for (const g of lo.groups) kho[g.id] = g
fs.writeFileSync('groups.json', JSON.stringify(kho, null, 2))
res.writeHead(200, { 'Content-Type': 'application/json' }).end(JSON.stringify({ ok: true, nhan: lo.groups.length }))
})
}).listen(8080)n8n: node Webhook (POST, Response 200) → Split Out trường groups → ghi vào Google Sheet / CSDL theo khoá id.
(b) Đẩy thẳng vào CSDL MySQL / PostgreSQL
Khai Loại (MySQL / MariaDB hoặc PostgreSQL), Máy chủ, Cổng (3306 / 5432), Tên CSDL, Người dùng, Mật khẩu, Bảng (mặc định nextcore_groups), tuỳ chọn SSL (bật khi CSDL nằm ngoài mạng nội bộ; app kiểm chứng chỉ). Bấm Kiểm kết nối trước khi bật:
- Đã kết nối · bảng … chưa có ⇒ lần đẩy đầu app chạy
CREATE TABLE IF NOT EXISTStheo lược đồ dưới. - Đã kết nối · bảng … khớp lược đồ ⇒ dùng được ngay.
- Bảng … đã có nhưng thiếu cột … ⇒ app không tự sửa bảng của bạn: thêm cột còn thiếu, hoặc đặt tên bảng khác để app tự tạo. Bảng có thêm cột riêng của bạn thì không sao.
Quyền tối thiểu cho người dùng CSDL: SELECT, INSERT, UPDATE trên bảng (thêm CREATE nếu để app tự tạo bảng). Tạo một người dùng riêng cho NextCore Browser, đừng dùng root.
Lược đồ bảng
MySQL / MariaDB:
CREATE TABLE IF NOT EXISTS `nextcore_groups` (
`group_id` VARCHAR(64) NOT NULL,
`ten` VARCHAR(255) NOT NULL,
`url` VARCHAR(512) NOT NULL,
`rut_gon` VARCHAR(128) NULL,
`thanh_vien` BIGINT NULL,
`thanh_vien_lam_tron` BOOLEAN NOT NULL DEFAULT FALSE,
`bai_ngay` DOUBLE NULL,
`che_do` VARCHAR(16) NULL,
`khu_vuc_id` INT NULL,
`khu_vuc` VARCHAR(128) NULL,
`danh_muc_id` INT NULL,
`danh_muc` VARCHAR(160) NULL,
`lan_dau` DATETIME(3) NOT NULL,
`lan_cuoi` DATETIME(3) NOT NULL,
`day_luc` DATETIME(3) NOT NULL,
PRIMARY KEY (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;PostgreSQL:
CREATE TABLE IF NOT EXISTS "nextcore_groups" (
"group_id" VARCHAR(64) NOT NULL,
"ten" VARCHAR(255) NOT NULL,
"url" VARCHAR(512) NOT NULL,
"rut_gon" VARCHAR(128) NULL,
"thanh_vien" BIGINT NULL,
"thanh_vien_lam_tron" BOOLEAN NOT NULL DEFAULT FALSE,
"bai_ngay" DOUBLE PRECISION NULL,
"che_do" VARCHAR(16) NULL,
"khu_vuc_id" INTEGER NULL,
"khu_vuc" VARCHAR(128) NULL,
"danh_muc_id" INTEGER NULL,
"danh_muc" VARCHAR(160) NULL,
"lan_dau" TIMESTAMPTZ NOT NULL,
"lan_cuoi" TIMESTAMPTZ NOT NULL,
"day_luc" TIMESTAMPTZ NOT NULL,
PRIMARY KEY ("group_id")
);- Cột trùng nghĩa với trường payload API (
thanh_vien_lam_tron=thanhVienLamTron…);day_luc= lúc app ghi lần gần nhất. - Giờ lưu theo UTC (MySQL
DATETIME(3)ghi giờ UTC; PostgreSQLTIMESTAMPTZ). - Ghi đè theo
group_id:INSERT … ON DUPLICATE KEY UPDATE(MySQL) /INSERT … ON CONFLICT ("group_id") DO UPDATE(PostgreSQL).lan_daugiữ giá trị lần ghi đầu, mọi cột khác cập nhật.
Đọc lại — ví dụ
-- 20 group Lâm Đồng đông nhất, cập nhật trong 7 ngày
SELECT ten, url, thanh_vien, bai_ngay
FROM nextcore_groups
WHERE khu_vuc = 'Lâm Đồng' AND lan_cuoi >= NOW() - INTERVAL 7 DAY
ORDER BY thanh_vien DESC
LIMIT 20;Hỏi nhanh
Group trong kho bị xoá thì sao? App không gửi lệnh xoá — đích giữ bản cuối đã nhận. Group đã xoá + chặn trong app không được tìm lại nên không gửi nữa.
Hai máy cùng đẩy về một bảng? Được — khoá là group_id, máy gửi sau ghi đè số liệu mới hơn.
Có giới hạn tốc độ? Mỗi lượt tối đa 20 lô × 100 group; kho lớn hơn sẽ được gửi tiếp ở lượt nền mỗi phút.