Hướng dẫn chi tiết từng bước tạo License giao diện cho người mới bắt đầu

Chào mọi người, bài viết này mình chia sẻ việc tạo License cho người mới bắt đầu làm bản quyền giao diện website/blog vừa dễ tiếp thu và dễ hình dung được khi người dùng đăng ký giao diện thì sẻ tự động kiểm tra trên Sever/Mysql/Google Script xem có trùng khớp với người dùng đăng ký không, nếu giao diện sửa đổi thông tin mà người quản trị đã ghi sẳn trên giao diện thì sẻ tự động chuyển hướng về trang quản trị và bắt người dùng mua bản quyền giao diện để hoàn tất việc sử dụng như nhiều trang website bán giao diện hiện tại.

Ở đây mình có thêm về tên miền muốn hiển thị giao diện và thời gian (vd: bạn muốn sử dụng trọn đời thì gửi thời gian muốn hết hạn 10 năm, 20 năm ...v.v) và việc mình thêm có thời gian bản quyền giao diện để phù hợp với một số anh em bạn bè muốn sử dụng giao diện đó có thời gian định sẳn và giá thành khi mua sẻ bớt lại, giảm chi phí khi đầu tư giao diện và có thể thay giao diện khác thoải mái mà không lo nghĩ gì nhiều haha.

Bản thân mình vốn hay thay đổi nhiều giao diện cũng bị nhiều anh em bạn bè nói nên sử dụng một giao diện và viết bài thật tốt để tăng thứ hạng "SEO", bản thân vốn thích tìm hiểu và ưu thích giao diện đẹp, nhanh, chuẩn seo, và khi kiểm tra trên trang "Pagespeed.gooogle.com" sẻ đạt điểm tối đa, bản thân luôn tìm hiểu và mong muôn blog mình sẻ được nhiều anh em bạn bè biết đến và tìm hiểu, nhưng do mình thay đổi tên miền và giao diện quá nhiều nên thứ hạng "SEO" blog của mình không tốt lắm trong giới chuyên môn đánh giá. :D.

Tiếp tục với chủ đề mình đang nói đến đó là việc tạo "License" cho giao diện website/blog.
Ở đây mình giới thiếu trang quản lý keygen đơn giản, mà không tốn chi phí cho việc duy trì và những bạn bè chưa đủ điều kiện để có "VPS/Hosting" làm trang lưu trử "Keygen", đó là "Sheet Google" trang này được phát triển ra để cho người dùng sử dụng như một trang "Word,Excel" nhưng thích ứng thêm phần "App Script" để viết code và tùy biến nội dung hiển thị trên trang "Sheet Google" nên mình đã tìm hiểu từ "Google" và mình đã làm ra một phiên bản không tốt với một số người nhưng lại là niềm vui do chính bản thân mình làm ra.

Hình ảnh bên dưới là khi mình ghi dử liệu tạo "License" sẻ được in thông tin lên "Sheet Google" để mình dễ quản lý và nắm bắt được người mua.

Hướng dẫn chi tiết từng bước tạo License giao diện cho người mới bắt đầu Như mọi người đã thấy thì việc tạo "License" như hình ảnh phía trên có ngày tháng tạo và thời gian "Expired (hêt hạn)" và "Status (trạng thái)", khi mình thay đổi trang thái "Active" thành "None" thì "License" sẻ bị vô hiệu hóa và không còn khả dụng trên trang "Website/Blog" của mọi người nữa.

Bắt đầu công việc.

Bước 1. Mọi người truy cập vào trang : https://docs.google.com/spreadsheets/create và điền thông tin như bên dưới.

Nội dung

key | domain | email | status | expired | created
  

Bước 2. Từ giao diện "Sheet Google" mọi người chọn "Extensions → Apps Script" và dán đoạn code sau vào trang.

App Script
const SHEET_NAME = "Sheet1";
const ADMIN_TOKEN = "hungblog-admin-2026";

function doGet(e) {
  const action = e.parameter.action;

  if (action === "check") {
    return checkLicense(e);
  }

  if (action === "create") {
    return createLicense(e);
  }

  return json({
    success: false,
    message: "Action không hợp lệ"
  });
}

function createLicense(e) {
  const token = e.parameter.token;
  const domain = e.parameter.domain || "";
  const email = e.parameter.email || "";
  const days = Number(e.parameter.days || 365);

  if (token !== ADMIN_TOKEN) {
    return json({
      success: false,
      message: "Sai token admin"
    });
  }

  if (!domain) {
    return json({
      success: false,
      message: "Thiếu domain"
    });
  }

  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);

  const key = generateKey();
  const created = new Date();
  const expired = new Date();
  expired.setDate(expired.getDate() + days);

  sheet.appendRow([
    key,
    cleanDomain(domain),
    email,
    "active",
    formatDate(expired),
    formatDate(created)
  ]);

  return json({
    success: true,
    key: key,
    domain: cleanDomain(domain),
    expired: formatDate(expired)
  });
}

function checkLicense(e) {
  const key = e.parameter.key || "";
  const domain = cleanDomain(e.parameter.domain || "");

  if (!key || !domain) {
    return json({
      valid: false,
      message: "Thiếu key hoặc domain"
    });
  }

  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
  const rows = sheet.getDataRange().getValues();

  for (let i = 1; i < rows.length; i++) {
    const rowKey = rows[i][0];
    const rowDomain = cleanDomain(rows[i][1]);
    const rowStatus = rows[i][3];
    const rowExpired = rows[i][4];

    if (rowKey === key && rowDomain === domain) {
      const today = new Date();
      const expiredDate = new Date(rowExpired);

      if (rowStatus !== "active") {
        return json({
          valid: false,
          message: "Key đã bị khóa"
        });
      }

      if (expiredDate < today) {
        return json({
          valid: false,
          message: "Key đã hết hạn"
        });
      }

      return json({
        valid: true,
        message: "Key hợp lệ",
        expired: rowExpired
      });
    }
  }

  return json({
    valid: false,
    message: "Key không tồn tại hoặc sai tên miền"
  });
}

function generateKey() {
  const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
  let key = "HB";

  for (let block = 0; block < 3; block++) {
    key += "-";
    for (let i = 0; i < 4; i++) {
      key += chars.charAt(Math.floor(Math.random() * chars.length));
    }
  }

  return key;
}

function cleanDomain(domain) {
  return domain
    .replace("https://", "")
    .replace("http://", "")
    .replace("www.", "")
    .replace("/", "")
    .toLowerCase()
    .trim();
}

function formatDate(date) {
  return Utilities.formatDate(date, "Asia/Ho_Chi_Minh", "yyyy-MM-dd");
}

function json(data) {
  return ContentService
    .createTextOutput(JSON.stringify(data))
    .setMimeType(ContentService.MimeType.JSON);
}
  

Ở phần mình bôi đỏ, đó chính là key mặc định để mọi người có thể viết một trang đăng ký trực tuyến, mình sẻ giới thiếu ở phía sau, nếu bản quên "Key" đó thì sẻ không ghi dử liệu trực tuyến được mà bắt buộc chính người quản lý vào đăng ký trực tiếp "License" cho người dùng đăng ký.

Bước 3. Sau khi dán đoạn code ở "Bước 2" và chỉnh sửa lại những thứ bạn mong muốn thì tiếp đó bạn "Deploy Web App" và làm theo từng bước như sau, "Deploy → New deployment → Web app" trong mục bạn điền tên và chọn "Execute as: Me" và "Who has access: Anyone" và trang website sẻ trả về cho bạn một dạng link "script.google.com/xxxx", bạn lưu lại đường link trên và quay trở lại giao diện "website/blog" để viết code "Javascript" để gọi và kiểm tra dử liệu.

Bên dưới là liên kết đăng ký trực tiếp cho người thuần code và ghi nhớ rỏ những biến để ghi dử liệu lên.
Link App Script
LINK_WEB_APP?action=create&token=<b>hungblog-admin-2026</b>&domain=hungblog.com&email=test@gmail.com&days=365
Trong đường link trên, phần mình bôi đen chính là chìa khóa mà để mở khóa khi tạo key ở bước 2 khi dán vào app script.

Khi các bạn đăng ký thành công thì trang website sẻ trả về nội dung như bên dưới, đồng nghĩa với việc bạn đã đăng ký thành công "License" cho giao diện.
*.Json
{

  "success": true,

  "key": "HB-ABCD-1234-EFGH",

  "domain": "hungblog.com",

  "expired": "2027-06-19"

}
   
Tiếp đó bạn viết hàm kiểm tra và dán vào giao diện website/blog để kiểm tra xem license có hợp lệ hay không.
Javascript
<script>
const LICENSE_API ="https://key.hungblog.com/";
const LICENSE_KEY = "HB-PLA8-GJYG-M6PC";
const DOMAIN = location.hostname;

fetch(`${LICENSE_API}?action=check&key=${LICENSE_KEY}&domain=${DOMAIN}`)
  .then(res => res.json())
  .then(data => {

    // KEY ĐÚNG
    if (data.valid) {
      document.body.innerHTML = `
        <div style="
          text-align:center;
          margin-top:80px;
          font-family:Arial,sans-serif;
          color:#555;
        ">
          <h1 style="
            font-size:48px;
            margin-bottom:20px;
            color:#4CAF50;
          ">
            Website đã kích hoạt bản quyền
          </h1>

          <p style="
            font-size:24px;
            margin-bottom:10px;
          ">
            Giấy phép hợp lệ và đang hoạt động
          </p>

          <p style="
            font-size:18px;
            color:#777;
          ">
            Cảm ơn bạn đã sử dụng phiên bản chính thức từ nhà phát hành.
          </p>
        </div>
      `;
    }

    // KEY SAI
    else {
      document.body.innerHTML = `
        <div style="
          text-align:center;
          margin-top:80px;
          font-family:Arial,sans-serif;
          color:#555;
        ">
          <h1 style="
            font-size:48px;
            margin-bottom:20px;
            color:#E53935;
          ">
            Website chưa kích hoạt bản quyền
          </h1>

          <p style="
            font-size:24px;
            margin-bottom:10px;
          ">
            Key không tồn tại hoặc sai tên miền
          </p>

          <p style="
            font-size:18px;
            color:#777;
          ">
            Vui lòng liên hệ nhà phát triển để được hỗ trợ.
          </p>
        </div>
      `;
    }

  })
   
  .catch(() => {
    document.body.innerHTML = `
      <div style="text-align:center;margin-top:80px">
        <h2>Không thể kết nối máy chủ bản quyền</h2>
      </div>
    `;
  });
</script>
  
Trong đoạn code trên phần "const LICENSE_API ="https://key.hungblog.com/";" chính là đường link google script ở bước 2 khi các bạn dán code và tạo liên kết, mọi người thay đổi liên kết này thành liên kết của các bạn, và phần "const LICENSE_KEY = "HB-PLA8-GJYG-M6PC";" chính là keygen mà bạn tạo.

Như vậy cũng đã hoàn thành sơ bộ việc tạo license cho website/blog cho mọi người áp dụng, có thời gian rảnh nhiều mình sẻ hướng dẫn tiếp về việc trên. Chúc mọi người thành công