Speech Drafting Tool

Speech Drafting Tool

Craft compelling speeches with AI assistance

Speech Parameters

Generated Speech

Your speech draft will appear here.

Fill in the details and click "Draft Speech".

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

` : '').join('') .replace(/

/g, '

').replace(/<\/h3><\/p>/g, '

'); } async function handleGeneration() { const speechParams = { topic: elements.topic.value.trim(), audience: elements.audience.value, tone: elements.tone.value, duration: elements.duration.value }; if (!speechParams.topic || !speechParams.duration) { alert('Please provide a Topic and Duration for the speech.'); return; } // UI state elements.placeholder.classList.add('hidden'); elements.loader.classList.remove('hidden'); elements.speechOutput.innerHTML = ''; elements.generateBtn.disabled = true; elements.generateBtn.querySelector('span').textContent = 'Drafting...'; elements.downloadPdfBtn.disabled = true; elements.teleprompterBtn.disabled = true; const systemPrompt = "You are a world-class speechwriter. Your task is to draft a complete, coherent, and engaging speech based on the user's requirements. Structure the speech with a clear introduction, body (with distinct main points), and conclusion. Incorporate speaker cues in bold, such as **(Pause for effect)**, **(Softer tone)**, or **(Emphasize this word)**, where appropriate to guide the delivery."; const userQuery = ` Draft a speech with these parameters: - Topic: "${speechParams.topic}" - Target Audience: ${speechParams.audience} - Desired Tone: ${speechParams.tone} - Estimated Duration: ${speechParams.duration} minutes. Please format the output in simple markdown with headings for 'Introduction', 'Main Point 1', etc., and 'Conclusion'. `; const apiKey = ""; const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-05-20:generateContent?key=${apiKey}`; const payload = { contents: [{ parts: [{ text: userQuery }] }], systemInstruction: { parts: [{ text: systemPrompt }] }, }; try { 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: ${response.status}`); const result = await response.json(); const candidate = result.candidates?.[0]; if (candidate && candidate.content?.parts?.[0]?.text) { fullSpeechText = candidate.content.parts[0].text; elements.speechOutput.innerHTML = simpleMarkdownToHtml(fullSpeechText); elements.downloadPdfBtn.disabled = false; elements.teleprompterBtn.disabled = false; } else { throw new Error("Invalid API response structure."); } } catch (error) { console.error("Error generating speech:", error); elements.speechOutput.innerHTML = `
Error: Failed to generate speech. Please try again.
`; } finally { elements.loader.classList.add('hidden'); elements.generateBtn.disabled = false; elements.generateBtn.querySelector('span').textContent = 'Draft Speech'; } } async function handlePdfDownload() { const { jsPDF } = window.jspdf; const pdf = new jsPDF({ unit: 'pt', format: 'letter' }); pdf.setFont('Merriweather', 'bold'); pdf.setFontSize(20); pdf.text(`Speech on: ${elements.topic.value}`, 40, 60); pdf.setFont('Lato', 'normal'); pdf.setFontSize(10); pdf.text(`For: ${elements.audience.value} | Tone: ${elements.tone.value} | Duration: ${elements.duration.value} mins`, 40, 80); pdf.setLineWidth(1); pdf.line(40, 90, 572, 90); const speechTextForPdf = fullSpeechText.replace(/###\s*/g, '\n').replace(/\*\*/g, ''); pdf.setFont('Merriweather', 'normal'); pdf.setFontSize(12); const textLines = pdf.splitTextToSize(speechTextForPdf, 532); // 572 - 40 margin pdf.text(textLines, 40, 120); pdf.save(`Speech-${elements.topic.value.replace(/\s+/g, '_')}.pdf`); } function startTeleprompter() { elements.teleprompterContent.innerHTML = fullSpeechText.replace(/###\s*.*?\n/g, '

').replace(/\*\*/g, ''); elements.teleprompterModal.classList.remove('hidden'); setTimeout(() => elements.teleprompterModal.classList.remove('opacity-0'), 10); let position = window.innerHeight; elements.teleprompterContent.style.transform = `translateY(${position}px)`; if (teleprompterInterval) clearInterval(teleprompterInterval); teleprompterInterval = setInterval(() => { position -= (teleprompterSpeed / 5); elements.teleprompterContent.style.transform = `translateY(${position}px)`; if (position < -elements.teleprompterContent.clientHeight) { position = window.innerHeight; // Loop back to the top } }, 20); } function stopTeleprompter() { if (teleprompterInterval) clearInterval(teleprompterInterval); teleprompterInterval = null; elements.teleprompterModal.classList.add('opacity-0'); setTimeout(() => elements.teleprompterModal.classList.add('hidden'), 300); } function updateSpeed(delta) { teleprompterSpeed = Math.max(1, Math.min(10, teleprompterSpeed + delta)); elements.teleprompterSpeedLabel.textContent = `Speed: ${teleprompterSpeed}`; } // --- EVENT LISTENERS --- elements.generateBtn.addEventListener('click', handleGeneration); elements.downloadPdfBtn.addEventListener('click', handlePdfDownload); elements.teleprompterBtn.addEventListener('click', startTeleprompter); elements.teleprompterClose.addEventListener('click', stopTeleprompter); elements.teleprompterSpeedUp.addEventListener('click', () => updateSpeed(1)); elements.teleprompterSpeedDown.addEventListener('click', () => updateSpeed(-1)); // --- INITIALIZATION --- lucide.createIcons(); });
Scroll to Top