Lý thuyết
40 phút
Bài 6/7

Google Workspace Integration

Kết nối n8n với Google Sheets, Gmail, Drive, Calendar - Tự động hóa toàn bộ Google Workspace

Google Workspace Integration

Google Workspace là nền tảng productivity phổ biến nhất. Học cách tự động hóa Google Sheets, Gmail, Drive sẽ unlock rất nhiều use cases.

🎯 Mục tiêu

  • Setup Google credentials trong n8n
  • Automate Google Sheets operations
  • Build Gmail automation workflows
  • Integrate Drive và Calendar

1. Setup Google Credentials

1.1. Tạo Google Cloud Project

  1. Truy cập Google Cloud Console
  2. Create new project: "n8n-automation"
  3. Enable APIs:
    • Google Sheets API
    • Gmail API
    • Google Drive API
    • Google Calendar API

1.2. Create OAuth Credentials

Text
1Google Cloud Console
2
3 ├── APIs & Services → Credentials
4
5 ├── Create Credentials → OAuth Client ID
6
7 ├── Application type: Web application
8
9 ├── Authorized redirect URIs:
10 │ https://your-n8n.com/rest/oauth2-credential/callback
11 │ (hoặc http://localhost:5678/rest/oauth2-credential/callback)
12
13 └── Copy Client ID và Client Secret

1.3. Add to n8n

  1. n8n → Credentials → Add Credential
  2. Search "Google Sheets OAuth2"
  3. Paste Client ID & Secret
  4. Click "Sign in with Google"
  5. Authorize access

2. Google Sheets Automation

2.1. Common Operations

OperationUse case
Append RowAdd new data
Read RowsGet data
Update RowModify existing
Delete RowRemove data
LookupFind specific row

2.2. Workflow: Form to Sheet

Khi có Google Form submission → Save to master Sheet với timestamp.

Text
1┌──────────────┐ ┌──────────────┐ ┌──────────────┐
2│ Google Forms │────►│ Set Node │────►│Google Sheets │
3│ Trigger │ │(Add timestamp)│ │(Append Row) │
4└──────────────┘ └──────────────┘ └──────────────┘

Step 1: Google Forms Trigger

Text
1Trigger: On form submit
2Form ID: [your form ID]

Step 2: Set Node

JavaScript
1// Add processing timestamp
2Fields:
3- submitted_at: {{ $now.format('YYYY-MM-DD HH:mm:ss') }}
4- processed: true
5- source: "Google Forms"
6
7// Keep original data
8- name: {{ $json.responses.name }}
9- email: {{ $json.responses.email }}

Step 3: Google Sheets

Text
1Operation: Append Row
2Spreadsheet: Master Data
3Sheet: Responses
4Columns:
5 - Name: {{ $json.name }}
6 - Email: {{ $json.email }}
7 - Submitted At: {{ $json.submitted_at }}

2.3. Workflow: Daily Report from Sheet

Mỗi sáng đọc sales data và gửi summary.

Text
1┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
2│ Schedule │────►│Google Sheets │────►│ Code Node │────►│ Slack │
3│ (9 AM daily)│ │ (Read rows) │ │(Calculate) │ │(Send report) │
4└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘

Code Node (Calculate Summary):

JavaScript
1const items = $input.all();
2
3// Calculate totals
4const totalSales = items.reduce((sum, item) =>
5 sum + parseFloat(item.json.amount || 0), 0);
6
7const totalOrders = items.length;
8const avgOrder = totalSales / totalOrders;
9
10// Find top product
11const productCounts = {};
12items.forEach(item => {
13 const product = item.json.product;
14 productCounts[product] = (productCounts[product] || 0) + 1;
15});
16const topProduct = Object.keys(productCounts)
17 .reduce((a, b) => productCounts[a] > productCounts[b] ? a : b);
18
19return [{
20 json: {
21 report_date: new Date().toISOString().split('T')[0],
22 total_sales: totalSales.toFixed(2),
23 total_orders: totalOrders,
24 avg_order: avgOrder.toFixed(2),
25 top_product: topProduct,
26 message: `📊 Daily Sales Report
27
28 Total Sales: $${totalSales.toFixed(2)}
29 Orders: ${totalOrders}
30 Avg Order: $${avgOrder.toFixed(2)}
31 Top Product: ${topProduct}`
32 }
33}];

2.4. Advanced: Lookup và Update

Text
1Workflow: Update order status
2
3Trigger: Webhook (order shipped notification)
4
5 ├── Google Sheets: Lookup (find by Order ID)
6
7 ├── IF: Row found?
8 │ ├── Yes → Google Sheets: Update Row (status = "Shipped")
9 │ └── No → Slack: Alert "Order not found"
10
11 └── Email: Send tracking to customer

3. Gmail Automation

3.1. Gmail Trigger

Text
1Trigger when:
2- New email received
3- Email with specific label
4- Email from specific sender
5- Email with attachment

3.2. Workflow: Invoice Processing

Email invoice → Extract data → Save to Sheet → Archive email

Text
1┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
2│Gmail Trigger │────►│ Code Node │────►│Google Sheets │────►│ Gmail │
3│(Label:Invoice)│ │(Extract data)│ │(Append row) │ │(Add label) │
4└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘

Gmail Trigger Config:

Text
1Trigger: On new email
2Filters:
3 - Label: Invoices
4 - Has Attachment: true

Code Node (Extract Invoice Data):

JavaScript
1const email = $input.first().json;
2
3// Simple extraction from subject/body
4const subject = email.subject;
5const body = email.text;
6
7// Extract invoice number (assuming format: INV-XXXXX)
8const invoiceMatch = body.match(/INV-\d+/);
9const invoiceNumber = invoiceMatch ? invoiceMatch[0] : 'Unknown';
10
11// Extract amount (assuming format: $X,XXX.XX)
12const amountMatch = body.match(/\$[\d,]+\.?\d*/);
13const amount = amountMatch ? amountMatch[0].replace(/[$,]/g, '') : '0';
14
15// Extract date
16const dateMatch = body.match(/\d{1,2}\/\d{1,2}\/\d{4}/);
17const invoiceDate = dateMatch ? dateMatch[0] : new Date().toLocaleDateString();
18
19return [{
20 json: {
21 invoice_number: invoiceNumber,
22 amount: parseFloat(amount),
23 date: invoiceDate,
24 from: email.from,
25 subject: subject,
26 received_at: new Date().toISOString()
27 }
28}];

3.3. Send Emails

Text
1Workflow: Weekly newsletter
2
3Schedule (Monday 9 AM)
4
5 ├── Google Sheets: Get subscribers
6
7 ├── Split In Batches (10 per batch)
8
9 └── Gmail: Send email
10 - To: {{ $json.email }}
11 - Subject: Weekly Update
12 - Body: [HTML template]

Gmail Node Config:

Text
1Operation: Send Email
2To: {{ $json.email }}
3Subject: 📬 Weekly Newsletter - {{ $now.format('MMMM D') }}
4Email Type: HTML
5Body:
HTML
1<div style="font-family: Arial; max-width: 600px; margin: 0 auto;">
2 <h1>Hello {{ $json.name }}!</h1>
3 <p>Here's your weekly update...</p>
4 <a href="https://example.com" style="background: #007bff; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;">
5 Read More
6 </a>
7</div>

4. Google Drive Integration

4.1. Common Operations

OperationDescription
UploadAdd files to Drive
DownloadGet files from Drive
Create FolderOrganize files
MoveReorganize files
ShareSet permissions

4.2. Workflow: Auto-backup Attachments

Email với attachment → Save to Drive → Log to Sheet

Text
1┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
2│Gmail Trigger │────►│Google Drive │────►│Google Sheets │────►│ Gmail │
3│(Has attach) │ │(Upload file) │ │(Log details) │ │(Send confirm)│
4└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘

Google Drive Upload Config:

Text
1Operation: Upload
2File Name: {{ $json.attachments[0].filename }}
3Parent Folder: [Backup Folder ID]
4Binary Property: data (from Gmail attachment)

4.3. Generate and Upload Reports

Text
1Schedule
2
3 ├── HTTP Request: Get data from API
4
5 ├── Code: Generate CSV content
6
7 ├── Google Drive: Upload as CSV
8
9 └── Gmail: Send link to team

5. Google Calendar

5.1. Workflow: Meeting Reminder

Sáng mỗi ngày check calendar và gửi summary.

Text
1┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
2│ Schedule │────►│ Calendar │────►│ Code Node │────►│ Slack │
3│ (7:30 AM) │ │(Get today's) │ │(Format list) │ │(Post agenda) │
4└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘

Google Calendar Config:

Text
1Operation: Get Many
2Calendar: Primary
3Time Min: {{ $now.startOf('day').toISO() }}
4Time Max: {{ $now.endOf('day').toISO() }}

Format Code:

JavaScript
1const events = $input.all();
2
3if (events.length === 0) {
4 return [{
5 json: {
6 message: "📅 No meetings today! Time for deep work. 💪"
7 }
8 }];
9}
10
11const eventList = events.map(e => {
12 const start = new Date(e.json.start.dateTime || e.json.start.date);
13 const time = start.toLocaleTimeString('en-US', {
14 hour: '2-digit',
15 minute: '2-digit'
16 });
17 return `• ${time} - ${e.json.summary}`;
18}).join('\n');
19
20return [{
21 json: {
22 message: `📅 Today's Schedule (${events.length} meetings)\n\n${eventList}`
23 }
24}];

5.2. Auto-create Calendar Events

Text
1Google Form (Meeting Request)
2
3 ├── Google Calendar: Create Event
4
5 ├── Gmail: Send confirmation
6
7 └── Google Sheets: Log request

6. Complete Project: Lead Management

Full Workflow

Text
1Google Form → Sheet → Email Sequence → CRM Update
2
3┌─────────────┐
4│ Google Form │
5│ (New Lead) │
6└──────┬──────┘
7
8
9┌─────────────┐ ┌─────────────┐
10│Google Sheets│────►│ Gmail │
11│(Save + Score)│ │(Welcome) │
12└──────┬──────┘ └─────────────┘
13
14
15┌─────────────┐ ┌─────────────┐
16│ Wait │────►│ Gmail │
17│ (2 days) │ │(Follow-up) │
18└──────┬──────┘ └─────────────┘
19
20
21┌─────────────┐
22│ Slack │
23│(Notify sales)│
24└─────────────┘

Implementation Notes

  1. Lead Scoring (Code Node):
JavaScript
1const lead = $input.first().json;
2
3let score = 0;
4// Score based on company size
5if (lead.company_size === 'Enterprise') score += 30;
6else if (lead.company_size === 'SMB') score += 20;
7else score += 10;
8
9// Score based on urgency
10if (lead.timeline === 'Immediate') score += 40;
11else if (lead.timeline === '1-3 months') score += 25;
12else score += 10;
13
14return [{
15 json: {
16 ...lead,
17 lead_score: score,
18 priority: score >= 60 ? 'High' : score >= 40 ? 'Medium' : 'Low'
19 }
20}];
  1. Conditional Follow-up:
Text
1IF lead_score >= 60:
2 → Immediate sales call
3 → Personal email from account exec
4ELSE:
5 → Nurture sequence
6 → Weekly newsletter

📝 Quiz

  1. OAuth2 credentials cần gì từ Google Cloud?

    • API Key only
    • Client ID và Client Secret
    • Service Account
    • Username/Password
  2. Google Sheets "Append Row" làm gì?

    • Xóa row cuối
    • Update row đầu
    • Thêm row mới ở cuối
    • Replace toàn bộ data
  3. Gmail trigger có thể filter theo?

    • Chỉ sender
    • Chỉ subject
    • Label, sender, attachment, và nhiều criteria khác
    • Không filter được
  4. Cách upload file lên Drive trong n8n?

    • Paste URL
    • Dùng binary data từ node trước
    • Chỉ text files
    • Không thể upload qua n8n

🎯 Key Takeaways

  1. OAuth2 setup cần làm 1 lần, dùng cho nhiều workflows
  2. Google Sheets = Database đơn giản cho automation
  3. Gmail + Drive + Calendar = Full productivity automation
  4. Combine services để build complex workflows
  5. Code nodes help extract/transform data linh hoạt

🚀 Bài tiếp theo

Error Handling và Monitoring - Học cách xử lý lỗi và monitor workflows production!