API Trigger: Stripe Webhook để soạn thảo email

Khi nào nên chọn API trigger?

Các routine theo lịch trình chạy theo đồng hồ. Các routine GitHub-event phản ứng với những thay đổi code. Mọi thứ khác nằm trong API trigger.

API trigger là linh hoạt nhất: Bất kỳ hệ thống nào có thể gửi yêu cầu POST đến một URL đều có thể kích hoạt routine của bạn. Điều đó bao gồm:

  • Stripe webhook - khách hàng vừa thanh toán, nâng cấp gói đăng ký, yêu cầu hoàn tiền
  • Cảnh báo Sentry - lỗi mới, vượt quá ngưỡng
  • Hệ thống giám sát - Datadog, PagerDuty, Honeycomb kích hoạt dựa trên một chỉ số
  • Công cụ hỗ trợ khách hàng - phiếu mới, vi phạm SLA, leo thang
  • Hệ thống backend của riêng bạn - bất kỳ sự kiện nào bạn đã công bố

Trong bài học này, chúng ta sẽ xây dựng một ví dụ từ bài đăng trên blog ra mắt của Anthropic: Một Stripe webhook kích hoạt một routine, đọc thông tin chi tiết của khách hàng mới và soạn thảo một email chào mừng được cá nhân hóa, email này sẽ được lưu vào thư mục nháp Gmail của bạn - sẵn sàng để người dùng xem xét và gửi.

Cấu trúc của API trigger

Khi bạn tạo một routine được kích hoạt bởi API, Anthropic sẽ tạo ra một URL endpoint duy nhất. Nó trông giống như thế này:

https://api.claude.com/v1/routines/{routine-id}/fire

Đây là URL mà hệ thống nguồn của bạn gửi yêu cầu POST đến. Quá trình xác thực diễn ra thông qua tiêu đề - thường là API key được tạo khi bạn thiết lập routine. Ví dụ:

Authorization: Bearer ccr_xxxxxxxxxxxxxxxxxxx

Phần body yêu cầu chỉ là JSON. Bất cứ thứ gì bạn gửi sẽ được đưa vào prompt của routine dưới dạng dữ liệu đầu vào. Đây là câu lệnh curl tối thiểu cần thiết:

curl -X POST \
  "https://api.claude.com/v1/routines/{routine-id}/fire" \
  -H "Authorization: Bearer $CCR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event": "customer.subscription.created",
    "customer_id": "cus_abc123",
    "customer_email": "new@example.com",
    "plan": "pro_monthly"
  }'

Routine sẽ được thực thi. Prompt của bạn có thể tham chiếu đến bất kỳ trường nào từ phần body JSON đó.

Bước 1: Prompt

Bắt đầu với prompt, vì prompt xác định dữ liệu bạn cần từ Stripe. Đây là prompt chúng ta sẽ sử dụng:

Bạn đang viết một email chào mừng được cá nhân hóa cho một khách hàng mới vừa
đăng ký.

Bạn sẽ nhận được sự kiện `subscription.created` của Stripe làm dữ liệu đầu vào, bao gồm:
email khách hàng, tên khách hàng và gói dịch vụ họ đã chọn.

Sử dụng Gmail MCP connector để tạo bản NHÁP (không gửi) trong thư mục nháp của Gmail với cấu trúc sau:

To: {email khách hàng}
From: tôi
Subject: Chào mừng bạn đến với {tên sản phẩm} - hãy cùng thiết lập nhé

Nội dung (dưới 150 từ):
- Lời chào thân thiện ngắn gọn gửi đến khách hàng bằng tên
- Đề cập cụ thể đến gói dịch vụ họ đã chọn và những lợi ích mà gói dịch vụ mang lại
- Ba hành động cụ thể họ có thể thực hiện ngay hôm nay, được liệt kê bằng dấu chấm đầu dòng
- Lời kết "hãy trả lời email này nếu bạn cần bất cứ điều gì" từ tôi

Quy tắc:
- Luôn tạo dưới dạng bản nháp, không bao giờ gửi
- Không bao giờ đề cập đến giá cả, hoàn tiền hoặc nâng cấp
- Không bao giờ sử dụng biểu tượng cảm xúc
- Nếu thiếu tên khách hàng, hãy sử dụng "there" làm lời chào
- Nếu sự kiện không phải là subscription.created, thì không làm gì cả và thoát

Lưu ý các mẫu phòng thủ:

  • Hướng dẫn CHỈ TẠO BẢN NHÁP rõ ràng - được nhắc lại để đảm bảo an toàn mặc dù chúng ta cũng sẽ hạn chế phạm vi token
  • Xử lý trạng thái rỗng - nếu sự kiện không như mong đợi, hãy thoát ra
  • Giới hạn từ nghiêm ngặt - 150 từ
  • Mẫu định dạng - cấu trúc email chính xác

Bước 2: Thiết lập Gmail MCP connector (Phạm vi tối thiểu)

Đây là nơi mà vấn đề bảo mật trở nên quan trọng.

Vào Settings → Connectors → Gmail và bắt đầu routine OAuth. Khi Gmail hỏi bạn muốn cấp quyền cho những phạm vi nào, hãy chọn cẩn thận:

Phạm viCó cấp quyền không?Lý do
gmail.drafts.create✅ CóCần thiết - routine này tạo ra các bản nháp
gmail.send❌ KHÔNGChúng ta hoàn toàn không muốn Claude gửi
gmail.readonly❌ KHÔNGRoutine này không cần đọc thư hiện có
gmail.modify❌ KHÔNGĐừng để routine chỉnh sửa hoặc xóa
gmail.labels❌ KHÔNGKhông cần thiết cho bản nháp

Nếu giao diện người dùng của connector không cho phép bạn chọn phạm vi riêng lẻ, hãy sử dụng admin policy Google Workspace hoặc ứng dụng OAuth có phạm vi giới hạn. Nguyên tắc: nếu công việc là "soạn thảo email", connector chỉ nên có khả năng soạn thảo email. Không được gửi. Không được đọc. Không được chỉnh sửa.

Đây là lỗi bảo mật phổ biến thứ hai trong các routine (sau những connector không được lọc): Cấp quá nhiều phạm vi cho connector tại thời điểm OAuth.

Bước 3: Cấu hình API trigger

Quay lại Routines UI:

  1. New routine
  2. Trigger type: API
  3. Routine name: stripe-onboarding-draft
  4. Generate API key - đây là Bearer token mà trình xử lý Stripe webhook sẽ sử dụng. Sao chép nó và lưu trữ trong trình quản lý secret của bạn. Bạn sẽ không thể nhìn thấy nó nữa.
  5. Connectors: Chỉ Gmail (bỏ chọn tất cả những thứ khác - xem Bài học 2)
  6. Dán prompt từ bước 1
  7. Save

Sau khi lưu, bạn sẽ thấy URL trình kích hoạt của routine. Sao chép URL đó - nó sẽ được đưa vào cấu hình Stripe webhook.

Bước 4: Kết nối với Stripe

Bây giờ hãy kết nối với Stripe. Đây là thiết lập một lần duy nhất trong bảng điều khiển Stripe của bạn:

  1. Developers → Webhooks → Add endpoint
  2. Endpoint URL: URL kích hoạt từ routine
  3. Events to listen for: customer.subscription.created (và chỉ sự kiện này)
  4. Save

Đây là điểm cần lưu ý: Stripe gửi yêu cầu POST trực tiếp đến URL của bạn với signature sự kiện của Stripe trong tiêu đề, nhưng routine của bạn sẽ không biết cách tự xác minh signature đó. Bạn có hai lựa chọn:

Lựa chọn A: Đặt một máy chủ proxy ở giữa (khuyến nghị cho môi trường sản xuất). Máy chủ của bạn nhận Stripe webhook, xác minh signature của Stripe, sau đó chuyển tiếp payload đến URL trigger của routine với Bearer token của bạn. Máy chủ của bạn là ranh giới tin cậy.

Lựa chọn B: Chấp nhận rằng bất kỳ ai tìm thấy URL trigger của bạn đều có thể kích hoạt routine. Chỉ chấp nhận được cho các bản demo, thử nghiệm nội bộ hoặc công việc không nhạy cảm. Nếu ai đó đoán được hoặc đánh cắp URL + Bearer token, họ có thể kích hoạt routine và tiêu tốn hạn mức của bạn.

Đối với bài học này, lựa chọn B sẽ ổn - chúng ta đang xây dựng một routine gửi email chỉ để soạn thảo. Đối với môi trường sản xuất (đặc biệt nếu routine có thể gửi tin nhắn thực hoặc sửa đổi dữ liệu thực), hãy luôn sử dụng lựa chọn A.

Đây là một proxy Node tối thiểu bạn có thể đặt phía trước:

// Cloudflare Worker, hàm Vercel hoặc bất kỳ endpoint serverless nào
export async function POST(request) {
  // 1. Xác minh signature Stripe
  const sig = request.headers.get('stripe-signature');
  const payload = await request.text();
  const event = stripe.webhooks.constructEvent(payload, sig, STRIPE_SECRET);

  // 2. Lọc theo sự kiện chúng ta quan tâm
  if (event.type !== 'customer.subscription.created') {
    return new Response('ignored', { status: 200 });
  }

/ // 3. Chuyển tiếp đến hàm
  await fetch(process.env.CCR_TRIGGER_URL, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.CCR_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      event: event.type,
      customer_id: event.data.object.customer,
      customer_email: event.data.object.customer_email,
      customer_name: event.data.object.customer_name,
      plan: event.data.object.items.data[0].price.nickname,
    }),
  });

  return new Response('ok', { status: 200 });
}

Đây là khoảng 40 dòng kết nối, và đó là mẫu an toàn cho mọi routine được kích hoạt bởi API trong môi trường sản xuất.

Bước 5: Kiểm tra với payload fake

Trước khi chờ đợi một đăng ký thực sự, hãy chạy routine theo cách thủ công:

curl -X POST \
  "$CCR_TRIGGER_URL" \
  -H "Authorization: Bearer $CCR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event": "customer.subscription.created",
    "customer_id": "cus_test_123",
    "customer_email": "test@example.com",
    "customer_name": "Alex Chen",
    "plan": "Pro Monthly"
  }'

Mở lịch sử chạy của routine. Bạn sẽ thấy:

  • Yêu cầu đã được nhận
  • Đã sử dụng Gmail MCP connector
  • Bản nháp đã được tạo
  • Quá trình chạy đã hoàn tất

Mở thư mục bản nháp Gmail của bạn. Sẽ có một bản nháp gửi đến test@example.com, chào Alex bằng tên, đề cập đến gói Pro Monthly, với ba hành động tiếp theo và chữ ký của bạn.

Nếu mọi thứ có vẻ ổn, hãy bật công tắc trên Stripe. Người đăng ký thực sự tiếp theo của bạn sẽ nhận được một bản nháp được cá nhân hóa trong hộp thư đến của bạn chỉ trong vài giây.

Lỗi thường gặp: Sử dụng cùng một mẫu cho "Gửi tin nhắn thực"

Câu hỏi đặt ra: "Tại sao tôi không để Claude gửi email?"

Đừng làm vậy. Không phải trong các routine ban đầu của bạn, và không phải nếu không có sự kiểm tra kỹ lưỡng.

Lý do:

  • Bản nháp có thể được xem xét. Các email gửi thực thì không.
  • Bản nháp tạo ra một rào cản tự nhiên cho người dùng. Bạn nhìn thấy tin nhắn trước khi khách hàng nhìn thấy.
  • Bản nháp có quy mô khác nhau. Một lần gửi sai có thể gửi email cho 1.000 khách hàng. Một bản nháp sai chỉ gây ra sự xấu hổ trong trường hợp xấu nhất.

Nếu bạn cần tự động gửi sau này, hãy chứng minh điều đó. Hãy bắt đầu với bản nháp, theo dõi routine của bạn để đảm bảo chất lượng đầu ra trong 30 ngày, sau đó hãy xem xét cấp quyền gửi có phạm vi. Ngay cả khi đó - hãy giữ tùy chọn ưu tiên bản nháp cho những tin nhắn nhạy cảm nhất.

Những điểm chính cần ghi nhớ

  • Các API trigger mở khóa bất kỳ nguồn sự kiện nào, không chỉ GitHub
  • Dữ liệu sự kiện trở thành đầu vào mà prompt của bạn có thể tham chiếu
  • Luôn đặt một máy chủ proxy phía trước để xác minh signature nguồn cho môi trường sản xuất
  • Cấp quyền OAuth phạm vi tối thiểu cho các connector - drafts.create, không phải full send
  • Bắt đầu mọi routine tự động hóa mới ở chế độ chỉ tạo bản nháp, nâng cấp lên chế độ chỉ gửi sau khi đã chứng minh được độ tin cậy
  • Câu 1:

    Phạm vi quyền TỐI THIỂU bạn nên cấp cho routine token cho Gmail MCP connector là gì?

    GIẢI THÍCH:

    Nguyên tắc quyền tối thiểu chiến thắng. Nếu công việc là 'soạn thảo email để người khác xem xét', routine chỉ cần quyền drafts.create - không cần send, không cần read, không cần admin. Một routine bị xâm phạm chỉ có thể làm những gì phạm vi của nó cho phép.

  • Câu 2:

    Khi Stripe kích hoạt webhook tại routine endpoint của bạn, payload sự kiện sẽ được gửi đến đâu?

    GIẢI THÍCH:

    Dữ liệu payload trở thành đầu vào cho routine - bạn tham chiếu nó trong prompt của mình giống như bất kỳ biến nào khác. Đây là toàn bộ vấn đề: Dữ liệu sự kiện CHÍNH là công việc mà Claude cần thực hiện.

  • Câu 3:

    Bạn nên làm gì trước khi kết nối bất kỳ dịch vụ bên thứ ba nào với API trigger của một routine?

    GIẢI THÍCH:

    Các routine được kích hoạt bởi API là những endpoint có thể truy cập công khai. Nếu không xác minh signature, bất kỳ ai phát hiện ra URL đều có thể kích hoạt routine và tiêu tốn hạn mức của bạn (hoặc tệ hơn, đánh cắp dữ liệu connector). Luôn luôn xác minh webhook signature trong hệ thống nguồn hoặc tại máy chủ proxy của bạn.

Thứ Ba, 21/04/2026 15:53
51 👨
Xác thực tài khoản!

Theo Nghị định 147/2024/ND-CP, bạn cần xác thực tài khoản trước khi sử dụng tính năng này. Chúng tôi sẽ gửi mã xác thực qua SMS hoặc Zalo tới số điện thoại mà bạn nhập dưới đây:

Số điện thoại chưa đúng định dạng!
Số điện thoại này đã được xác thực!
Bạn có thể dùng Sđt này đăng nhập tại đây!
Lỗi gửi SMS, liên hệ Admin
0 Bình luận
Sắp xếp theo