Hướng dẫn

Google Sheets + Zalo OA: Tự Động Gửi Tin Nhắn Khách Hàng 2026

Tuân HoangTuân Hoang
8 tháng 8, 2026
18 phút đọc
Google Sheets + Zalo OA: Tự Động Gửi Tin Nhắn Khách Hàng 2026

Zalo có hơn 75 triệu người dùng tại Việt Nam — đây là kênh giao tiếp với khách hàng hiệu quả nhất hiện nay.

Hướng dẫn toàn diện kết nối Google Sheets với Zalo Official Account (OA) để tự động gửi tin nhắn thông báo đơn hàng, chăm sóc khách hàng, chúc mừng sinh nhật và blast khuyến mãi — không cần lập trình viên, chỉ cần Apps Script.

1. Zalo OA Là Gì? Tại Sao Dùng Cho Kinh Doanh?

Zalo Official Account (OA) là tài khoản Zalo dành cho doanh nghiệp, thương hiệu và tổ chức — khác với tài khoản cá nhân thông thường. Với Zalo OA, bạn có thể:

  • Gửi tin nhắn broadcast đến tất cả người theo dõi (follower)
  • Nhận và phản hồi tin nhắn từ khách hàng qua giao diện quản lý
  • Gửi tin nhắn tự động qua Zalo API khi tích hợp với hệ thống bên ngoài
  • Chia sẻ bài viết, sản phẩm, chương trình khuyến mãi lên feed của follower
  • Phân tích thống kê tương tác — tỷ lệ mở, click, follow/unfollow

75M+

Người dùng Zalo tại VN

95% dùng hàng ngày

85%

Tỷ lệ mở tin nhắn OA

Cao hơn email 4-5 lần

Free

API cơ bản miễn phí

Gói trả phí từ 300K/tháng

So Sánh Zalo OA vs Facebook Page vs Email Marketing

Tiêu ChíZalo OAFacebook PageEmail Marketing
Tỷ lệ mở80–90%2–5% (organic)20–30%
Tỷ lệ click15–25%0.5–1%2–5%
Chi phí/tin nhắn~0–50đ200–2000đ (ads)50–200đ
Độ phù hợp VNRất caoCaoTrung bình
Tích hợp APICó (REST API)Có (Graph API)Có (nhiều dịch vụ)
Phù hợp SME VNTốt nhấtTốtTrung bình

2. Tạo Và Cấu Hình Zalo OA

Trước khi tích hợp với Google Sheets, bạn cần có Zalo OA đã được xác minh. Quy trình:

Bước 1: Đăng Ký Zalo OA

  1. Truy cập oa.zalo.me và chọn "Tạo OA mới"
  2. Chọn loại OA: Doanh nghiệp (được gửi tin nhắn theo dõi tự động)
  3. Điền thông tin: Tên OA, danh mục, mô tả, logo, ảnh bìa
  4. Xác minh tài khoản với CMND/CCCD và giấy phép kinh doanh (nếu có)
  5. Chờ duyệt 1-3 ngày làm việc

Bước 2: Kích Hoạt Tính Năng API

Sau khi OA được duyệt, vào phần Cài đặt → Tích hợp API:

  • Tạo ứng dụng tại developers.zalo.me
  • Đăng ký ứng dụng với loại "Official Account"
  • Lấy App IDApp Secret
  • Cấu hình redirect URI (dùng cho OAuth flow lấy token)

Lưu ý quan trọng về phân loại OA:

  • OA Basic (miễn phí): Gửi ZNS tin nhắn dạng template, giới hạn 3,000 tin/tháng
  • OA Pro (trả phí): Gửi tin nhắn tự do (Broadcast), phân tích nâng cao, từ 300K/tháng
  • • Để tự động hóa nâng cao (ví dụ: gửi theo sự kiện đơn hàng), cần tích hợp ZNS (Zalo Notification Service)

3. Lấy Access Token Zalo API

Access Token là "chìa khóa" để Apps Script giao tiếp với Zalo API. Có 2 loại token:

OA Access Token (Dành Cho Gửi Tin OA)

Token này cho phép gửi tin nhắn từ OA tới người dùng đã follow OA.

// Buoc 1: Lay Authorization Code
// Truy cap URL nay trong browser, dang nhap bang tai khoan OA:
https://oauth.zaloapp.com/v4/oa/permission?app_id=YOUR_APP_ID
  &redirect_uri=https://example.com/callback
  &code_challenge=GENERATED_CODE_CHALLENGE

// Buoc 2: Doi code lay Access Token
// POST request:
POST https://oauth.zaloapp.com/v4/oa/access_token
Content-Type: application/x-www-form-urlencoded

app_id=YOUR_APP_ID
&app_secret=YOUR_APP_SECRET
&code=AUTHORIZATION_CODE_FROM_STEP_1
&grant_type=authorization_code
&code_verifier=ORIGINAL_CODE_VERIFIER

// Response:
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6Ikp...",
  "refresh_token": "6uf5b1a7...",
  "expires_in": 86400
}

Lưu Token Vào Google Sheets

Để Apps Script sử dụng được token, lưu vào một tab riêng trong Google Sheets:

// Tab: Config (an khoi nguoi dung thuong)
// Row 1: ZALO_ACCESS_TOKEN | [gia tri token]
// Row 2: ZALO_REFRESH_TOKEN | [gia tri refresh token]
// Row 3: ZALO_APP_ID       | [app id]
// Row 4: ZALO_APP_SECRET   | [app secret]
// Row 5: TOKEN_EXPIRES_AT  | [timestamp het han]

// Ham lay token trong Apps Script:
function getZaloToken() {
  const ss = SpreadsheetApp.getActiveSpreadsheet()
  const config = ss.getSheetByName("Config")
  const data = config.getDataRange().getValues()
  const tokenMap = {}
  for (const row of data) {
    tokenMap[row[0]] = row[1]
  }
  return tokenMap["ZALO_ACCESS_TOKEN"]
}

Tự Động Refresh Token

Token Zalo có hạn 24 giờ. Cần script tự động refresh:

function refreshZaloToken() {
  const ss = SpreadsheetApp.getActiveSpreadsheet()
  const config = ss.getSheetByName("Config")
  const data = config.getDataRange().getValues()
  const tokenMap = {}
  const rowMap = {}
  for (let i = 0; i < data.length; i++) {
    tokenMap[data[i][0]] = data[i][1]
    rowMap[data[i][0]] = i + 1
  }

  const response = UrlFetchApp.fetch("https://oauth.zaloapp.com/v4/oa/access_token", {
    method: "POST",
    contentType: "application/x-www-form-urlencoded",
    payload: [
      "app_id=" + tokenMap["ZALO_APP_ID"],
      "grant_type=refresh_token",
      "refresh_token=" + tokenMap["ZALO_REFRESH_TOKEN"]
    ].join("&")
  })

  const result = JSON.parse(response.getContentText())
  if (result.access_token) {
    config.getRange(rowMap["ZALO_ACCESS_TOKEN"], 2).setValue(result.access_token)
    config.getRange(rowMap["ZALO_REFRESH_TOKEN"], 2).setValue(result.refresh_token)
    config.getRange(rowMap["TOKEN_EXPIRES_AT"], 2).setValue(new Date().getTime() + 86400000)
    console.log("Token refreshed successfully")
  }
}

// Cai trigger tu dong refresh moi 20 gio:
function setupRefreshTrigger() {
  ScriptApp.newTrigger("refreshZaloToken")
    .timeBased().everyHours(20).create()
}

4. Cấu Trúc Google Sheets Cho Quản Lý Khách Hàng

Trước khi tích hợp Zalo, bạn cần thiết kế Google Sheets lưu trữ thông tin khách hàng đúng chuẩn. Cấu trúc đề xuất:

TabMục ĐíchCột Chính
KhachHangDanh sách khách hàngMaKH, Ho Ten, Zalo ID, SĐT, Ngày Sinh, Nhóm KH, Ngày Theo Dõi OA
DonHangĐơn hàngMaDH, MaKH, Ngày, SanPham, SoTien, TrangThai, Giao Hàng
LichSuZaloLog tin nhắn đã gửiThời Gian, MaKH, LoaiTin, NoiDung, TrangThai Gửi
ConfigCấu hình token và settingsKey, Value
TemplateTemplate tin nhắnTenTemplate, NoiDung, ThamSo, TrangThai

Lấy Zalo User ID Của Khách Hàng

Để gửi tin nhắn tới khách hàng cụ thể, bạn cần Zalo User ID (UID) của họ. Có 3 cách lấy UID:

  • Cách 1 — Webhook OA: Khi khách nhắn tin cho OA, webhook trả về UID. Tự động nhất.
  • Cách 2 — Đăng nhập Zalo: Nhúng nút "Đăng nhập Zalo" vào website/form, lấy UID khi họ đăng nhập.
  • Cách 3 — QR Code OA: Khách quét QR follow OA, bạn lấy UID từ event follower mới.

Mẹo thực tế:

Tạo form Google Forms có nút "Xác nhận qua Zalo". Khi khách điền form và xác nhận, bạn vừa lấy được SĐT vừa lấy được Zalo UID. Lưu cả hai vào tab KhachHang để dùng cho cả SMS và Zalo OA sau này.

5. Apps Script: Gửi Tin Nhắn Cơ Bản Qua Zalo API

Đây là hàm cốt lõi — gửi một tin nhắn văn bản tới một Zalo UID cụ thể:

// Ham gui tin nhan van ban toi mot Zalo UID
function sendZaloMessage(toUserId, message) {
  const token = getZaloToken()  // Ham lay token da viet o tren

  const payload = {
    recipient: { user_id: toUserId },
    message: { text: message }
  }

  const options = {
    method: "POST",
    contentType: "application/json",
    headers: { "access_token": token },
    payload: JSON.stringify(payload)
  }

  const response = UrlFetchApp.fetch(
    "https://openapi.zalo.me/v3.0/oa/message/cs",
    options
  )
  const result = JSON.parse(response.getContentText())

  // Log ket qua vao sheet
  const ss = SpreadsheetApp.getActiveSpreadsheet()
  const logSheet = ss.getSheetByName("LichSuZalo")
  logSheet.appendRow([
    new Date(),
    toUserId,
    "TEXT",
    message.substring(0, 100),
    result.error === 0 ? "THANH CONG" : "LOI: " + result.message
  ])

  return result
}

// Ham gui tin nhan co anh va nut bam (dang Banner)
function sendZaloBannerMessage(toUserId, title, description, imageUrl, btnText, btnUrl) {
  const token = getZaloToken()

  const payload = {
    recipient: { user_id: toUserId },
    message: {
      attachment: {
        type: "template",
        payload: {
          template_type: "banner",
          elements: [{
            media_type: "image",
            attachment_id: imageUrl,
            title: title,
            subtitle: description,
            default_action: { type: "oa.open.url", url: btnUrl },
            buttons: [{
              title: btnText,
              type: "oa.open.url",
              payload: { url: btnUrl }
            }]
          }]
        }
      }
    }
  }

  const options = {
    method: "POST",
    contentType: "application/json",
    headers: { "access_token": token },
    payload: JSON.stringify(payload)
  }

  return JSON.parse(UrlFetchApp.fetch(
    "https://openapi.zalo.me/v3.0/oa/message/cs",
    options
  ).getContentText())
}

6. Tự Động Thông Báo Đơn Hàng Và Giao Hàng

Đây là use case phổ biến nhất và hiệu quả nhất. Khi khách đặt hàng hoặc trạng thái đơn thay đổi, tự động gửi Zalo.

Trigger Theo Sự Kiện Thay Đổi Trong Sheet

// Trigger: Khi nguoi dung chinh sua sheet DonHang
function onEdit(e) {
  const sheet = e.range.getSheet()
  if (sheet.getName() !== "DonHang") return

  const row = e.range.getRow()
  const col = e.range.getColumn()

  // Col 8 = TrangThai don hang
  if (col !== 8 || row <= 1) return

  const rowData = sheet.getRange(row, 1, 1, 15).getValues()[0]
  const [maDH, maKH, ngay, sanPham, soTien, soLuong, dvt, trangThai] = rowData

  // Tim Zalo UID cua khach hang
  const ss = SpreadsheetApp.getActiveSpreadsheet()
  const khSheet = ss.getSheetByName("KhachHang")
  const khData = khSheet.getDataRange().getValues()
  let zaloId = ""
  let hoTen = ""
  for (let i = 1; i < khData.length; i++) {
    if (khData[i][0] === maKH) {
      zaloId = khData[i][2]  // Col 3 = Zalo ID
      hoTen = khData[i][1]   // Col 2 = Ho Ten
      break
    }
  }

  if (!zaloId) return

  // Tao noi dung tin nhan theo trang thai
  let message = ""
  if (trangThai === "XAC_NHAN") {
    message = "Xin chao " + hoTen + ",\n"
      + "Don hang #" + maDH + " da duoc xac nhan!\n"
      + "San pham: " + sanPham + "\n"
      + "Tong tien: " + Number(soTien).toLocaleString("vi-VN") + " dong\n"
      + "Chung toi se xu ly va lien he ban som nhat. Cam on ban!"
  } else if (trangThai === "DANG_GIAO") {
    message = "Don hang #" + maDH + " dang tren duong giao!\n"
      + "Du kien giao trong 1-3 ngay lam viec.\n"
      + "Lien he hotline neu can: 1900xxxx"
  } else if (trangThai === "DA_GIAO") {
    message = "Don hang #" + maDH + " da giao thanh cong!\n"
      + "Cam on " + hoTen + " da mua hang. Mong nhan duoc phan hoi cua ban!\n"
      + "Danh gia san pham: https://sheet.com.vn/review"
  } else if (trangThai === "HUY") {
    message = "Don hang #" + maDH + " da bi huy theo yeu cau.\n"
      + "Neu co thac mac, lien he: https://sheet.com.vn/support"
  }

  if (message) {
    sendZaloMessage(zaloId, message)
  }
}

Bảng Trạng Thái Đơn Hàng Và Tin Nhắn Tương Ứng

Trạng TháiNội Dung ChínhThời Điểm GửiLoại Tin
XAC_NHANXác nhận đơn, tóm tắt sản phẩm, tổng tiềnNgay khi xác nhậnCS Message
DANG_XU_LYĐang đóng gói, thời gian xử lýKhi cập nhậtCS Message
DANG_GIAOĐang vận chuyển, mã vận đơn, link tra cứuKhi bàn giao shipCS Message
DA_GIAOGiao thành công, mời đánh giáSau giao hàng 2hCS Message
HUYThông báo hủy, hướng dẫn hỗ trợNgay khi hủyCS Message
HOAN_TIENThông tin hoàn tiền, thời hạn xử lýKhi xác nhận hoànCS Message

7. Gửi Chúc Mừng Sinh Nhật Tự Động

Tin nhắn chúc sinh nhật là một trong những chiến dịch retention marketing có tỷ lệ chuyển đổi cao nhất — khách hàng cảm thấy được quan tâm và thường kèm mã giảm giá để tăng doanh thu.

// Chay moi ngay luc 8:00 sang de kiem tra sinh nhat
function sendBirthdayMessages() {
  const ss = SpreadsheetApp.getActiveSpreadsheet()
  const khSheet = ss.getSheetByName("KhachHang")
  const data = khSheet.getDataRange().getValues()

  const today = new Date()
  const todayMonth = today.getMonth() + 1
  const todayDay = today.getDate()

  for (let i = 1; i < data.length; i++) {
    const [maKH, hoTen, zaloId, sdt, ngaySinh] = data[i]
    if (!ngaySinh || !zaloId) continue

    const bd = new Date(ngaySinh)
    const bdMonth = bd.getMonth() + 1
    const bdDay = bd.getDate()

    if (bdMonth === todayMonth && bdDay === todayDay) {
      const tuoi = today.getFullYear() - bd.getFullYear()
      const maGiamGia = "BD" + maKH.toString().slice(-4) + today.getFullYear()
      const message = "Chuc Mung Sinh Nhat " + hoTen + "!\n"
        + "Nhan hang SheetStore gui tang ban mon qua dac biet:\n"
        + "GIAM 20% don hang trong hom nay voi ma: " + maGiamGia + "\n"
        + "Chuc ban tuoi " + tuoi + " that nhieu suc khoe va hanh phuc!\n"
        + "Xem san pham: https://sheet.com.vn/marketplace"

      const result = sendZaloMessage(zaloId, message)
      console.log("Birthday sent to " + hoTen + ":", result.error === 0 ? "OK" : result.message)

      // Luu ma giam gia vao sheet DiscountCodes de kiem tra sau
      const discountSheet = ss.getSheetByName("MaGiamGia") ||
        ss.insertSheet("MaGiamGia")
      discountSheet.appendRow([maGiamGia, maKH, 20, new Date(), new Date(today.getTime() + 86400000), "CHUA_DUNG"])
    }
  }
}

// Cai trigger chay 8h sang moi ngay:
function setupBirthdayTrigger() {
  ScriptApp.newTrigger("sendBirthdayMessages")
    .timeBased().atHour(8).everyDays(1).create()
}

Kết quả thực tế từ khách hàng SheetStore:

Chiến dịch sinh nhật tự động giúp tăng tỷ lệ mua hàng lặp lại lên 35%. Tỷ lệ sử dụng mã giảm giá sinh nhật đạt 45% — cao hơn nhiều so với broadcast thông thường (8-12%).

8. Blast Khuyến Mãi Hàng Loạt

Gửi tin nhắn hàng loạt (broadcast) tới tất cả follower hoặc nhóm khách hàng cụ thể khi có chương trình khuyến mãi:

// Blast tin nhan khuyen mai toi nhom khach hang
// Tham so: nhomKH = "VIP" | "THUONG_XUYEN" | "TAT_CA"
function blastPromotion(tieudeTin, noiDungTin, nhomKH, gioiHanSoLuong) {
  const ss = SpreadsheetApp.getActiveSpreadsheet()
  const khSheet = ss.getSheetByName("KhachHang")
  const data = khSheet.getDataRange().getValues()

  let danhSachGui = []
  for (let i = 1; i < data.length; i++) {
    const [maKH, hoTen, zaloId, sdt, ngaySinh, nhomKHData] = data[i]
    if (!zaloId) continue
    if (nhomKH !== "TAT_CA" && nhomKHData !== nhomKH) continue
    danhSachGui.push({ maKH, hoTen, zaloId })
  }

  // Gioi han so luong neu can
  if (gioiHanSoLuong > 0) {
    danhSachGui = danhSachGui.slice(0, gioiHanSoLuong)
  }

  console.log("Sending to " + danhSachGui.length + " customers...")

  let thanhCong = 0, thatBai = 0
  for (const kh of danhSachGui) {
    // Personalize tin nhan voi ten khach
    const tinNhanCaNhan = noiDungTin.replace("{ten}", kh.hoTen)

    const result = sendZaloMessage(kh.zaloId, tinNhanCaNhan)

    if (result.error === 0) {
      thanhCong++
    } else {
      thatBai++
      console.log("Failed for " + kh.maKH + ":", result.message)
    }

    // Delay 100ms giua moi tin de tranh rate limit
    Utilities.sleep(100)
  }

  console.log("Done! Thanh cong: " + thanhCong + ", That bai: " + thatBai)
  return { thanhCong, thatBai, tongGui: danhSachGui.length }
}

// Vi du su dung:
function chayBlastTetNguyen() {
  blastPromotion(
    "Khuyen mai Tet 2026",
    "Chao {ten}! Mung nam moi 2026!\n"
    + "SheetStore giam 30% tat ca goi trong thang 1.\n"
    + "Ma: TET2026 - Han dung: 31/01/2026\n"
    + "Dang ky ngay: https://sheet.com.vn/bang-gia",
    "TAT_CA",
    0  // 0 = khong gioi han
  )
}

Lưu ý về giới hạn rate Zalo API:

  • CS Message (free): 100 tin/giây, tối đa khi trong cửa sổ 48h sau tương tác của khách
  • ZNS (trả phí): Gửi không giới hạn thời gian, cần template được duyệt, từ 100đ/tin
  • Broadcast (OA Pro): Gửi tới tất cả follower theo batch, tối đa 100K tin/lần
  • • Luôn thêm Utilities.sleep(100) giữa các lần gửi liên tiếp để tránh bị block

9. Thư Viện Template Tin Nhắn Hiệu Quả

Tin nhắn hiệu quả cần ngắn gọn, cá nhân hóa, có CTA rõ ràng. Dưới đây là các template thực tế:

Template 1: Xác Nhận Đơn Hàng

Xin chào [Tên khách],
Đơn hàng #[Mã DH] đã được xác nhận!
▪ [Sản phẩm] x[Số lượng]: [Giá tiền]đ
Tổng: [Tổng tiền]đ
Giao hàng dự kiến: [Ngày]
Theo dõi đơn: https://sheet.com.vn/track/[MaDH]

Template 2: Nhắc Nhở Giỏ Hàng Bỏ Quên

Chào [Tên],
Bạn vẫn còn [X sản phẩm] trong giỏ hàng 🛒
Đừng để vuột mất — chỉ còn [X] sản phẩm trong kho!
Hoàn tất mua hàng: https://sheet.com.vn/cart
Cần hỗ trợ? Reply tin này nhé!

Template 3: Upsell Sau Mua Hàng

Hi [Tên], đơn #[MaDH] đã đến nơi!
Khách hàng dùng [Sản phẩm đã mua] thường cũng thích:
▪ [Sản phẩm gợi ý 1] — [Giá]
▪ [Sản phẩm gợi ý 2] — [Giá]
Giảm thêm 10% với mã: UPSELL10
Xem ngay: https://sheet.com.vn

Template 4: Tái Kích Hoạt Khách Không Hoạt Động

Chào [Tên], lâu không gặp!
Đã [X] ngày kể từ lần mua cuối. Chúng tôi nhớ bạn 😊
Có rất nhiều sản phẩm mới kể từ đó...
Quay lại hôm nay và nhận ưu đãi đặc biệt: COMEBACK15
Khám phá: https://sheet.com.vn/marketplace

// Ham gui tin nhan tai kich hoat khach khong hoat dong 30+ ngay
function sendReactivationMessages() {
  const ss = SpreadsheetApp.getActiveSpreadsheet()
  const dhSheet = ss.getSheetByName("DonHang")
  const khSheet = ss.getSheetByName("KhachHang")

  const dhData = dhSheet.getDataRange().getValues()
  const khData = khSheet.getDataRange().getValues()

  // Tim ngay mua hang cuoi cua moi khach
  const lastPurchase = {}
  for (let i = 1; i < dhData.length; i++) {
    const maKH = dhData[i][1]
    const ngayDH = new Date(dhData[i][2])
    if (!lastPurchase[maKH] || ngayDH > lastPurchase[maKH]) {
      lastPurchase[maKH] = ngayDH
    }
  }

  const now = new Date()
  const threshold = 30 * 24 * 60 * 60 * 1000 // 30 ngay

  for (let i = 1; i < khData.length; i++) {
    const [maKH, hoTen, zaloId] = khData[i]
    if (!zaloId || !lastPurchase[maKH]) continue

    const daysSince = (now - lastPurchase[maKH]) / (24 * 60 * 60 * 1000)
    if (daysSince >= 30 && daysSince < 31) { // Chi gui dung ngay thu 30
      const message = "Chao " + hoTen + ", lau khong gap!\n"
        + "Da " + Math.round(daysSince) + " ngay ke tu lan mua cuoi.\n"
        + "Quay lai hom nay va nhan uu dai: COMEBACK15\n"
        + "Kham pha: https://sheet.com.vn/marketplace"
      sendZaloMessage(zaloId, message)
    }
  }
}

10. So Sánh Zalo OA Với Các Kênh Nhắn Tin Khác

Tiêu ChíZalo OASMS GatewayViber OAWhatsApp Business
Độ phủ VNRất cao (75M users)Toàn bộThấp (~5M)Thấp (~3M)
Chi phí cơ bảnMiễn phí (CS Msg)400–800đ/SMSTrả phíTrả phí
Hỗ trợ hình ảnhCó (Banner, Carousel)Không
API tích hợpREST API đầy đủREST APIREST APIREST API
Kết hợp GSheetsDễ dàngTrung bìnhKhóKhó
Tối ưu cho SME VNTốt nhấtTốtKhông phù hợpKhông phù hợp

Với đặc thù thị trường Việt Nam, Zalo OA là lựa chọn rõ ràng nhất. Kết hợp Google Sheets + Apps Script + Zalo OA tạo ra một hệ thống CRM và marketing automation hoàn chỉnh với chi phí chưa đến 1 triệu đồng/tháng.

11. SheetStore: Tích Hợp Zalo OA Sẵn Có

SheetStore cung cấp hệ thống Google Sheets đã tích hợp sẵn với Zalo OA — bạn chỉ cần điền token và bật tính năng, không cần tự viết code.

Tính Năng Zalo Có Sẵn Trong SheetStore

  • ✓ Thông báo đơn hàng tự động 5 trạng thái
  • ✓ Chúc sinh nhật + tặng mã giảm giá tự động
  • ✓ Blast khuyến mãi theo nhóm khách hàng
  • ✓ Nhắc nhở khách hàng không hoạt động
  • ✓ Log lịch sử toàn bộ tin nhắn đã gửi
  • ✓ Dashboard thống kê tỷ lệ gửi thành công

Ưu Điểm So Với Tự Xây Dựng

  • ✓ Tiết kiệm 20-40 giờ lập trình
  • ✓ Template tin nhắn đã được test thực tế
  • ✓ Xử lý token refresh tự động
  • ✓ Error handling và retry logic đầy đủ
  • ✓ Hỗ trợ setup và hướng dẫn sử dụng
  • ✓ Cập nhật khi Zalo API thay đổi

SheetStore Gói Business — Bao Gồm Tích Hợp Zalo OA

Chỉ 1.499.000đ/năm — bao gồm tất cả tính năng Zalo OA automation và hỗ trợ triển khai.

Xem Chi Tiết Gói Business

12. Lỗi Thường Gặp Và Cách Khắc Phục

LỗiNguyên NhânCách Khắc Phục
error: -216Access token hết hạnGọi refreshZaloToken() và thử lại
error: -201User ID không tồn tại hoặc chưa follow OAKiểm tra lại Zalo UID, nhắc khách follow OA trước
error: -400Định dạng request saiKiểm tra JSON payload, headers access_token
error: -216 liên tụcRefresh token cũng hết hạn (sau 90 ngày)Phải lấy lại authorization code từ đầu
Rate limit exceededGửi quá nhanh (>100 tin/giây)Thêm Utilities.sleep(200) giữa các lần gửi
CS Message không hoạt độngNgoài cửa sổ 48h sau tương tác của kháchDùng ZNS thay CS Message cho tin chủ động

13. FAQ — Câu Hỏi Thường Gặp

Khách hàng có bị tính phí khi nhận tin nhắn Zalo OA không?

Không. Phía khách hàng nhận tin hoàn toàn miễn phí. Chỉ có doanh nghiệp (bên gửi) mới phải trả phí nếu dùng ZNS hoặc gói OA Pro. CS Message (gửi trong cửa sổ 48h) miễn phí cho cả hai phía.

Google Apps Script có giới hạn số lần gọi API trong ngày không?

Có. Apps Script miễn phí cho phép tối đa 20,000 lần gọi UrlFetchApp mỗi ngày. Với Google Workspace có thể nâng lên 100,000. Nếu cần gửi hơn 20,000 tin/ngày, nên chuyển sang server VPS thay vì Apps Script.

Làm sao để khách hàng đồng ý nhận tin nhắn từ OA?

Khách phải chủ động follow OA mới nhận được tin nhắn (CS Message). Các cách khuyến khích follow: QR code tại cửa hàng, nút "Theo dõi Zalo OA" trên website, gửi link OA trong hóa đơn. ZNS không yêu cầu follow nhưng cần số điện thoại đã đăng ký Zalo.

SheetStore có hỗ trợ ZNS (Zalo Notification Service) không?

Có, gói SheetStore Business hỗ trợ cả CS Message lẫn ZNS. ZNS cho phép gửi tin nhắn chủ động dựa trên số điện thoại, không cần khách follow OA trước. Chi phí ZNS từ 100–200đ/tin tùy loại template.

Có thể gửi file PDF hóa đơn qua Zalo OA không?

Có, Zalo OA API hỗ trợ gửi file đính kèm bao gồm PDF, hình ảnh. Tuy nhiên, cần upload file lên Zalo trước để lấy attachment_id, sau đó dùng attachment_id đó trong payload gửi tin. Apps Script có thể xử lý việc này thông qua Zalo File Upload API.

Nếu khách unfollow OA thì sao?

Khi khách unfollow, Zalo sẽ gửi event webhook thông báo. Apps Script có thể lắng nghe webhook này để cập nhật trạng thái trong Google Sheets (đánh dấu cột "Follow OA" = FALSE) và không gửi tin nhắn cho họ nữa, tránh bị báo spam.

Tự Động Hóa Chăm Sóc Khách Hàng Qua Zalo Ngay Hôm Nay

SheetStore đã tích hợp sẵn Zalo OA — không cần viết code, triển khai trong 1 ngày làm việc.

Chia sẻ bài viết:

Tuân Hoang

Tuân Hoang

Đội ngũ SheetStore

Bạn thấy bài viết hữu ích?

Đăng ký nhận thông báo khi có bài viết mới.

Nhận thông báo khi có bài viết mới. Không spam, hứa luôn! 😊

Bình luận (0)

Vui lòng đăng nhập để tham gia thảo luận