Communitygithub.com

biz-telegram-payment-notify

Sepay Webhook からの支払い成功通知を Telegram ボットにリアルタイム転送するスキルです。Next.js プロジェクトで、@BotFather を使ったボット作成、chat_id 取得、並列通知処理をステップバイステップでガイドします。

biz-telegram-payment-notify とは?

このスキルは、Next.js プロジェクトにおいて、Sepay Webhook が受信した支払い成功通知を Telegram ボットにリアルタイムで転送するための完全なガイドを提供します。主な機能として、(1) @BotFather を使った Telegram ボットの作成手順、(2) 個人チャットとグループチャット両方に対応した chat_id の取得方法、(3) 既存の Sepay Webhook ルートを自動検出し、Resend メール送信と並列で Telegram 通知を実行する `sendTelegramNotification()` ヘルパー関数の実装を提供します。特に、Telegram 通知の失敗が Webhook の 200 レスポンスをブロックしないよう `Promise.allSettled` を使用し、Sepay のリトライによる重複通知を防止します。デフォルトのメッセージフォーマットはベトナム語で、顧客名、電話番号、メールアドレス、金額(VND)、商品名、タイムスタンプを含み、モバイルフレンドリーな HTML 形式で表示されます。このスキルは、Claude Code、Cursor、Codex などの AI エージェントを対象としており、開発者が手動でコードを書くことなく、迅速に Telegram 通知を統合できるように設計されています。

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

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Biz Telegram Payment Notify — Sepay 入金時にリアルタイムアラート

このスキルは、Next.js プロジェクトの既存の Sepay Webhook に Telegram ボット通知 を組み込みます。顧客が Sepay にリンクされた銀行口座に振り込みに成功するたびに、このスキルは Telegram ボットを使用して、オーナー(または営業チームグループ)のチャットにリアルタイムでメッセージをプッシュします。メッセージには、顧客名、電話番号、金額、商品名、時刻が含まれます。

理念: 顧客向けのメール自動応答(Resend)とオーナー向けの Telegram アラートは、異なる2つのアクターにサービスを提供します。メールは顧客向けのフォーマルな手段です。Telegram はオーナー向けの「ping」です。外出先でも Telegram を開けばすぐに新しい注文を確認でき、100通のメールの中から探すために Gmail を開く必要はありません。Telegram のレイテンシは 2 秒未満ですが、メールは 30~60 秒です。

なぜ Slack/Discord/Zalo ではなく Telegram なのか: Telegram ボットは 5 分でセットアップでき(トークン1つ + chat_id 1つ)、ワークスペースやサーバー管理者は不要、無制限の無料メッセージ、メールより強力なプッシュ通知、iOS/Android/デスクトップのネイティブアプリを備えています。Slack はワークスペースと招待が必要です。Discord はサーバーと権限設定が必要です。Zalo OA は確認済みビジネスアカウント(承認に3〜7日)と月間アクティブユーザー料金が必要です。Telegram はオーナー側のアラートにとって最も抵抗の少ない経路です。

出力: コードパッチ + ステップバイステップのボットセットアップガイド + 環境変数リスト + 3段階のテスト計画。このスキルは Telegram 送信テストを自動では行いません — ユーザーにあらかじめボットトークンと chat_id を貼り付けてもらう必要があります。これらの認証情報はユーザーの資産だからです。


このスキルを使用するタイミング

  • ユーザーが Sepay Webhook を設定したばかりで、顧客からの振込があったときに Telegram でリアルタイムに通知を受け取りたい場合。
  • ユーザーが /api/payment-success(または同等のエンドポイント)で Resend メールを既に処理しており、並列で Telegram アラートを追加したい場合 — 新しいルートを作成したり、ロジックを複製したりしません。
  • ユーザーが「注文があったら教えて」と言っていて、コンテキストが Sepay 統合のあるランディングページ販売の場合。

以下の場合はこのスキルを使用しないでください:

  • ユーザーが Slack/Discord 通知を希望する場合 → 別のユースケース。
  • ユーザーが Zalo OA ボットを希望する場合 → OA 確認済みビジネスアカウントと異なるコスト構造が必要。
  • ユーザーがまだ Sepay Webhook をセットアップしていない場合(銀行口座が Sepay にリンクされておらず、Webhook を受信するエンドポイントがない)→ このスキルは Sepay をゼロからセットアップするのではなく、既存の Webhook に配線するだけです。
  • ユーザーがオーナー向けにメールのみを希望する場合 → biz-email-setup に既に Email B(オーナー通知)があります。

ワークフロー概要(6フェーズ)

フェーズ 0: 既存の Sepay Webhook ルートを検出(パス + フレームワーク + ハンドラーの形状)
       ↓
フェーズ 0.5: リードストアを検出(lib/leads-kv.ts(/biz-setup-sepay-payment から))
           → あり: 実際の KV ルックアップを使用
           → なし: 2つのオプションを提示(raw モード または /biz-setup-sepay-payment を先に実行)
       ↓
フェーズ 1: ユーザーに Telegram ボットの作成をガイド(BotFather → トークン → chat_id)
       ↓ [ゲート — ユーザーがトークンと chat_id を貼り付けるのを待つ]
       ↓
フェーズ 2: メッセージフォーマットをドラフト → ユーザーにプレビュー表示 → 確認
       ↓
フェーズ 3: コードを配線(lib/telegram.ts ヘルパー + Webhook ハンドラーへの統合 + 環境変数)
       ↓
フェーズ 4: テスト計画(curl ボット直接 → シミュレートされた Sepay ペイロード → 本番確認)

フェーズ 1 とフェーズ 4 には ユーザーを待つゲート があります。ユーザーによる手動操作(トークン取得、本番確認)が必要だからです。フェーズ 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)に sendCustomerEmail + sendOwnerEmail を呼び出す Resend が既にあるsendTelegramNotification を同じ Promise.allSettled に配線
ユーザーが Sepay 固有のルートを持っているapp/api/sepay-webhook/route.ts または app/api/webhook/sepay/route.tsSepay ペイロードを解析して検証した後(transferType === 'in' ブランチ)に配線
どのルートも見つからない—停止。ユーザーに通知: "Sepay を受信する Webhook ルートが見つかりませんでした。先に Sepay Webhook をセットアップして(銀行口座を Sepay にリンク → ドメインを指す Webhook URL を作成)、その後戻ってきて Telegram を配線してください。または、Webhook が別の名前のエンドポイントにある場合は、パスを教えてください。"

現在のハンドラーを読み取り、形状を理解します:

  • Sepay リクエストを認証しているか?(Authorization ヘッダー Apikey または HMAC)
  • id または referenceCode に基づいて重複排除しているか?(Sepay は non-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つのシナリオ:

シナリオアクション
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 を配線し、顧客の名前/電話番号/メールアドレスを完全にルックアップします
  • Telegram アラートには "Nguyễn Văn A — 0901234567 — [email protected] — 499K — Khoá AI Agent" と表示されます

オプション 2 — Raw モード: リードをルックアップせずに、Sepay ペイロードをそのまま Telegram に送信します:

  • Telegram には "Vietcombank — 499.000đ — content: DH001 0901234567 — 14:32" のみ表示されます
  • オーナーは content から顧客を推測し、Resend メールログと照合します
  • シンプルで今すぐ実行できますが、UX は劣ります

1 か 2 を選んでください。

ユーザーが 1 を選んだ場合 → このスキルを停止し、/biz-setup-sepay-payment を提案します。ユーザーがセットアップを完了したら、このスキルに戻ってきます。

ユーザーが 2 を選んだ場合 → フェーズ 1 に進み、raw テンプレートを使用します(templates/lib-telegram-raw.ts を参照)。


フェーズ 1 — ユーザーに Telegram ボットの作成をガイド

詳細な手順とテキストスクリーンショットについては references/telegram-bot-setup.md を参照してください。ユーザー向けの3つの手順を要約します:

ステップ 1 — @BotFather で新しいボットを作成

1. Telegram を開く(モバイル/デスクトップ)
2. 検索: @BotFather → スタートを押す
3. コマンドを入力: /newbot
4. BotFather がボット名を尋ねる — 表示名を入力(例: "Đơn Hàng Brand X")
5. BotFather がユーザー名を尋ねる — "_bot" で終わるユーザー名を入力(例: brandx_orders_bot)— グローバルに一意である必要があります
6. BotFather が次の行を含むメッセージを返します:
   "Use this token to access the HTTP API: 1234567890:AAxxxxxxxxxxxxxxxxxxxxxx"
7. そのトークンをコピーして、私に貼り付けてください。

セキュリティに関する注意: このトークンはボットを制御する権限を与えます。Git にコミットしたり、公開したりしないでください。もし漏洩した場合は、@BotFather に戻り → /token → /revoke と入力して新しいトークンを作成してください。

ステップ 2 — chat_id を取得

1対1チャット(オーナーのみが受信) — ソロプレナーに推奨:

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のトークンに置き換えてください)
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>ĐƠN HÀNG MỚI</b>

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

🔗 Mã GD: <code>{{reference_code}}</code>

変数が注入された後:

🎉 ĐƠN HÀNG MỚI

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

🔗 Mã GD: FT26134567890

ユーザーにプレビューを表示し、尋ねます:

  1. このフォーマットでよろしいですか? 追加/削除したいフィールドはありますか?(例: UTM ソース、本日の注文件数、顧客の Zalo リンクなど)
  2. 絵文字が多すぎますか?(一部のユーザーはプレーンテキストを好みます)
  3. CRM/Sheets へのインライン CTA ボタン(リンク)を追加しますか?(高度 — スキルはインラインキーボードを追加できます)

フォーマットルール:

  • 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(バニラ JS)を参照してください。内容:

// lib/telegram.ts
type TelegramPayload = {
  name: string;
  phone: string;
  email: string;
  amount: number; // VND, raw number (例: 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] Missing TELEGRAM_BOT_TOKEN or 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] Send failed: ${res.status} ${errBody}`);
    }
  } catch (err) {
    console.error('[telegram] Network error:', 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>ĐƠN HÀNG MỚI</b>',
    '',
    `👤 <b>${escapeHtml(p.name)}</b>`,
    `📞 ${phoneStr}`,
    `📧 ${escapeHtml(p.email)}`,
    `💰 <b>${amountStr}</b> — ${escapeHtml(p.productName)}`,
    `🕐 ${now}`,
    p.referenceCode ? `\n🔗 Mã GD: <code>${escapeHtml(p.referenceCode)}</code>` : '',
  ].filter(Boolean).join('\n');
}

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

なぜエラーを飲み込むのか: Sepay は non-200 を受信すると Webhook をリトライします。Telegram のタイムアウト/ダウンが Webhook をクラッシュさせると、Sepay がリトライし、リトライのたびにメールが再送信され、支払いが再ログされ、ユーザーは1つの注文に対して5通のメールと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 }); // 送金を無視
  }

  // [既存] content(注文 ID を含む)または referenceCode に基づいてリードをルックアップ
  const lead = await lookupLeadByTransferContent(payload.content);

  // [新規] 3つの副作用を並列でファンアウト — Telegram の失敗はメールをブロックしない
  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.all ではなく Promise.allSettled を使用する理由:

  • Promise.all はいずれかの promise が失敗すると reject します → ハンドラーが throw し → Sepay が 500 を受信 → リトライ → 重複メール。
  • Promise.allSettled はすべての promise が settle(resolve または reject)するのを待ち、throw しません。

3.3 環境変数と .gitignore

# .env.local に追加
echo """
# Telegram Bot Notification
TELEGRAM_BOT_TOKEN=""
TELEGRAM_CHAT_ID=""
""" >> .env.local

.env.local が既に .gitignore にあることを確認:

grep -q '.env.local' .gitignore || echo '.env.local' >> .gitignore

最後に: ユーザーに、フェーズ 1 で取得したトークンと chat_id を .env.local に貼り付けるように指示します:

⚠️ 貼り付けが必要です:
1. .env.local を開く
2. TELEGRAM_BOT_TOKEN= の後にボットトークンを貼り付け
3. TELEGRAM_CHAT_ID= の後に chat_id を貼り付け
4. 保存 → npm run dev で再起動

フェーズ 4 — テスト計画

3段階:

レベル 1 — ボット直接テスト(ネットワーク確認)

# 設定が正しいか確認
curl -X POST "https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/sendMessage" \
  -H "Content-Type: application/json" \
  -d '{
    "chat_id": "<TELEGRAM_CHAT_ID>",
    "text": "🧪 Telegram 通知システムのテスト",
    "parse_mode": "HTML"
  }'

# 期待される結果: Telegram で "🧪 Telegram 通知システムのテスト" が表示される
# 表示されない場合: トークン/chat_id を確認。トークンが無効な場合、403 エラーが返る

レベル 2 — シミュレートされた Sepay Webhook

フェーズ 3 のコードをデプロイせずにテスト。ローカルでシミュレート:

# ローカルサーバーを起動 (npm run dev)
# 新しいターミナルで:
curl -X POST "http://localhost:3000/api/sepay-webhook" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "test_telegram_001",
    "transferType": "in",
    "transferAmount": 499000,
    "content": "TEST_ORDER_123",
    "referenceCode": "TEST_REF001",
    "accountNumber": "1234567890",
    "gateway": "Vietcombank"
  }'

# Terminal のログで確認:
# [telegram] Send success: 200 OK
# Telegram で受信したメッセージを確認

Raw モードの場合(リードストアなし)— フォーマットは異なりますが、テスト手順は同じです。Promise.allSettled により、リードルックアップが失敗しても Telegram が引き続き動作することを確認します。

レベル 3 — 本番確認

# 1 本番にデプロイ
# 2 実際の bank transfer を行う(数万 VND で十分)
# 3 Telegram で受信したメッセージを確認:
#    - 名前、電話番号、メールが正しいか?
#    - 金額が正しいか?(499.000đ vs 499K vs ...)
#    - 時間がベトナム時間か?
# 4 Resend メールログでメールが送信されたか確認(Telegram の失敗はメールに影響しない)

ロールバック計画:

  • 問題が発生した場合: .env.local から TELEGRAM_BOT_TOKEN と TELEGRAM_CHAT_ID を削除 → サーバーを再起動 → コードは残るが、トークンがないため sendTelegramNotification は早期リターンしてエラーログを出力する。Sepay Webhook とメールは引き続き正常に動作する。
  • それでも問題が解決しない場合: lib/telegram.ts を削除し、Webhook ハンドラーからのインポートと呼び出しを削除する。

まとめ

アーティファクト場所
ヘルパー関数lib/telegram.ts
環境変数TELEGRAM_BOT_TOKEN + TELEGRAM_CHAT_ID in .env.local
Webhook 統合app/api/payment-success/route.ts(または同等)に Promise.allSettled として配線
メッセージテンプレートlib/telegram.ts の formatMessage() 関数
テストスクリプトレベル 1 (curl)、レベル 2 (simulated webhook)、レベル 3 (production test)

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'.

関連スキル