Package Information
Documentation
n8n-nodes-codesave-gateway
Community node để gọi Code-Save AI Gateway từ n8n — chat đồng bộ, job bất đồng bộ (ảnh/video/việc nặng), liệt kê model, và nhận webhook callback.
Gateway là một cổng AI thống nhất (Gemini/Vertex…) với hàng đợi job, retry + fallback model, tính phí và log tập trung. Node này là client chính thức cho n8n.
Cài đặt
Gói phát hành công khai trên npmjs → cài thẳng từ UI, không cần cấu hình registry, không cần vào máy chủ.
Trong n8n (khuyên dùng): Settings → Community Nodes → Install → nhập n8n-nodes-codesave-gateway → Install.
Thủ công (self-host):
cd ~/.n8n/nodes
npm install n8n-nodes-codesave-gateway
# khởi động lại n8n
Node là client mỏng — không chứa secret. Quyền truy cập gateway do API key bạn nhập trong credential quyết định; cài node mà không có key hợp lệ thì không gọi được gì.
Hướng dẫn đầy đủ: https://gateway.code-save.com/docs/cai-dat/
Credential
Tạo một credential Code-Save Gateway API. Nó giữ cả hai loại key — điền một hoặc cả hai:
| Trường | Bắt buộc | Mô tả |
|---|---|---|
| Base URL | ✓ | Mặc định https://gateway.code-save.com. Chỉ dùng cho Gateway API Key |
| Gateway API Key | — | csg_<project>_<secret> — lấy trong dashboard gateway |
| Webhook Signing Secret | — | Chỉ cần cho node Trigger nhận callback do gateway gửi |
| Gemini API Key (Của Bạn) | — | AIza… — lấy ở Google AI Studio hoặc Google Cloud Console, để gọi thẳng Google |
Nút Test thử đúng những key đang điền: Gateway API Key gọi GET /v1/models của gateway, Gemini API Key
gọi GET /v1beta/models của Google. Có một key hỏng thì báo đúng key đó và cho biết key kia vẫn dùng được.
Gateway hay Gemini API Key riêng
Node Code-Save Gateway có trường Kết Nối Qua ở đầu, trên Resource:
| Kết Nối Qua | Gọi tới | Chi phí tính vào | Dùng được |
|---|---|---|---|
| Code-Save Gateway (mặc định) | gateway.code-save.com |
gói gateway của bạn | Chat, Job, Model, Trigger |
| Gemini API Key (Của Bạn) | thẳng generativelanguage.googleapis.com |
project Google của key | Chat, Job, Model, Trigger |
Danh sách trong Kết Nối Qua đi theo credential:
- Có đủ hai key → chọn được cả hai; đổi qua lại không đụng tới credential.
- Chỉ có một key → chỉ còn đường đó, node luôn chạy đường đó. Muốn đổi được thì thêm key còn lại vào credential.
Chat ở hai đường nhận cùng tham số và trả cùng khuôn kết quả (choices[0].message.content,reasoning_content, usage… hoặc bản Simplify), nên các node phía sau không phải sửa. Dropdown model tự nạp
lại khi đổi đường.
Dropdown Kết Nối Qua được nạp khi mở node. Vừa thêm/bớt key trong credential thì đóng rồi mở lại node để
danh sách cập nhật. Lúc chạy, node luôn tính lại theo key đang có trong credential.Node mới + credential chỉ có Gemini API Key: n8n có thể hiện
The value "gateway" is not supported!dưới
Kết Nối Qua (giá trị mặc định chưa đổi). Node vẫn chạy đúng đường Gemini; chọn lại Gemini API Key trong
dropdown để hết cảnh báo và để node giữ đường này cả khi sau này credential có thêm Gateway API Key.
Cách key được bảo vệ:
- n8n mã hoá credential khi lưu; key bị che trên giao diện.
- Mỗi key chỉ được gắn vào request tới đúng máy của nó:
- Gemini API Key chỉ tới
https://generativelanguage.googleapis.com, trong headerx-goog-api-key. Key không nằm trên URL (URL hay lọt vào log/lỗi) và không theo redirect. - Gateway API Key chỉ tới đúng Base URL.
- Sửa Base URL cũng không lấy được Gemini API Key.
- Gemini API Key chỉ tới
- Gemini API Key đi thẳng n8n → Google, không qua gateway Code-Save.
- Lỗi đã được làm sạch, không chứa request/header gốc → key không lọt vào lịch sử execution.
- Nên giới hạn key trong Google Cloud Console chỉ gọi được Generative Language API.
Khác biệt khi dùng key riêng (vì không có gateway đứng giữa):
- Job (Async) và Trigger chạy được nhưng khác vài điểm — xem mục Job + Trigger ở chế độ API Key ngay dưới.
- 429 (Chat): node đợi theo
retryDelaycủa Google nếu ≤30s (tối đa 2 lần); lâu hơn nghĩa là hết quota ngày → báo lỗi ngay. - Không có log/tính phí tập trung ở dashboard gateway; xem chi phí trong Google Cloud Billing.
- Danh sách model là của Google (theo quyền của key), không phải danh sách gateway đang phục vụ.
Job + Trigger ở chế độ API Key
Chuyển một workflow đang chạy qua gateway:
- Dán Gemini API Key vào credential Code-Save Gateway API mà workflow đang dùng.
- Ở mọi node Code-Save Gateway, đổi Kết Nối Qua sang Gemini API Key (Của Bạn).
Trigger dùng cùng credential nên tự nhận chữ ký mới, không phải sửa. Model, action, payload, fallback models,
max attempts, idempotency key, Callback URL giữ nguyên.
Không có hàng đợi gateway đứng giữa → chính node làm phần đó: gọi Google, retry, fallback model, gửi callback.
Kết quả vẫn trả đúng khuôn job của gateway (id, status, attempts, fallback_index, response_payload…).
| Loại việc | Submit | Submit and Wait | Get / Download Result |
|---|---|---|---|
Ảnh, text, TTS (generateContent, predict) |
chạy tới xong ngay trong node rồi mới trả (completed/failed); có Callback URL thì gửi callback xong mới trả |
như Submit | đọc từ item phía trước, không gọi mạng |
Video Veo (predictLongRunning) |
Google nhận việc → trả job_id dạng akv-… ngay (running). Có Callback URL thì node chờ video xong rồi gửi callback |
chờ video xong, tải về binary | Get hỏi thẳng Google; Download tải video từ Google |
Lấy kết quả:
- File (ảnh/audio/video) nằm ở binary
datacủa item.response_payloadgiống gateway: file đơn →{done, result_saved, result_ext}; nhiều ảnh → giữ base64. TTS: PCM được bọc thành WAV như gateway. result_urlluônnull— node nào đang GETresult_urlthì chuyển sang binarydatahoặc Download Result.- Trigger: callback được ký HMAC bằng khoá suy ra từ chính Gemini API Key (không cần Webhook Signing Secret) — Trigger phải dùng cùng credential với node Submit. File ≤ ~9MB đi kèm callback và ra binary
datacủa Trigger. File lớn hơn không đi kèm (webhook n8n nhận tối đa 16MB) → nối Download Result sau Trigger (video tải lại từ Google; ảnh/audio lấy từ bộ nhớ đệm, xem dưới).
Giới hạn so với gateway:
- Job ảnh/text/audio (
aks-…) không có kho lưu phía server: Get/Download Result chỉ đọc được từ item phía trước, hoặc bộ nhớ đệm 30 phút trong cùng tiến trình n8n (queue mode nhiều worker không dùng chung). Sau đójob_idkhông tra lại được. - Submit ảnh/text/audio chặn workflow tới khi xong (trần 15 phút); Submit Veo có Callback URL cũng chặn tới khi video xong.
- Cancel: ảnh/text/audio đã xong khi Submit trả về nên không huỷ được; Veo: Gemini API không cho huỷ — video vẫn chạy và vẫn tính phí.
- Veo chỉ nhận tham số Gemini API hỗ trợ (
aspectRatio,durationSeconds,negativePrompt,resolution,seed);personGeneration,generateAudio,storageUri… bị bỏ;sampleCountphải là 1; filegcsUri/gs://không dùng được → gửi base64. - Veo Submit không có Callback URL: retry/fallback chỉ ở bước khởi tạo; lỗi phát sinh khi Google đang tạo video → Get trả
failed, không tự sang model khác. - Trường chỉ Vertex có trong payload được tự bỏ:
labels,safetySettings[].method,generationConfig.routingConfig/modelSelectionConfig. - Tên model khác nhau giữa gateway và Google (vd
gemini-2.5-flash-tts↔gemini-2.5-flash-preview-tts) được tự dò khi Google trả 404. - Priority và Prompt Text bị bỏ qua (chỉ có nghĩa trong hàng đợi gateway).
- 429: chờ theo
retryDelay(≤60s) rồi thử lại; Google bảo chờ lâu hơn → sang fallback model, hết model → jobfailedvớirate_limited. - Key sai / billing / API chưa bật → node báo lỗi ngay (không thành job
failed), vì model nào cũng sẽ lỗi như nhau. - TTS đôi khi trả
finishReason: OTHERkhông kèm audio (tuỳ câu chữ) — job vẫncompletednhư ở gateway; Download Result báo rõ "Google không trả file".
Nâng cấp từ 0.3.x: Settings → Community Nodes → Update rồi tải lại trang. Workflow cũ không phải
sửa gì — chưa có trường Kết Nối Qua thì node tự hiểu là Code-Save Gateway, chạy y như trước. Thêm Gemini
API Key vào credential cũ cũng không làm node cũ tự đổi đường; node chỉ đổi khi bạn chọn lại Kết Nối Qua.
Nâng cấp từ 0.4.0 (nếu đã dùng chế độ API Key): kiểu credential riêng "Code-Save: Gemini API Key (Của Bạn)"
đã được gộp vào Code-Save Gateway API, nên node dùng nó sẽ báo thiếu credential.
- Dán Gemini API Key vào credential Code-Save Gateway API (hoặc tạo credential mới chỉ với key này).
- Chọn credential đó ở mỗi node Code-Save, kể cả Trigger.
- Nếu credential có cả hai key, đặt Kết Nối Qua = Gemini API Key (Của Bạn).
Node: Code-Save Gateway
Resource: Chat (Sync)
Complete → POST /v1/chat. Gửi hội thoại, nhận trả lời ngay trong luồng. Hỗ trợ temperature/top_p/max_tokens, stop sequences, JSON mode, và thinking (budget + include thoughts). Bật Simplify để lấy gọn content / reasoning_content / usage.
Đa phương thức (ảnh/audio): mỗi message có field Attachments (Binary Fields) — nhập tên binary field của item (cách nhau dấu phẩy). Node tự đọc mimeType, base64-hoá và gắn kèm dưới dạng image/* hoặc audio/*. Bỏ trống = chỉ gửi text (tương thích ngược). Model phải hỗ trợ loại input tương ứng (đa số Gemini nhận ảnh; 2.5+ nhận audio).
Dùng cho: chat ngắn, tương tác (p50 ~3s). Đường sync có deadline gateway (SYNC_MAX_MS) và giữ 1 slot suốt thời gian chạy — không hợp cho việc dài.
Resource: Job (Async)
| Operation | Ý nghĩa |
|---|---|
| Submit | Đẩy job vào hàng đợi, trả job_id ngay. Kết quả nhận qua Trigger (webhook) hoặc poll. Điền Callback URL = URL của node Trigger. |
| Submit and Wait | Submit rồi tự poll tới khi xong. Tuyến tính như sync nhưng có độ bền của async, không cần dựng webhook, và không bị HTTP timeout chặn. |
| Get | GET /v1/jobs/:id — trạng thái + result_url (khi completed). |
| Download Result | Job completed → tải file (ảnh/video) từ result_url về binary. |
| Cancel | DELETE /v1/jobs/:id — chỉ khi pending/running. |
Hỗ trợ priority, idempotency_key, max_attempts (retry cùng model), fallback models (nhảy model giữ vị trí FIFO), và action generateContent / predict / predictLongRunning (Veo) / streamGenerateContent.
Kết quả trả về (đọc kỹ — breaking change 2026-07-23)
Kết quả ảnh/video của job KHÔNG còn base64 inline trong response_payload — phải tải qua result_url. Đây là cờ slim_images (bật 2026-07-23) để gateway thôi lưu ảnh 2 lần.
| Loại job | response_payload chứa gì |
Lấy kết quả ở đâu |
|---|---|---|
Ảnh đơn (gemini-*-image, sampleCount=1) |
chỉ {done, result_saved, result_ext} — đã gỡ base64 |
result_url (hoặc operation Download Result) |
Nhiều ảnh (sampleCount>1, nhiều inlineData) |
giữ base64 (lưới an toàn — result_url chỉ mang ảnh đầu) |
base64 inline hoặc result_url (ảnh đầu) |
Video (veo-*) |
{done, result_saved, result_ext, operation_name} — không có bytes |
result_url (hoặc Download Result) |
Audio / TTS (gemini-*-tts) |
{done, result_saved, result_ext:"wav"} — đã gỡ base64; PCM thô đã được bọc → WAV |
result_url (hoặc Download Result) |
Chat/text (POST /v1/chat) |
không đổi | content trong response |
Cách dùng chuẩn: khi nhận completed (qua Trigger hoặc Submit-and-Wait) → chạy Download Result với Job ID để lấy file binary, hoặc tự GET result_url.
result_urlkhông cần Authorization (token nằm trong URL). Token hết hạn ~24h, nhưng mỗi lần Get lại cấp token mới → đối soát muộn vẫn tải được miễn file còn.- File kết quả giữ tối đa 7 ngày (2 ngày nếu đã
ack-consumed) → tải & lưu về kho của bạn ngay khi completed. - Lưới đỡ tạm: gọi
GET /v1/jobs/:id?include_base64=1để dựng lại base64 ảnh đầu từ file đĩa (tạm thời — nên chuyển sangresult_url).
Chọn sync hay async là theo độ nặng của việc, không phải mệnh lệnh:
- Việc nhẹ → Chat (Sync).
- Việc nặng, muốn tuyến tính, ngại webhook → Job → Submit and Wait (mặc định khuyên dùng).
- Fire-and-forget, nhiều việc song song → Job → Submit + Trigger.
- Veo/video → Submit với action
predictLongRunning(async về bản chất).
Resource: Model
List → GET /v1/models. Danh sách model đang phục vụ (dùng cho dropdown, tự động). Admin bật model
mới ở gateway là dropdown thấy ngay ở lần load kế tiếp — không cần cập nhật/publish lại node. Node chỉ
truyền payload nên tham số model mới cũng dùng được ngay (ràng buộc tham số xem /v1/models/catalog · /docs).
TTS Gemini native: chọn model gemini-2.5-flash-tts / gemini-2.5-pro-tts (tên cũ -preview-tts vẫn chạy nhờ alias), resource
Job action generateContent, Payload (JSON):
{
"contents": [{ "role": "user", "parts": [{ "text": "Xin chào, đây là giọng đọc thử." }] }],
"generationConfig": {
"responseModalities": ["AUDIO"],
"speechConfig": { "voiceConfig": { "prebuiltVoiceConfig": { "voiceName": "Kore" } } }
}
}
Kết quả là job audio (result_ext=wav) — nối Download Result để lấy file như ảnh/video. ~30 giọng dựng
sẵn, đa giọng qua multiSpeakerVoiceConfig.
Node: Code-Save Gateway Trigger
Webhook nhận callback job. Dán URL Production của node vào Callback URL khi Submit.
Verify HMAC: header
X-Gateway-Signature: sha256=<hex>= HMAC-SHA256(raw body, secret), so sánh timing-safe. Chữ ký khớp một trong hai khoá của credential là hợp lệ:- Webhook Signing Secret — callback do gateway gửi;
HMAC-SHA256(key = Gemini API Key, "codesave-n8n-callback-v1")dạng hex — callback do node Submit chạy bằng Gemini API Key gửi (tự suy ra, không phải nhập). Trigger phải dùng cùng credential với node Submit.
Credential không có khoá nào → mọi callback bị từ chối
401 missing_webhook_secret.Chống replay: bỏ delivery có
tscũ hơn 300s.Chống lặp: dedup theo
job_id:event:ts+ terminal-guardjob_id:final(job đã xong thì bỏ mọi delivery sau).Lọc theo event
completed/failed/retrying.
Retry & lỗi
Mọi request tự thử lại khi gặp 429 theo header Retry-After (tối đa 2 lần) — bao gồm project_concurrency_limit, no_slot_available, gateway_overloaded, budget. 4xx khác ném lỗi ngay.
410 model_retired_candidate_unconfirmed: model đã qua hạn ngừng phục vụ mà gateway chưa xác minh model thay thế → đổi model trong node sang model mới (xem gợi ý successor trong detail). Nếu đã có thay thế xác minh, gateway tự chuyển trong suốt (không lỗi).
License
MIT