MinAI - Về trang chủ
Hướng dẫn
11/1345 phút
Đang tải...

Code Node

Sử dụng JavaScript trong n8n cho custom logic, data processing, và API calls

Code Node

Khi built-in nodes không đủ, Code node cho bạn viết JavaScript tùy ý — từ data processing đến API calls phức tạp.

0

🎯 Mục tiêu bài học

TB5 min

🎯 Mục tiêu

  • Viết code trong n8n Code node
  • Xử lý data phức tạp
  • Call external APIs
  • Build reusable logic

Checkpoint

Khi nào cần dùng Code node thay vì built-in nodes? Cho ví dụ cụ thể.

1

📖 Code Node Basics

TB5 min

1. Code Node Basics

1.1 Two Modes

ModeDescriptionUse Case
Run Once for All ItemsCode chạy 1 lần, nhận tất cả itemsAggregation, sorting, complex logic
Run Once for Each ItemCode chạy cho từng item riêngTransform, validate each item

1.2 Hello World

JavaScript
1// Mode: Run Once for Each Item
2// Input: Each item from previous node
3
4const name = $input.item.json.name;
5const greeting = 'Hello, ' + name + '!';
6
7return {
8 json: {
9 greeting,
10 processedAt: new Date().toISOString()
11 }
12};

1.3 Access Input Data

JavaScript
1// === Run Once for Each Item ===
2const item = $input.item.json;
3// item.name, item.email, item.price...
4
5// === Run Once for All Items ===
6const items = $input.all();
7// items[0].json.name, items[1].json.name...
8
9// Access by node name
10const webhookData = $('Webhook').item.json;
11const sheetsData = $('Google Sheets').all();

1.4 Return Data

JavaScript
1// Return single item
2return {
3 json: { result: "success", value: 42 }
4};
5
6// Return multiple items
7return [
8 { json: { name: "A", score: 95 } },
9 { json: { name: "B", score: 87 } },
10 { json: { name: "C", score: 72 } }
11];
12
13// Return nothing (filter out item)
14return [];

Checkpoint

Phân biệt "Run Once for All Items" và "Run Once for Each Item". Khi nào dùng mode nào?

2

📊 Data Processing

TB5 min

2. Data Processing

2.1 Map & Transform

JavaScript
1// Mode: Run Once for All Items
2const items = $input.all();
3
4const transformed = items.map(item => {
5 const d = item.json;
6 return {
7 json: {
8 fullName: (d.firstName + ' ' + d.lastName).trim(),
9 email: d.email.toLowerCase().trim(),
10 revenue: d.quantity * d.unitPrice,
11 category: categorize(d.revenue),
12 isVIP: d.totalSpend > 10000000
13 }
14 };
15});
16
17function categorize(amount) {
18 if (amount > 5000000) return 'Premium';
19 if (amount > 1000000) return 'Standard';
20 return 'Basic';
21}
22
23return transformed;

2.2 Filter Complex Conditions

JavaScript
1// Mode: Run Once for All Items
2const items = $input.all();
3
4const filtered = items.filter(item => {
5 const d = item.json;
6 const createdDate = new Date(d.createdAt);
7 const thirtyDaysAgo = new Date();
8 thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
9
10 return (
11 d.status === 'active' &&
12 d.amount > 0 &&
13 d.email.includes('@') &&
14 createdDate > thirtyDaysAgo
15 );
16});
17
18return filtered;

2.3 Group By & Aggregate

JavaScript
1// Mode: Run Once for All Items
2const items = $input.all();
3
4// Group by category
5const groups = {};
6for (const item of items) {
7 const cat = item.json.category;
8 if (!groups[cat]) {
9 groups[cat] = { count: 0, totalRevenue: 0, items: [] };
10 }
11 groups[cat].count++;
12 groups[cat].totalRevenue += item.json.revenue;
13 groups[cat].items.push(item.json.name);
14}
15
16// Convert to array of items
17return Object.entries(groups).map(([category, data]) => ({
18 json: {
19 category,
20 count: data.count,
21 totalRevenue: data.totalRevenue,
22 avgRevenue: Math.round(data.totalRevenue / data.count),
23 topItems: data.items.slice(0, 5)
24 }
25}));

2.4 Deduplicate with Priority

JavaScript
1// Keep highest-value duplicate
2const items = $input.all();
3const unique = new Map();
4
5for (const item of items) {
6 const key = item.json.email;
7 const existing = unique.get(key);
8
9 if (!existing || item.json.value > existing.json.value) {
10 unique.set(key, item);
11 }
12}
13
14return Array.from(unique.values());

Checkpoint

Viết code Group By category và tính tổng revenue. Dùng approach nào?

3

📝 String & Date Processing

TB5 min

3. String & Date Processing

3.1 Vietnamese Text Processing

JavaScript
1// Remove Vietnamese diacritics
2function removeDiacritics(str) {
3 return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
4}
5
6// Slug generation
7function toSlug(text) {
8 return removeDiacritics(text)
9 .toLowerCase()
10 .replace(/[^a-z0-9]+/g, '-')
11 .replace(/^-|-$/g, '');
12}
13
14const name = $input.item.json.name; // "Nguyễn Văn Anh"
15return {
16 json: {
17 name,
18 slug: toSlug(name), // "nguyen-van-anh"
19 search: removeDiacritics(name) // "Nguyen Van Anh"
20 }
21};

3.2 Date Operations

JavaScript
1// Parse & format dates
2const dateStr = $input.item.json.date; // "2026-01-20"
3const date = new Date(dateStr);
4
5const day = date.getDate().toString().padStart(2, '0');
6const month = (date.getMonth() + 1).toString().padStart(2, '0');
7const year = date.getFullYear();
8
9return {
10 json: {
11 original: dateStr,
12 formatted: day + '/' + month + '/' + year, // "20/01/2026"
13 dayOfWeek: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'][date.getDay()],
14 isWeekend: [0, 6].includes(date.getDay()),
15 daysFromNow: Math.ceil((date - new Date()) / (1000 * 60 * 60 * 24))
16 }
17};

3.3 Parse Unstructured Text

JavaScript
1// Extract info from email body
2const body = $input.item.json.emailBody;
3
4// Extract order number: "Order #12345"
5const orderMatch = body.match(/Order #(\d+)/i);
6const orderId = orderMatch ? orderMatch[1] : null;
7
8// Extract amount: "Total: 1,500,000 VND"
9const amountMatch = body.match(/Total:\s*([\d,]+)\s*VND/i);
10const amount = amountMatch
11 ? parseInt(amountMatch[1].replace(/,/g, ''))
12 : null;
13
14// Extract email
15const emailMatch = body.match(/[\w.-]+@[\w.-]+\.\w+/);
16const email = emailMatch ? emailMatch[0] : null;
17
18return {
19 json: { orderId, amount, email, rawBody: body }
20};

Checkpoint

Hàm removeDiacritics hoạt động như thế nào? Regex /[\u0300-\u036f]/g match cái gì?

4

🌐 HTTP Requests in Code

TB5 min

4. HTTP Requests in Code

4.1 Fetch API

JavaScript
1// Mode: Run Once for Each Item
2const userId = $input.item.json.userId;
3
4const response = await fetch('https://api.example.com/users/' + userId, {
5 method: 'GET',
6 headers: {
7 'Authorization': 'Bearer ' + $env.API_TOKEN,
8 'Content-Type': 'application/json'
9 }
10});
11
12if (!response.ok) {
13 throw new Error('API error: ' + response.status);
14}
15
16const userData = await response.json();
17
18return {
19 json: {
20 ...($input.item.json),
21 userName: userData.name,
22 userEmail: userData.email
23 }
24};

4.2 POST Request

JavaScript
1const payload = {
2 model: "gpt-4o-mini",
3 messages: [
4 { role: "system", content: "Classify this text as positive/negative/neutral." },
5 { role: "user", content: $input.item.json.text }
6 ],
7 temperature: 0
8};
9
10const response = await fetch('https://api.openai.com/v1/chat/completions', {
11 method: 'POST',
12 headers: {
13 'Authorization': 'Bearer ' + $env.OPENAI_API_KEY,
14 'Content-Type': 'application/json'
15 },
16 body: JSON.stringify(payload)
17});
18
19const data = await response.json();
20const sentiment = data.choices[0].message.content;
21
22return {
23 json: {
24 text: $input.item.json.text,
25 sentiment
26 }
27};

Checkpoint

Cách gọi API bằng fetch() trong Code node? Cần await và xử lý response ra sao?

5

🛡️ Error Handling

TB5 min

5. Error Handling

5.1 Try-Catch

JavaScript
1try {
2 const data = JSON.parse($input.item.json.rawData);
3 const result = processData(data);
4
5 return {
6 json: { success: true, result }
7 };
8} catch (error) {
9 return {
10 json: {
11 success: false,
12 error: error.message,
13 originalData: $input.item.json.rawData
14 }
15 };
16}

5.2 Validation

JavaScript
1function validate(item) {
2 const errors = [];
3
4 if (!item.email || !item.email.includes('@'))
5 errors.push('Invalid email');
6
7 if (!item.name || item.name.length < 2)
8 errors.push('Name too short');
9
10 if (item.amount && item.amount < 0)
11 errors.push('Negative amount');
12
13 return errors;
14}
15
16const errors = validate($input.item.json);
17
18if (errors.length > 0) {
19 return {
20 json: {
21 valid: false,
22 errors,
23 original: $input.item.json
24 }
25 };
26}
27
28return {
29 json: {
30 valid: true,
31 ...$input.item.json
32 }
33};

Checkpoint

Try-catch trong Code node quan trọng vì sao? Validation function nên check những gì?

6

🔧 Practical Patterns

TB5 min

6. Practical Patterns

6.1 Build HTML Email

JavaScript
1const items = $input.all();
2
3// Build table rows from data
4const rows = items.map(item => {
5 const name = item.json.name;
6 const amount = item.json.amount.toLocaleString('vi-VN');
7 const status = item.json.status;
8 return ' <tr><td>' + name + '</td><td>' + amount + ' ₫</td><td>' + status + '</td></tr>';
9}).join('\n');
10
11// Build full HTML
12const header = '<h2>Daily Sales Report</h2>';
13const dateStr = new Date().toLocaleDateString('vi-VN');
14const tableStart = '<table border="1" cellpadding="8">';
15const tableHeader = ' <tr><th>Name</th><th>Amount</th><th>Status</th></tr>';
16const tableEnd = '</table>';
17const footer = '<p>Total: ' + items.length + ' orders</p>';
18
19const html = [header, '<p>Date: ' + dateStr + '</p>',
20 tableStart, tableHeader, rows, tableEnd, footer].join('\n');
21
22return [{ json: { html: html, subject: 'Daily Sales Report' } }];

6.2 CSV Generation

JavaScript
1const items = $input.all();
2const headers = Object.keys(items[0].json);
3
4const csv = [
5 headers.join(','),
6 ...items.map(item =>
7 headers.map(h => '"' + (item.json[h] ?? '') + '"').join(',')
8 )
9].join('\n');
10
11return [{ json: { csv, filename: 'report_' + Date.now() + '.csv' } }];

6.3 Rate-Limited Batch Processing

JavaScript
1const items = $input.all();
2const batchSize = 5;
3const delayMs = 1000;
4const results = [];
5
6for (let i = 0; i < items.length; i += batchSize) {
7 const batch = items.slice(i, i + batchSize);
8
9 const batchResults = await Promise.all(
10 batch.map(item => processItem(item.json))
11 );
12
13 results.push(...batchResults);
14
15 if (i + batchSize < items.length) {
16 await new Promise(resolve => setTimeout(resolve, delayMs));
17 }
18}
19
20return results.map(r => ({ json: r }));

7. Hands-on Lab

Lab 1: CSV Parser & Transformer

  1. Webhook — Receive raw CSV text
  2. Code — Parse CSV, clean data, calculate totals
  3. Code — Generate summary (groups, averages, top items)
  4. Slack — Post formatted results

Lab 2: AI-Powered Classifier

  1. Google Sheets — Get unclassified items
  2. Code — Call OpenAI API to classify each item
  3. Code — Aggregate results by classification
  4. Google Sheets — Update with classifications

Lab 3: HTML Report Generator

  1. Schedule (end of day)
  2. HTTP Request — Get day's data from multiple APIs
  3. Code — Build HTML email with tables, charts, KPIs
  4. Email — Send to stakeholders

📝 Quiz

  1. Code node "Run Once for All Items" khác "Each Item" ở?

    • Nhận tất cả items cùng lúc vs từng item
    • Không khác nhau
    • Speed khác nhau
    • Language khác nhau
  2. Để return multiple items từ Code node?

    • Gọi return nhiều lần
    • Return array of json objects (mỗi object có key json)
    • Dùng loop node
    • Không thể
  3. $input.item.json dùng trong mode nào?

    • Run Once for Each Item
    • Run Once for All Items
    • Cả hai
    • Không mode nào

🎯 Key Takeaways

  1. Two modes — "Each Item" for transforms, "All Items" for aggregation
  2. $input — Access current/all items
  3. fetch() — Call any API from code
  4. Return format — Object với key json hoặc array of objects
  5. Error handling — Always try-catch for production workflows

Checkpoint

Viết Code node tạo HTML email report từ danh sách items. Cần return data ở format nào?


🚀 Bài tiếp theo

Error Handling & Monitoring — Xử lý lỗi và monitoring production workflows!