Online Smart Business Letter Writing Assistant

Online Smart Business Letter Writing Assistant

Contact Information

Your Information (Sender)

Recipient's Information

Compose Your Letter

Review & Download Your Letter

Your formatted letter will appear here once you fill in the details.

${recipientTitle}

${recipientCompany}

${recipientAddress}

${recipientCityStateZip}


Dear ${recipientName || 'Recipient'},


${letterBody.replace(/\n/g, '
')}

Sincerely,



${senderName}

`; const pdfHtml = `

${senderName}

${senderTitle}

${senderCompany}

${senderAddress}

${senderCityStateZip}

${senderEmail}

${senderPhone}

${today}

${recipientName}

${recipientTitle}

${recipientCompany}

${recipientAddress}

${recipientCityStateZip}

Dear ${recipientName || 'Recipient'},

${letterBody}

Sincerely,




${senderName}

`; if (letterPreview) letterPreview.innerHTML = html; if (letterPreviewPdf) letterPreviewPdf.innerHTML = pdfHtml; } // --- AI Content Generation --- if (generateContentBtn) { generateContentBtn.addEventListener('click', async () => { const purpose = inputs.letterPurpose ? inputs.letterPurpose.value : ''; const tone = inputs.letterTone ? inputs.letterTone.value : 'Formal'; const senderName = inputs.senderName ? inputs.senderName.value : 'the sender'; const recipientName = inputs.recipientName ? inputs.recipientName.value : 'the recipient'; if (!purpose) { alert('Please specify the purpose of the letter.'); return; } const prompt = `Write a professional business letter from ${senderName} to ${recipientName}. The purpose of the letter is: "${purpose}". The desired tone is ${tone}. Write only the body of the letter, starting after the salutation "Dear ${recipientName}," and ending before "Sincerely,". Do not include the salutation or the closing.`; const spinner = document.getElementById('generateSpinner'); const btnText = document.getElementById('generateBtnText'); if (spinner) spinner.classList.remove('hidden'); if (btnText) btnText.textContent = 'Generating...'; generateContentBtn.disabled = true; try { let chatHistory = [{ role: "user", parts: [{ text: prompt }] }]; const payload = { contents: chatHistory }; const apiKey = ""; // API key will be handled by the environment const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-05-20:generateContent?key=${apiKey}`; const response = await fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (!response.ok) { throw new Error(`API request failed with status ${response.status}`); } const result = await response.json(); if (result.candidates && result.candidates.length > 0 && result.candidates[0].content && result.candidates[0].content.parts && result.candidates[0].content.parts.length > 0) { const text = result.candidates[0].content.parts[0].text; if (inputs.letterBody) { inputs.letterBody.value = text.trim(); updatePreview(); // Update preview after generating content } } else { throw new Error('Unexpected API response structure.'); } } catch (error) { console.error('Error generating letter content:', error); if (inputs.letterBody) { inputs.letterBody.value = 'Sorry, there was an error generating the content. Please try again.'; } } finally { if (spinner) spinner.classList.add('hidden'); if (btnText) btnText.textContent = 'Generate Letter Content with AI'; generateContentBtn.disabled = false; } }); } // --- PDF Download Logic --- if (downloadPdfBtn) { downloadPdfBtn.addEventListener('click', () => { updatePreview(); // Ensure PDF content is up-to-date const { jsPDF } = window.jspdf; const pdfElement = document.getElementById('letter-preview-pdf'); if (!pdfElement) { console.error("PDF preview element not found."); return; } html2canvas(pdfElement, { scale: 2, // Higher scale for better quality useCORS: true }).then(canvas => { const imgData = canvas.toDataURL('image/png'); // A4 size: 210mm x 297mm. In points (1pt = 1/72 inch): ~595 x 842 const pdf = new jsPDF({ orientation: 'portrait', unit: 'pt', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const canvasWidth = canvas.width; const canvasHeight = canvas.height; const canvasAspectRatio = canvasWidth / canvasHeight; const pdfAspectRatio = pdfWidth / pdfHeight; let finalCanvasWidth, finalCanvasHeight; // Fit canvas content to PDF page width finalCanvasWidth = pdfWidth; finalCanvasHeight = finalCanvasWidth / canvasAspectRatio; pdf.addImage(imgData, 'PNG', 0, 0, finalCanvasWidth, finalCanvasHeight); pdf.save("business-letter.pdf"); }).catch(error => { console.error("Error generating PDF:", error); }); }); } // --- Initial Setup --- updateTabUI(); updatePreview(); });
Scroll to Top