sangwaritaxi_website/src/supabase/functions/server/index.tsx

227 lines
9.4 KiB
TypeScript

import { Hono } from "npm:hono";
import { cors } from "npm:hono/cors";
import { logger } from "npm:hono/logger";
import * as kv from "./kv_store.tsx";
const app = new Hono();
// Enable logger
app.use('*', logger(console.log));
// Enable CORS for all routes and methods
app.use(
"/*",
cors({
origin: "*",
allowHeaders: ["Content-Type", "Authorization"],
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
exposeHeaders: ["Content-Length"],
maxAge: 600,
}),
);
// Health check endpoint
app.get("/make-server-10d555e8/health", (c) => {
return c.json({ status: "ok" });
});
// Test email configuration endpoint
app.get("/make-server-10d555e8/test-email-config", (c) => {
const resendApiKey = Deno.env.get('RESEND_API_KEY');
return c.json({
emailConfigured: !!resendApiKey,
apiKeyFormat: resendApiKey ? (resendApiKey.startsWith('re_') ? 'valid' : 'invalid') : 'missing',
apiKeyLength: resendApiKey?.length || 0
});
});
// Email endpoint for booking confirmations
app.post("/make-server-10d555e8/send-booking-email", async (c) => {
try {
const bookingData = await c.req.json();
console.log('Received booking data:', JSON.stringify(bookingData, null, 2));
// Store booking in KV store
const bookingId = `booking_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
await kv.set(bookingId, {
...bookingData,
bookingId,
createdAt: new Date().toISOString(),
status: 'confirmed'
});
console.log('Booking stored with ID:', bookingId);
const resendApiKey = Deno.env.get('RESEND_API_KEY');
console.log('API Key exists:', !!resendApiKey);
console.log('API Key length:', resendApiKey?.length || 0);
console.log('API Key prefix:', resendApiKey?.substring(0, 7) || 'none');
if (!resendApiKey) {
console.error('RESEND_API_KEY environment variable not found');
throw new Error('RESEND_API_KEY not configured - please set up your Resend API key');
}
// Validate API key format (Resend keys typically start with 're_')
if (!resendApiKey.startsWith('re_')) {
console.error('Invalid API key format. Resend API keys should start with "re_"');
throw new Error('Invalid RESEND_API_KEY format - Resend API keys should start with "re_"');
}
// Get vehicle pricing
const getVehiclePrice = (vehicleType) => {
switch (vehicleType) {
case '5-seater': return '₹999';
case '7-seater': return '₹1600';
case 'innova': return '₹2000';
default: return 'Contact for pricing';
}
};
const price = getVehiclePrice(bookingData.vehicleType);
// Email content for business owner
const businessEmailContent = `
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f9f9f9;">
<div style="background-color: #ff6b35; color: white; padding: 20px; text-align: center; border-radius: 10px 10px 0 0;">
<h1 style="margin: 0;">🚗 New Taxi Booking - Sangwari Taxi</h1>
</div>
<div style="background-color: white; padding: 30px; border-radius: 0 0 10px 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);">
<h2 style="color: #ff6b35; margin-top: 0;">Booking Details</h2>
<p><strong>Booking ID:</strong> ${bookingId}</p>
<p><strong>Customer Name:</strong> ${bookingData.contactName}</p>
<p><strong>Contact Number:</strong> ${bookingData.contactNumber}</p>
<p><strong>Pickup Location:</strong> ${bookingData.pickup}</p>
<p><strong>Drop-off Location:</strong> ${bookingData.dropoff}</p>
<p><strong>Date:</strong> ${bookingData.date}</p>
<p><strong>Time:</strong> ${bookingData.time}</p>
<p><strong>Passengers:</strong> ${bookingData.passengers}</p>
<p><strong>Vehicle Type:</strong> ${bookingData.vehicleType} (${price})</p>
<p><strong>Booking Time:</strong> ${new Date().toLocaleString('en-IN')}</p>
<div style="background-color: #fff3e0; padding: 15px; border-radius: 5px; margin: 20px 0; border-left: 4px solid #ff6b35;">
<p style="margin: 0; color: #d84315;"><strong>Action Required:</strong> Please contact the customer to confirm pickup details and arrange the taxi service.</p>
</div>
</div>
</div>`;
// Email content for customer
const customerEmailContent = `
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f9f9f9;">
<div style="background-color: #ff6b35; color: white; padding: 20px; text-align: center; border-radius: 10px 10px 0 0;">
<h1 style="margin: 0;">🚗 Booking Confirmed - Sangwari Taxi</h1>
</div>
<div style="background-color: white; padding: 30px; border-radius: 0 0 10px 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);">
<h2 style="color: #ff6b35; margin-top: 0;">Dear ${bookingData.contactName},</h2>
<p>Thank you for choosing Sangwari Taxi! Your booking has been confirmed.</p>
<h3 style="color: #ff6b35;">Booking Details:</h3>
<p><strong>Booking ID:</strong> ${bookingId}</p>
<p><strong>Pickup Location:</strong> ${bookingData.pickup}</p>
<p><strong>Drop-off Location:</strong> ${bookingData.dropoff}</p>
<p><strong>Date:</strong> ${bookingData.date}</p>
<p><strong>Time:</strong> ${bookingData.time}</p>
<p><strong>Passengers:</strong> ${bookingData.passengers}</p>
<p><strong>Vehicle Type:</strong> ${bookingData.vehicleType} (${price})</p>
<div style="background-color: #e8f5e8; padding: 15px; border-radius: 5px; margin: 20px 0; border-left: 4px solid #4caf50;">
<p style="margin: 0; color: #2e7d32;"><strong>Next Steps:</strong> Our team will contact you shortly to confirm pickup details. Please keep your phone available.</p>
</div>
<h3 style="color: #ff6b35;">Contact Information:</h3>
<p><strong>Phone:</strong> 7477247488</p>
<p><strong>Email:</strong> bookme@sangwaritaxi.com</p>
<p><strong>Address:</strong> Commercial complex second floor Nehru Nagar east Bhilai beside state bank Pin 490020</p>
<p style="margin-top: 30px;">Thank you for choosing Sangwari Taxi. We look forward to serving you!</p>
</div>
</div>`;
// Send email to business owner
console.log('Attempting to send business email...');
const businessEmailResponse = await fetch('https://api.resend.com/emails', {
method: 'POST',
headers: {
'Authorization': `Bearer ${resendApiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
from: 'Sangwari Taxi <noreply@sangwaritaxi.com>',
to: ['bookme@sangwaritaxi.com'],
subject: `New Taxi Booking #${bookingId} - ${bookingData.contactName}`,
html: businessEmailContent,
}),
});
const businessEmailResult = await businessEmailResponse.text();
console.log('Business email response status:', businessEmailResponse.status);
console.log('Business email response:', businessEmailResult);
if (!businessEmailResponse.ok) {
console.error('Failed to send business email:', businessEmailResult);
throw new Error(`Failed to send business email: ${businessEmailResult}`);
}
// Send confirmation email to customer (if they provided email)
let customerEmailResponse = null;
if (bookingData.customerEmail && bookingData.customerEmail.trim() !== '') {
console.log('Attempting to send customer email to:', bookingData.customerEmail);
customerEmailResponse = await fetch('https://api.resend.com/emails', {
method: 'POST',
headers: {
'Authorization': `Bearer ${resendApiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
from: 'Sangwari Taxi <noreply@sangwaritaxi.com>',
to: [bookingData.customerEmail],
subject: `Booking Confirmed #${bookingId} - Sangwari Taxi`,
html: customerEmailContent,
}),
});
const customerEmailResult = await customerEmailResponse.text();
console.log('Customer email response status:', customerEmailResponse.status);
console.log('Customer email response:', customerEmailResult);
if (!customerEmailResponse.ok) {
console.error('Failed to send customer email:', customerEmailResult);
// Don't fail the whole request if customer email fails
}
} else {
console.log('No customer email provided, skipping customer notification');
}
console.log('Booking email sent successfully:', bookingId);
return c.json({
success: true,
message: 'Booking confirmed and emails sent successfully',
bookingId: bookingId,
emailsSent: {
business: true,
customer: !!customerEmailResponse?.ok
}
});
} catch (error) {
console.error('Error processing booking:', error);
// If it's an API key issue, provide specific guidance
if (error.message.includes('API key') || error.message.includes('validation_error')) {
return c.json({
success: false,
message: `Email service configuration error: ${error.message}. Please check your Resend API key setup.`,
error: 'EMAIL_CONFIG_ERROR'
}, 400);
}
// For other errors, still save the booking but indicate email failure
return c.json({
success: false,
message: `Booking saved but email notification failed: ${error.message}`,
error: 'EMAIL_SEND_FAILED'
}, 500);
}
});
Deno.serve(app.fetch);