hướng dẫn A–Z theo cách ổn định + dễ scale nhiều blog

Ok, đây là một workflow rất “chuẩn hệ thống” – đúng kiểu bạn đang build: viết → đánh dấu → tự động xuất bản. Mình sẽ hướng dẫn A–Z theo cách ổn định + dễ scale nhiều blog (không lỗi vặt).


🧠 Tổng quan luồng

  1. Viết bài trong Google Docs
  2. Lưu metadata (title, docId, status…) trong Google Sheets
  3. Apps Script đọc Sheet
  4. Nếu status = publish → lấy nội dung Docs
  5. Gọi Blogger API → đăng bài

⚙️ Bước 1: Chuẩn bị Google Sheet

Tạo 1 sheet tên posts với cấu trúc:

A

B

C

D

E

title

docId

status

postId

publishedAt

👉 Giải thích:

  • title: tiêu đề bài
  • docId: ID của Google Docs (lấy trên URL)
  • status: draft / publish
  • postId: lưu lại ID Blogger sau khi đăng
  • publishedAt: thời gian đăng

✍️ Bước 2: Viết bài trong Google Docs

  • Viết bình thường
  • Có thể dùng:
  • H1 = title
  • H2 = heading
  • Lấy docId từ URL:

https://docs.google.com/document/d/XXXXXXXXXXXX/edit

👉 Copy đoạn XXXXXXXXXXXX bỏ vào Sheet


🔐 Bước 3: Bật Blogger API

Vào Apps Script:

  1. Services (Dịch vụ nâng cao)
     → bật Blogger API
  2. Vào: 👉 https://console.cloud.google.com
     → bật luôn Blogger API v3

🧩 Bước 4: Code Apps Script

Dán code này vào:

function publishPosts() {
 
const blogId = "YOUR_BLOG_ID";

 
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("posts");
 
const data = sheet.getDataRange().getValues();

 
for (let i = 1; i < data.length; i++) {
   
const [title, docId, status, postId] = data[i];

   
if (status !== "publish" || postId) continue;

   
try {
     
const content = getDocContent(docId);

     
const post = {
       title: title,
       content: content
     };

     
const response = Blogger.Posts.insert(post, blogId);

     sheet.getRange(i + 1, 4).setValue(response.id);
     sheet.getRange(i + 1, 5).setValue(
new Date());

   }
catch (err) {
     Logger.log(err);
   }
 }
}


📄 Bước 5: Hàm lấy nội dung Google Docs

function getDocContent(docId) {
 
const doc = DocumentApp.openById(docId);
 
const body = doc.getBody();

 
let html = "";

 
const elements = body.getNumChildren();

 
for (let i = 0; i < elements; i++) {
   
const el = body.getChild(i);

   
if (el.getType() === DocumentApp.ElementType.PARAGRAPH) {
     html +=
"<p>" + el.asParagraph().getText() + "</p>";
   }

   
if (el.getType() === DocumentApp.ElementType.LIST_ITEM) {
     html +=
"<li>" + el.asListItem().getText() + "</li>";
   }
 }

 
return html;
}


🚀 Bước 6: Lấy blogId

Cách nhanh nhất:

  1. Vào Blogger
  2. Mở blog
  3. URL dạng:

https://www.blogger.com/blog/posts/XXXXXXXX

👉 XXXXXXXX chính là blogId


⚡ Bước 7: Tự động hóa (Auto chạy)

Vào: Triggers → Add Trigger

  • Function: publishPosts
  • Event: Time-driven
  • Chọn:
  • mỗi 5 phút / 10 phút

👉 Từ đây: chỉ cần set status = publish → auto đăng


🔥 Nâng cấp xịn (khuyên dùng)

1. Thêm cột slug + label

slug

labels

const post = {
 
title: title,
 
content: content,
 
labels: ["blog", "auto"],
 url: slug
};


2. Viết Markdown trong Docs → convert HTML

(để đẹp hơn, chuẩn SEO hơn)


3. Sync nhiều blog

Tạo thêm cột:

blogId

→ mỗi dòng đăng blog khác nhau


4. Chống đăng trùng

Bạn đã có:

if (postId) continue;

👉 OK rồi


⚠️ Lỗi phổ biến bạn từng gặp

👉 ReferenceError: Blogger is not defined

✔ Fix:

  • chưa bật Advanced Blogger Service
  • hoặc chưa bật trong Google Cloud

🧠 Tư duy hệ thống của bạn (rất đáng giá)

Cái bạn đang build thực chất là:

“CMS cá nhân hóa bằng Google ecosystem”

Nâng cấp thêm 1 chút là thành:

  • Notion AI → viết
  • Sheet → control
  • Script → automation
  • Blogger → distribution

👉 Đây chính là “content machine”


🎯 Tóm gọn 1 câu

Bạn chỉ cần viết → tick publish → hệ thống tự chạy.


Nếu bạn muốn, mình có thể:

  • Hoặc

Bạn đang đi đúng hướng kiểu “người build hệ thống sống bằng automation” rồi đấy.