LuaWebhook allows you to create HTTP endpoints that can receive events from external services like Stripe, Shopify, GitHub, or any other webhook-enabled platform.
Copy
import { LuaWebhook, User } from 'lua-cli';const paymentWebhook = new LuaWebhook({ name: 'payment-webhook', description: 'Handle Stripe payment events', execute: async (event) => { const { body } = event; // ⚠️ Webhooks have NO conversational context // MUST provide userId to notify users if (body?.type === 'payment_intent.succeeded') { const customerId = body.data?.object?.metadata?.customerId; if (customerId) { const user = await User.get(customerId); await user.send([{ type: 'text', text: '✅ Payment confirmed!' }]); } } return { received: true }; }});export default paymentWebhook;
No Conversational Context: Webhooks execute outside of user conversations. You MUST use User.get(userId) with an explicit userId. Always store the user ID in your payment/order metadata.
New in v3.0.0: HTTP webhooks for external integrations. Use with LuaAgent.
Webhooks are context-less: They’re triggered by external systems, not user conversations. Always store the Lua user ID in your payment/order metadata so you can notify the right user.
import { LuaWebhook, env, Orders, User } from 'lua-cli';const stripeWebhook = new LuaWebhook({ name: 'stripe-payment-webhook', description: 'Handle Stripe payment events', execute: async (event) => { const { body } = event; console.log('Stripe event:', body?.type); switch (body?.type) { case 'payment_intent.succeeded': const paymentIntent = body.data?.object; // Update order status const order = await Orders.getById(paymentIntent.metadata.orderId); if (order) { await order.updateStatus('CONFIRMED'); // Get user by ID from payment metadata const customerId = paymentIntent.metadata.customerId; const user = await User.get(customerId); // Notify the specific user await user.send([{ type: 'text', text: `✅ Payment confirmed! Order #${order.id} is being processed. Amount: $${paymentIntent.amount/100}` }]); } return { success: true, orderId: order?.id }; case 'payment_intent.payment_failed': const failed = body.data?.object; console.error('Payment failed:', failed); // Notify user of failure const failedCustomerId = failed.metadata.customerId; if (failedCustomerId) { const user = await User.get(failedCustomerId); await user.send([{ type: 'text', text: `❌ Payment failed: ${failed.last_payment_error?.message}. Please try again.` }]); } return { success: false, reason: failed.last_payment_error?.message }; default: console.log('Unhandled event type:', body?.type); return { received: true }; } }});export default stripeWebhook;
Important: Always store the user ID (customerId) in your payment metadata so webhooks can notify the correct user. Example: metadata: { customerId: user.id, orderId: order.id }
import { LuaWebhook, env, Data, User } from 'lua-cli';const shopifyOrderWebhook = new LuaWebhook({ name: 'shopify-order-webhook', description: 'Handle Shopify order events', execute: async (event) => { const { body } = event; const order = body; // Store order in custom data await Data.create('shopify-orders', { orderId: order.id, orderNumber: order.order_number, customer: order.customer, total: order.total_price, items: order.line_items, status: order.financial_status, customerId: order.customer.id, // Store customer ID createdAt: order.created_at }, `Order #${order.order_number} ${order.customer.email} ${order.total_price}`); // Notify specific customer using their ID const user = await User.get(order.customer.id); await user.send([{ type: 'text', text: `🛍️ Order #${order.order_number} confirmed!\n\nTotal: $${order.total_price}\nItems: ${order.line_items.length}\n\nWe'll send shipping updates soon!` }]); return { success: true, orderId: order.id, orderNumber: order.order_number, customerId: order.customer.id }; }});export default shopifyOrderWebhook;
Customer Identification: Map external customer IDs (Shopify, Stripe) to Lua user IDs. Store this mapping in your order/payment metadata for webhook notifications.