Communitygithub.com

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

在 Next.js 專案中,為來自 Sepay webhook 的成功付款設定 Telegram 機器人通知。

MKT.LANDINGPAGE.SKILLS 是什麼?

此技能專注於在 Next.js 專案中整合 Telegram 機器人通知至既有的 Sepay 付款 Webhook。它提供從頭到尾的逐步引導,包含建立 Telegram 機器人、獲取 Token 與 Chat ID、撰寫可複用的發送通知函式,並將 Telegram 警報並聯整合至現有的 Webhook 處理流程中,確保 Telegram 發送失敗不會影響 Sepay 的付款回應。技能強調此過程的「非關鍵路徑」特性,採用 `Promise.allSettled` 防止 Webhook 重試導致的重複通知。支援 TypeScript 與 JavaScript 專案,並提供原始模式(直接轉發 Sepay 負載)與完整查找模式(透過 Vercel KV 查找客戶姓名、電話等)兩種選項。最終產出包含程式碼修補、環境變數設定、以及三階段的測試計畫,但需要使用者手動提供 Bot Token 與 Chat ID。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/lexuanthanhhy/MKT.LANDINGPAGE.SKILLS/tree/main/.claude/skills/biz-telegram-payment-notify

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Biz Telegram Payment Notify — Sepay 收款即時提醒

此技能將 Telegram 機器人通知 接入 Next.js 專案中既有的 Sepay Webhook。每當客戶成功轉帳至與 Sepay 連結的銀行帳戶時,技能將透過 Telegram Bot 即時推送一則訊息到擁有者(或業務團隊群組)的聊天室,訊息包含客戶姓名、手機號碼、金額、產品名稱及時間。

設計理念:給客戶的 Email 自動回覆(Resend)與給擁有者的 Telegram 警報服務兩個不同的角色。Email 是給客戶的正式文件。Telegram 則是給擁有者的「 Ping 」——當您在外出時,打開 Telegram 就能立即看到新訂單,無需在 Gmail 的眾多郵件中翻找。Telegram 延遲 < 2 秒,而 Email 則需 30-60 秒。

為什麼選擇 Telegram 而不是 Slack/Discord/Zalo:Telegram 機器人設定只需 5 分鐘(1 個 Token + 1 個 Chat ID),無需工作空間或伺服器管理員,免費且無限訊息,推播通知比 Email 更強大,且擁有原生的 iOS/Android/桌面應用程式。Slack 需要工作空間與邀請。Discord 需要伺服器與權限設定。Zalo OA 則需要經過驗證的商業帳號(審核需 3-7 天)以及每月活躍用戶費用。對於擁有者端的警示,Telegram 是阻力最小的路徑。

技能輸出:程式碼修補、機器人設定逐步指南、環境變數清單、三級測試計畫。技能不會自動測試發送 Telegram——要求使用者先提供 Bot Token 與 Chat ID,因為這些憑證屬於使用者的資產。


何時使用此技能

  • 使用者剛完成 Sepay Webhook 的接入,並希望在客戶轉帳時透過 Telegram 獲得即時通知。
  • 使用者已經擁有 /api/payment-success(或類似路徑)來處理 Resend Email,並希望平行新增 Telegram 警報——而不是建立新的路由或複製邏輯。
  • 使用者說「有訂單時通知我」,且情境是使用 Sepay 整合的銷售頁面。

請勿使用此技能的情況:

  • 使用者想要 Slack/Discord 通知 → 這是不同的使用案例。
  • 使用者想要 Zalo OA 機器人 → 需要經過驗證的商業 OA 帳號且成本結構不同。
  • 使用者尚未設定 Sepay Webhook(尚未有銀行帳戶連結 Sepay,尚未有接收 Webhook 的端點)→ 此技能不會從頭設定 Sepay,只會接入既有的 Webhook。
  • 使用者只需要給擁有者的 Email → biz-email-setup 已經提供了 Email B(擁有者通知)。

總體工作流程(6 個階段)

階段 0:偵測既有的 Sepay Webhook 路由(路徑 + 框架 + 處理器結構)
       ↓
階段 0.5:偵測客戶資料儲存(來自 /biz-setup-sepay-payment 的 lib/leads-kv.ts)
           → 有:使用實際的 KV 查找
           → 無:提供 2 個選項(原始模式 或 先執行 /biz-setup-sepay-payment)
       ↓
階段 1:引導使用者建立 Telegram 機器人(BotFather → Token → Chat ID)
       ↓ [閘門 — 等待使用者提供 Token + Chat ID]
       ↓
階段 2:草擬訊息格式 → 向使用者顯示預覽 → 確認
       ↓
階段 3:接入程式碼(lib/telegram.ts 輔助函式 + 整合至 Webhook 處理器 + 環境變數)
       ↓
階段 4:測試計劃(直接 curl 測試機器人 → 模擬 Sepay 負載 → 正式環境驗證)

階段 1 和 4 設有閘門等待使用者,因為需要使用者手動操作(取得 Token、驗證正式環境)。階段 0/0.5/2/3 則由技能主動執行。


階段 0 — 偵測既有的 Sepay Webhook

此技能會接入既有的 Webhook,不會建立新的路由。首先定位處理器。

尋找 Webhook 路由 — 根據常見關鍵字進行 grep:

# 在專案根目錄中
grep -r "sepay" --include="*.ts" --include="*.js" --include="*.tsx" -l
grep -r "transferAmount\|transferType\|payment-success\|payment-webhook" --include="*.ts" --include="*.js" -l

3 種常見情境:

情境既有的路徑行動
使用者使用 biz-email-setup 管線app/api/payment-success/route.ts(或 pages/api/payment-success.ts)已有 Resend 呼叫 sendCustomerEmail + sendOwnerEmail將 sendTelegramNotification 接入同一個 Promise.allSettled 中
使用者有 Sepay 專用路由app/api/sepay-webhook/route.ts 或 app/api/webhook/sepay/route.ts在解析並驗證 Sepay 負載後(transferType === 'in' 分支)接入
找不到任何路由—停止。通知使用者:「我找不到接收 Sepay 的 Webhook 路由。請您先設定 Sepay Webhook(將銀行連結至 Sepay → 建立指向您網域的 Webhook URL),完成後再回來讓我接入 Telegram。或者,如果您的 Webhook 使用其他端點名稱,請告訴我路徑。」

讀取現有處理器以了解其結構:

  • 是否對 Sepay 請求進行驗證?(Authorization 標頭的 Apikey 或 HMAC)
  • 是否根據 id 或 referenceCode 進行去重?(Sepay 在收到非 200 回應時會重試 → 需要去重以避免重複通知)
  • 是否根據 content(包含訂單 ID 的轉帳訊息)查找客戶?
  • 回傳給 Sepay 的回應格式:{ success: true } 或純文字 200 OK?

如果現有處理器尚未去重 — 提醒使用者,但不要阻止。此技能僅接入 Telegram,去重是付款邏輯的考量。若需要,建議使用者另外加入去重機制。


階段 0.5 — 偵測客戶資料儲存(關鍵)

Sepay Webhook 僅發送 content(客戶轉帳時貼上的文字)、transferAmount 和 referenceCode。Sepay 不知道客戶是誰——必須根據 content(包含訂單 ID)在本機儲存中進行查找。

技能會檢查 3 項:

# 1. 檢查客戶資料儲存輔助函式是否存在
test -f lib/leads-kv.ts || test -f lib/leads-kv.js && echo "lead store: ✓"

# 2. 檢查 Vercel KV 環境變數
grep -E "KV_REST_API_URL|KV_REST_API_TOKEN" .env.local && echo "KV env: ✓"

# 3. 檢查 @vercel/kv 是否已安裝
grep '"@vercel/kv"' package.json && echo "KV package: ✓"

3 種情境:

情境行動
全部 ✓ — 客戶資料儲存已就緒繼續階段 1,在 Webhook 處理器中使用 lib/leads-kv.ts 的 getLeadByOrderId()
缺少 1 項以上 — 尚未設定停止,詢問使用者 2 個選項(見下方)

若缺少時,詢問使用者:

我發現您還沒有客戶資料儲存(Vercel KV)。Sepay Webhook 不知道客戶是誰——只知道轉帳內容與金額。您想要:

選項 1 — 透過 /biz-setup-sepay-payment 進行完整的客戶資料儲存設定(建議):

  • 該技能將設定 Vercel KV、建立 lib/leads-kv.ts 檔案,並接入表單提交以在使用者註冊時儲存客戶資料
  • 完成後回到這裡,我就能接入 Telegram,查找完整的客戶姓名/電話/Email
  • Telegram 警報將顯示:「Nguyễn Văn A — 0901234567 — [email protected] — 499K — AI Agent 課程」

選項 2 — 原始模式:直接轉發 Sepay 負載,不查找客戶資料:

  • Telegram 僅顯示:「Vietcombank — 499.000đ — 內容: DH001 0901234567 — 14:32」
  • 擁有者需自行根據內容判斷客戶,並與 Resend Email 日誌交叉比對
  • 簡單、可立即運作,但使用者體驗較差

您要選擇 1 還是 2?

如果使用者選擇 1 → 暫停此技能,建議執行 /biz-setup-sepay-payment。待使用者完成設定後 → 再回到此技能。

如果使用者選擇 2 → 繼續階段 1,使用原始模板(請參閱 templates/lib-telegram-raw.ts)。


階段 1 — 引導使用者建立 Telegram 機器人

參閱 references/telegram-bot-setup.md 以獲得包含文字截圖的詳細指南。為使用者總結 3 個步驟:

步驟 1 — 透過 @BotFather 建立新機器人

1. 開啟 Telegram(手機/電腦)
2. 搜尋:@BotFather → 點選開始
3. 輸入指令:/newbot
4. BotFather 詢問機器人名稱 — 輸入顯示名稱(例如:「品牌 X 訂單」)
5. BotFather 詢問使用者名稱 — 輸入以 "_bot" 結尾的使用者名稱(例如:brandx_orders_bot)— 必須是全域唯一的
6. BotFather 回傳訊息,其中包含一行:
   "Use this token to access the HTTP API: 1234567890:AAxxxxxxxxxxxxxxxxxxxxxx"
7. 複製該 Token,提供給我。

安全性注意事項:此 Token 等於機器人的控制權。請勿提交到 Git 或公開分享。如果不慎洩漏,請回到 @BotFather → 輸入 /token → /revoke 以產生新 Token。

步驟 2 — 取得 Chat ID

個人聊天(僅擁有者接收) — 推薦給個人創業者:

1. 在 Telegram 中,搜尋:@userinfobot → 點選開始
2. 機器人回傳訊息,其中包含 "Id: 123456789" — 複製該數字。
3. 這就是您的 Chat ID。

群組聊天(業務團隊共同接收) — 推薦給團隊:

1. 建立一個新的 Telegram 群組(或使用現有的群組)
2. 點選群組名稱 → 新增成員 → 搜尋您剛建立的機器人(根據使用者名稱 @brandx_orders_bot)→ 新增
3. 在群組中輸入:/start@brandx_orders_bot(或任何訊息)
4. 開啟瀏覽器,存取:
   https://api.telegram.org/bot<TOKEN>/getUpdates
   (將 <TOKEN> 替換為步驟 1 的 Token)
5. 在 JSON 回應中,尋找 "chat":{"id":-1001234567890,...} — 複製該數字(如果有負號,請一併保留)
6. 這就是群組的 Chat ID。

頻道(單向廣播,無法討論)— Chat ID 以 -100 開頭。取得方式與群組相同,但需將機器人新增為頻道管理員。

步驟 3 — 提供給技能

等待使用者提供:

TELEGRAM_BOT_TOKEN=1234567890:AAxxxxxxxxxxxxxxxxxxxxxx
TELEGRAM_CHAT_ID=123456789

重要閘門:在使用者提供這兩個值之前,請不要繼續階段 2。如果使用者說「我已經有了,在其他地方」→ 仍然等待提供,因為需要在階段 3 將它們注入到 .env.local 中。


階段 2 — 草擬訊息格式

預設為越南語,行動裝置友善(Telegram 支援 HTML 渲染):

🎉 <b>新訂單</b>

👤 <b>{{name}}</b>
📞 {{phone}}
📧 {{email}}
💰 <b>{{amount}}</b> — {{product_name}}
🕐 {{time_vn}}

🔗 交易代碼:<code>{{reference_code}}</code>

變數注入後,實際顯示如下:

🎉 新訂單

👤 Nguyễn Văn A
📞 0901 234 567
📧 [email protected]
💰 499.000đ — AI Agent 課程
🕐 14:32 14/05/2026

🔗 交易代碼:FT26134567890

向使用者顯示預覽,並詢問:

  1. 這個格式可以嗎?需要新增/刪除任何欄位嗎?(例如:新增 UTM 來源、今日訂單數量、客戶 Zalo 連結)
  2. 表情符號會不會太多?(有些使用者偏好純文字)
  3. 希望新增一個內聯按鈕(CTA)連結到 CRM/試算表嗎?(進階功能 — 技能可以新增內聯鍵盤)

格式規則:

  • HTML 模式(parse_mode: "HTML")— Telegram 支援 <b>、<i>、<u>、<code>、<pre>、<a href>。不支援 <br> — 請使用 \n。
  • 越南盾金額格式:499.000đ(點號作為千分位分隔符,最後加上 đ)或簡潔的 499K / 1.99M 格式。如果有 offer.json 的 voice 設定,則依此讀取。
  • 電話號碼格式:0901 234 567(3-3-3 分組)— 在行動裝置上更易於閱讀。
  • 越南時間:HH:mm dd/mm/yyyy — 設定為越南時間(UTC+7),而非 UTC。
  • 避免表情符號過多(每則訊息 >5 個表情符號會降低專業感)。

階段 3 — 接入程式碼

3 項變更:

3.1 建立輔助函式 lib/telegram.ts

請參閱 templates/lib-telegram.ts(TypeScript)或 templates/lib-telegram.js(JavaScript)。內容如下:

// lib/telegram.ts
type TelegramPayload = {
  name: string;
  phone: string;
  email: string;
  amount: number; // VND,原始數字(例如:499000)
  productName: string;
  referenceCode?: string;
};

export async function sendTelegramNotification(payload: TelegramPayload): Promise<void> {
  const token = process.env.TELEGRAM_BOT_TOKEN;
  const chatId = process.env.TELEGRAM_CHAT_ID;

  if (!token || !chatId) {
    console.error('[telegram] 缺少 TELEGRAM_BOT_TOKEN 或 TELEGRAM_CHAT_ID');
    return; // 不拋出錯誤 — Telegram 失敗時不應阻止付款回應
  }

  const text = formatMessage(payload);

  try {
    const res = await fetch(`https://api.telegram.org/bot${token}/sendMessage`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        chat_id: chatId,
        text,
        parse_mode: 'HTML',
        disable_web_page_preview: true,
      }),
    });
    if (!res.ok) {
      const errBody = await res.text();
      console.error(`[telegram] 發送失敗:${res.status} ${errBody}`);
    }
  } catch (err) {
    console.error('[telegram] 網路錯誤:', err);
    // 吞下錯誤 — 不要讓 Telegram 失敗導致 Sepay 重試
  }
}

function formatMessage(p: TelegramPayload): string {
  const amountStr = p.amount.toLocaleString('vi-VN') + 'đ';
  const phoneStr = p.phone.replace(/(\d{4})(\d{3})(\d{3})/, '$1 $2 $3');
  const now = new Date().toLocaleString('vi-VN', {
    timeZone: 'Asia/Ho_Chi_Minh',
    day: '2-digit', month: '2-digit', year: 'numeric',
    hour: '2-digit', minute: '2-digit',
  });
  return [
    '🎉 <b>新訂單</b>',
    '',
    `👤 <b>${escapeHtml(p.name)}</b>`,
    `📞 ${phoneStr}`,
    `📧 ${escapeHtml(p.email)}`,
    `💰 <b>${amountStr}</b> — ${escapeHtml(p.productName)}`,
    `🕐 ${now}`,
    p.referenceCode ? `\n🔗 交易代碼:<code>${escapeHtml(p.referenceCode)}</code>` : '',
  ].filter(Boolean).join('\n');
}

function escapeHtml(s: string): string {
  return s.replace(/[<>&]/g, c => ({ '<': '&lt;', '>': '&gt;', '&': '&amp;' }[c]!));
}

為何吞下錯誤:如果 Sepay 收到非 200 回應,它會重試 Webhook。如果 Telegram 超時或故障導致 Webhook 當機 → Sepay 重試 → 每次重試都會重新發送 Email 並記錄付款 → 使用者會為一筆訂單收到 5 封 Email 和 5 則 Telegram 警報。Telegram 是盡力而為的輔助通道,並非關鍵路徑。

3.2 接入 Sepay Webhook 處理器

讀取現有處理器,找到處理付款成功的位置(在解析 Sepay 負載並驗證 transferType === 'in' 之後)。新增:

// app/api/payment-success/route.ts(或類似路徑)
import { sendTelegramNotification } from '@/lib/telegram';
import { sendCustomerEmail, sendOwnerEmail } from '@/lib/resend'; // 如果已存在

export async function POST(req: Request) {
  const payload = await req.json();

  // [現有] 驗證 Sepay 授權並解析負載
  if (payload.transferType !== 'in') {
    return Response.json({ success: true }); // 忽略轉出交易
  }

  // [現有] 根據內容(包含訂單 ID)或 referenceCode 查找客戶
  const lead = await lookupLeadByTransferContent(payload.content);

  // [新增] 平行展開 3 個副作用 — Telegram 失敗不會封鎖 Email
  await Promise.allSettled([
    sendCustomerEmail(lead),
    sendOwnerEmail(lead),
    sendTelegramNotification({
      name: lead.name,
      phone: lead.phone,
      email: lead.email,
      amount: payload.transferAmount,
      productName: lead.productName,
      referenceCode: payload.referenceCode,
    }),
  ]);

  return Response.json({ success: true });
}

使用 Promise.allSettled 而非 Promise.all 的原因:

  • Promise.all 若任何一個 Promise 失敗就會拒絕 → 處理器拋出錯誤 → Sepay 收到 500 狀態碼 → 重試 → 重複發送 Email。
  • Promise.allSettled 會等待所有 Promise 完成(無論成功或失敗),不會拋出錯誤。

3.3 環境變數 + .gitignore

# .env.local — 由參考文檔處理
TELEGRAM_BOT_TOKEN=1234567890:AAxxxxxxxxxxxxxxxxxxxxxx
TELEGRAM_CHAT_ID=123456789

確認這兩個變數存在於 .env.local 中。如果不存在,則新增。

將 .env.local 加入到 .gitignore 中(如果尚未加入):

# .gitignore
.env.local

如果 .env.local 已被追蹤(git check-ignore .env.local 顯示未忽略),警告使用者:

⚠️ .env.local 檔案目前正在被 Git 追蹤。TELEGRAM_BOT_TOKEN 是敏感資訊。請執行:

git rm --cached .env.local
echo '.env.local' >> .gitignore

來停止追蹤。完成後請將變數重新貼上到 .env.local 中。


階段 4 — 測試計劃

3 個測試級別,按順序執行:

測試 1 — 直接發送測試訊息(透過 curl)

無需等待 Webhook。使用 sendMessage API 直接測試 Bot:

curl -X POST "https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/sendMessage" \
  -H "Content-Type: application/json" \
  -d '{
    "chat_id": "<TELEGRAM_CHAT_ID>",
    "text": "🧪 <b>測試訊息</b>\n\n✅ Bot 設定成功!\n🕐 $(date +%H:%M\ %d/%m/%Y)",
    "parse_mode": "HTML"
  }'

預期結果:Telegram 聊天室中收到一則帶有「🧪 測試訊息」和「✅ Bot 設定成功!」的訊息。

測試 2 — 模擬 Sepay 負載

將 lib/telegram.ts 匯入並在建置後執行:

// scripts/test-telegram.js 或直接使用 REPL
import { sendTelegramNotification } from '../lib/telegram';

await sendTelegramNotification({
  name: 'Nguyễn Văn A (測試)',
  phone: '0901234567',
  email: '[email protected]',
  amount: 499000,
  productName: '測試產品',
  referenceCode: 'TEST' + Date.now(),
});

或者,直接向您的 Webhook 端點發送一個模擬請求:

curl -X POST "https://yourdomain.com/api/payment-success" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "test-123",
    "transferType": "in",
    "transferAmount": 499000,
    "content": "測試 - 0901234567 - 訂單001",
    "referenceCode": "TESTREF001",
    "accountNumber": "1900123456789",
    "bankName": "Vietcombank"
  }'

預期結果:

  1. Resend Email 按預期發送(如果已設定)
  2. Telegram 收到您定義的格式的警報
  3. API 回應:{ "success": true } 且狀態碼為 200

測試 3 — 正式環境驗證

  1. 請銀行傳送一筆小額測試轉帳到連結的帳戶(或使用 Sepay 的「 Test Payment 」功能,如果有)
  2. 檢查使用者端:
    • 收到一封格式良好的 Email → ✅
    • 在 Telegram 聊天室收到即時警報(< 5 秒) → ✅
    • 警報中的金額與實際轉帳金額相符 → ✅
  3. 故意測試錯誤情境:
    • 使 TELEGRAM_BOT_TOKEN 無效(暫時修改)→ 確認 Webhook 仍回傳 200 → Email 仍發送
    • 還原 Token → 確認 Telegram 恢復正常

參考文檔

檔案說明
templates/lib-telegram.tsTypeScript 範本 — 輔助函式 + 格式化
templates/lib-telegram.jsJavaScript 範本(無 TypeScript 專案用)
templates/lib-telegram-raw.ts原始模式範本 — 如果沒有 KV 客戶資料儲存時使用
references/telegram-bot-setup.md逐步的 Telegram Bot 建立指南(含文字截圖)
references/sepay-ip-whitelist.md需要將 Telegram IP 加入白名單嗎?通常不需要,但做為參考

已知邊界案例與處理

邊界案例處理方式
使用者尚未設定 Resend / Email 自動回覆只接入 Telegram;Email 部分不是此技能的必要條件。但需警告使用者。
Webhook 端點使用 HMAC 簽章驗證讀取現有驗證流程,不要在驗證前呼叫 sendTelegramNotification。
同一個 bot 被多個專案使用使用不同的 Chat ID(每個專案一個群組)。Token 可以相同。
使用者使用 Pages Router (pages/api)提供與 App Router 不同的範本:templates/lib-telegram-pages.ts
使用者想要圖片/檔案類型的警報此版本僅支援文字。圖片需要 sendPhoto API 不同的範本。

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

Best practices for Remotion - Video creation in React

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

Scaffold trang `/admin` CRM-style trực quan vào Next.js project (Supabase backend) — KHÔNG còn variant Vercel KV. Layout 1CRM-inspired: sidebar 3 tab (Tổng quan / Khách hàng / Email marketing) + popup nhập mã đăng nhập. **Tab Tổng quan**: 4 KPI cards (Tổng leads / Đã thanh toán / Tỷ lệ chuyển đổi / Doanh thu) có delta arrow vs kỳ trước, line chart leads+paid+revenue theo ngày dùng `recharts`, donut trạng thái paid/pending/expired, period selector pill 7d/30d/90d, list 5 thanh toán gần nhất. **Tab Khách hàng**: bảng leads + search + filter trạng thái + filter ngày + CSV export. **Tab Email marketing**: form soạn chiến dịch (tên + tiêu đề + body chọn định dạng **văn bản thường HOẶC HTML** + placeholder `{{name}}` + audience 4 loại all/paid/pending/last_days + tên người gửi) — có nút **Xem trước** mở modal iframe render đúng email thật (text → auto convert + wrap khung; HTML fragment → wrap khung, HTML đầy đủ giữ nguyên) → gửi bulk qua SMTP (reuse `nodemailer` của `biz-email-setup` — KHÔN

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

Deploy landing page / website (React, Next.js, Vite, static HTML) lên Vercel — tự kiểm tra Vercel CLI hoặc Vercel MCP đã cài chưa, nếu chưa thì cài qua npm/pnpm và hướng dẫn user authenticate (vercel login), tự detect framework (Next.js / Vite / CRA / static), auto-generate vercel.json khi cần, chạy `vercel --prod`, trả về live URL + inspect URL + hướng dẫn custom domain. USE WHEN user says 'deploy lên vercel', 'đẩy landing page lên vercel', 'publish website', 'go live', 'deploy nextjs', 'deploy react', 'deploy vite', 'tạo URL live', 'đưa lên production', 'biz-deploy-vercel', 'host landing page', 'vercel deploy', 'ship lên vercel', 'đẩy code lên vercel'. Skill này áp dụng cho cả case dùng Vercel CLI lẫn Vercel MCP server.

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

Setup SMTP-based email auto-responder cho landing page bán hàng — tự động gửi email sau khi user điền form (tên/SĐT/email), KHÔNG cố định vào provider nào. Skill này (1) hỏi user chọn SMTP provider (Gmail/Google Workspace, Resend SMTP, SendGrid, Mailgun, Brevo, Zoho, hoặc SMTP custom của hosting VN) và detect Next.js stack đang dùng, (2) đọc context từ `offer.json` + `conversion-copy.md` (từ `/biz-offer-alex-hormozi`) HOẶC đọc trực tiếp Next.js project đã build qua `ui-ux-pro-max` (file `app/page.tsx`) HOẶC đọc HTML landing page đã deploy để hiểu offer, dream outcome, mechanism, bonus. Lưu ý: skill `biz-sales-page-layout` đã DEPRECATED 2026-05-14 — pipeline mới skip layout/copy.json, (3) **draft 2 email**: email A — auto-responder gửi cho lead (warm welcome + deliver lead magnet/booking confirm/payment link tuỳ offer type), email B — notification gửi cho owner (lead alert + thông tin liên hệ), (4) **show draft cho user duyệt và chỉnh sửa** trước khi wire vào code, (5) cài `nodemailer`

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

Cài chatbot AI dạng floating widget góc dưới phải vào project Next.js có sẵn (App Router hoặc Pages Router), responsive đầy đủ web + tablet + mobile, gọi LLM qua OpenRouter (mặc định google/gemini-3-flash-preview, có thể đổi sang anthropic/claude-sonnet-4.6), streaming response, RENDER MARKDOWN trong assistant bubble (bold / list / link / code) qua react-markdown + remark-gfm — KHÔNG hiện raw **bold** dạng text — có knowledge base từ FAQ + tài liệu sản phẩm/khóa học do user cung cấp để chatbot tự động trả lời khách hàng, và TỰ ĐỘNG EXTRACT + LƯU LEAD (tên + SĐT + email) vào Upstash Redis/Vercel KV dưới namespace `chat-lead:{phone}` khi user cung cấp đầy đủ thông tin trong chat — dedupe theo SĐT, TTL 90 ngày, fire-and-forget không block stream. Skill tự detect số lượng project Next.js — nếu có nhiều hơn 1 sẽ hỏi user chọn project nào để cài; tự detect TypeScript/JS, App Router/Pages Router, Tailwind/CSS module, KV/Upstash availability (skip auto-save nếu chưa có); tự install react-markd

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

Đóng gói offer **không thể chối từ** (grand slam offer) theo phương pháp Alex Hormozi ($100M Offers) — nhận input pains/gains/customer jobs theo Value Proposition Design (Osterwalder 2014) + sản phẩm/dịch vụ, rồi sinh ra: (1) markdown report tiếng Việt đầy đủ Value Equation scoring + Core Offer + 3-4 Bonus stack + Guarantee + Urgency + Pricing, (2) offer.json structured cho pipeline downstream (`ui-ux-pro-max` build sales page production-ready), (3) conversion copy block (headline + subheadline + CTA) sẵn sàng paste landing page. 2 input mode: (B) user paste sẵn pains + gains + product, (C) user chỉ có sản phẩm — skill phỏng vấn theo VPD framework để surface pain/gain trước. Bonus stack mode hybrid: skill brainstorm 5-7 candidate có justification value rồi user pick/chỉnh 3-4 cái. Tiếng Việt thuần (xưng anh/chị), giá VND charm pricing (X99K), 3-tier decoy structure. USE WHEN user says 'đóng gói offer', 'tạo offer', 'thiết kế offer Hormozi', 'grand slam offer', 'value stack', 'offer sta

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

Nâng cấp copy sales page tiếng Việt — biến copy có sẵn (từ `offer.json` + `conversion-copy.md` của `/biz-offer-alex-hormozi`, HOẶC từ Next.js project đã build qua `ui-ux-pro-max`, HOẶC user paste block copy bất kỳ) thành **copy chất lượng cao chốt đơn**: headline punchy hơn, pain agitation đau hơn, mechanism rõ hơn, benefit cụ thể hơn, FAQ xử lý đúng objection của thị trường VN, CTA mạnh hơn. Skill này có 3 INTENSITY LEVEL: (1) **Polish** — light edit + power word + sửa nhịp; (2) **Conversion-optimized** — rewrite 5 block critical + tạo A/B variants cho hero/CTA; (3) **Sales-letter** — long-form story-driven full rewrite kèm P.S.. Mỗi section áp dụng đúng formula thuyết phục (PAR cho pain, BAB cho solution, FEP cho benefit, PVEN cho final CTA, Star-Chain-Hook cho testimonial). Output gồm 4 file: `copy-upgraded.md`, `copy-variants.md` (A/B test bank — 3 hero + 3 CTA + 3 final-CTA), `copy-changes.md` (diff Trước/Sau + lý do), `copy.json` (structured downstream). Giọng văn tiếng Việt thuầ

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

⚠️ DEPRECATED (2026-05-14) — Skill này KHÔNG còn trong pipeline chuẩn. Quy trình mới đã bỏ bước wireframe markdown trung gian: sau `/biz-offer-alex-hormozi` đi THẲNG sang `ui-ux-pro-max` để build Next.js sales page production-ready (có design language nhất quán: style + palette + font pairing, không phải Tailwind defaults). Lý do deprecate: wireframe markdown làm thêm 1 bước trung gian không tạo giá trị — `ui-ux-pro-max` đọc trực tiếp `offer.json` đã đầy đủ anchor + core + bonus + guarantee + urgency + pricing rồi ra HTML production luôn. Chỉ dùng skill này KHI user EXPLICITLY yêu cầu wireframe markdown để review/in/share trước khi build code (rare case). KHÔNG trigger trên các keyword 'tạo sales page', 'tạo landing page bán hàng' nữa — những keyword đó giờ trigger `ui-ux-pro-max`.

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

End-to-end Sepay VietQR payment infrastructure cho landing page Next.js — guide user setup Sepay account + bank linking + scaffold đầy đủ payment flow trong project. Skill này xử lý 7 phase: (0) detect Next.js stack + **HỎI user chọn lead store backend** (Vercel KV hoặc Supabase Free Postgres — default recommend Supabase do free tier rộng hơn ~50× + có SQL + admin UI), (1) GUIDE user đăng ký Sepay account tại my.sepay.vn + link bank account VN (Vietcombank/Techcombank/MB/ACB/VPBank/BIDV/...) + lấy API key + setup webhook URL trên Sepay dashboard, (2A nếu chọn KV) setup Vercel KV (install `@vercel/kv` + KV namespace + 4 env vars KV_*), (2B nếu chọn Supabase) setup Supabase project (tạo project tại Singapore region + chạy migration SQL tạo 4 bảng leads/phone_index/order_counter/webhook_dedup với pg_cron TTL cleanup + RLS deny-all + lấy SUPABASE_URL + SUPABASE_SERVICE_ROLE_KEY + Vercel Cron ping `/api/health` mỗi 6 ngày chống auto-pause), (3) scaffold `lib/leads-store.ts` (thin re-export

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

Convert a single MP3 voiceover file into a single HeyGen avatar lip-sync MP4 video. Single-purpose — no planning, no SRT, no chunking, no Remotion compositing. Hybrid path — REST upload (helper script) + HeyGen MCP for video creation, because the post-2026 MCP no longer exposes an asset-upload tool. Reads avatar look pool (`HEYGEN_AVATAR_LOOKS`) from `.env` and HeyGen API key (`HEYGEN_API_KEY`) for the upload step. USE WHEN user says "tạo video heygen từ mp3", "mp3 to heygen", "heygen mp4 từ audio", "convert mp3 sang heygen video", "tạo avatar video từ file mp3", "lip sync mp3 heygen", "biến mp3 thành video heygen", or any time the user has exactly one MP3 file and wants exactly one HeyGen avatar MP4 out.

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

Demand-side market research cho digital product / service ở Việt Nam — đo cầu thật + WTP + channel-market fit + defensibility qua keyword volume, marketplace sales (Shopee/Unica/Edumall/Gitiho/KyNa), community signal (FB groups, TikTok hashtag, Zalo OA), competitor pricing, unit economics — không phải macro PESTEL. Output: keyword portfolio + Niche Score 100 điểm 7-dimension có evidence + go/no-go decision + falsification protocol. Force triangulate ≥3 sources cho mỗi claim quan trọng. USE WHEN user says 'nghiên cứu thị trường', 'market research', 'validate niche', 'keyword research', 'demand validation', 'niche có nên làm không', 'có ai làm chưa', 'thị trường đủ lớn không', 'có lời không', 'chọn ngách', 'kiểm tra cầu'. Cũng trigger khi user mô tả 1 ý tưởng kinh doanh cụ thể và muốn check feasibility. Skill này KHÔNG fit: high-ticket transactional sale (BĐS, ô tô), B2B enterprise (sales cycle 6+ tháng), hyper-local geo micro-market (1 toà nhà, 1 phường). KHÔNG làm: macro PESTEL/Porter

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

Transcribe an MP3 voiceover into an SRT subtitle file and a word-level segments JSON using local OpenAI Whisper. Input is a single MP3 path; output is `<stem>.srt` + `<stem>_segments.json` written next to the MP3 (or to a custom output dir). USE WHEN the user says 'extract srt from mp3', 'trích srt từ mp3', 'transcribe voiceover', 'tạo file srt và segments', 'whisper transcribe', 'bóc transcript có timestamp', 'extract voiceover segments', 'tách SRT từ audio', or any time a downstream skill (plan-short-video-edit, heygen-remotion-short-video-editor) needs an SRT + word-level segments JSON from a voiceover MP3 and one does not already exist.

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

Convert Vietnamese/English script text to MP3 voiceover using ElevenLabs TTS API. Calls POST /v1/text-to-speech/{voice_id}, streams audio bytes, writes MP3 directly. Locked to Hoang's brand voice ID by default. USE WHEN user says 'tạo mp3 elevenlabs', 'elevenlabs tts', 'eleven labs voice', 'text to speech elevenlabs', 'tạo voiceover elevenlabs', 'đọc text bằng elevenlabs', 'tts elevenlabs to mp3', 'eleven labs script to mp3', 'voiceover bằng elevenlabs', 'giọng elevenlabs'.

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

End-to-end orchestrator: **script → final MP4 16:9 (1920×1080) podcast-keynote**.

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

End-to-end short-video pipeline — từ kịch bản (Việt/Anh) ra MP4 TikTok/Reels 9:16 hoàn chỉnh. Orchestrator 3 phase ghép skill có sẵn — (1) TTS provider chọn được giữa `mkt-elevenlabs-tts-to-mp3` (default, voice của Hoàng) hoặc `mkt-video-script-to-mp3` (MiniMax speech-2.8-hd), (2) checkpoint user duyệt MP3, (3) `heygen-mp3-to-mp4` lip-sync avatar HeyGen, (4) delegate Phase 3 packaging cho sub-agent `mkt-full-video-phase3-packager` (transcribe + scene outline + checkpoint + fan-out N scene writers parallel + scaffold + preview Studio). API key + voice ID cho cả 2 provider lưu ở `.env`. USE WHEN user nói "tạo full video từ script", "script to tiktok video", "pipeline full video heygen + hyperframe", "tạo video từ kịch bản đến mp4", "elevenlabs heygen hyperframe full pipeline", "minimax heygen pipeline", "kịch bản ra video tiktok", hoặc có sẵn 1 script + (optional) ảnh b-roll và muốn ra MP4 9:16 đóng gói có captions, SFX, b-roll.

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

Build a TikTok/Reels/YouTube **landscape 16:9 (1920×1080)** short video from a pre-recorded talking-head MP4 using HyperFrames — transcribe Vietnamese audio, scaffold a complete preview-ready 1920×1080 project with a slide pane (1200px) on the left and a floating avatar frame on the right, GSAP timeline có SPLIT↔PIP transitions (slide full-screen + avatar PIP corner thumbnail), breathing yoyo zoom + beat-driven punch-in trên avatar, 5 scene compositions kiểu "tier-row" pattern (post-stack hook / chats-stack problem / hero-orb solution / counter-row recap / terminal-row CTA), optional cream-paper editorial infographic image slots với `<img onerror>` fallback, 6 SFX wired tại scene boundaries, **NO captions** (giọng avatar là spine). USE WHEN user nói "edit video 16:9 từ HeyGen MP4", "scaffold project landscape", "podcast keynote editor", "talking head + slide editor", "build hyperframes 1920×1080", "tạo project 16:9 từ avatar mp4", "scaffold 16:9 hyperframes", "hyperframe landscape vide

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

Pipeline đóng gói: từ MP4 quay sẵn (talking head 9:16) tới HyperFrames preview project hoàn chỉnh có captions, SFX, zoom hooks, b-roll toàn cảnh có hiệu ứng rich, và CTA finale.

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

Audit bài Facebook / Reels / YouTube để phát hiện 4 downward drivers (over-branding, over-production, stock imagery, standardized aesthetic) + frequency-over-quality. Mỗi anti-pattern bị drop ~75% performance nếu hiện diện. USE WHEN user says 'audit content', 'check anti pattern', 'content có lỗi gì không', 'kiểm tra over branding', 'vì sao video bị chết', 'vì sao post không ai xem', 'content audit', 'kiểm tra chất lượng content'.

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

Tìm viral pattern ở ngành khác (bác sĩ, luật sư, tài chính, bất động sản, thủ công) có thể apply cho niche AI/automation của Hoang. Ngách AI educator VN còn ít format được khai thác — cross-industry adaptation là blue ocean. USE WHEN user says 'tìm format ngành khác', 'cross industry research', 'học format từ ngành khác', 'blue ocean format', 'tìm format chưa ai làm', 'adapt format từ niche khác', 'cross industry viral'.

lexuanthanhhy/MKT.LANDINGPAGE.SKILLS

Rewrite CTA kiểu autocratic (Mua ngay! Follow ngay! Đăng ký liền!) sang 3 variants Democratic / Benevolent / Laissez-faire — reach 85% dân số thay vì chỉ 5% (action-based). Áp dụng cho landing page, caption FB, CTA video, email. USE WHEN user says 'rewrite cta', 'sửa cta', 'cta không autocratic', 'viết lại kêu gọi hành động', 'cta cho landing page', 'cta nhẹ nhàng hơn', 'inclusive cta', 'cta democratic benevolent'.

相關技能