227 lines
9.4 KiB
TypeScript
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); |